Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

CopyShortId.C

Go to the documentation of this file.
00001 // Copyright (C) 2001, Compaq Computer Corporation
00002 // 
00003 // This file is part of Vesta.
00004 // 
00005 // Vesta is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 // 
00010 // Vesta is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with Vesta; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 #include "system.h"
00020 
00021 #include "CopyShortId.H"
00022 #include "ShortIdBlock.H"
00023 #include "FdCache.H"
00024 
00025 #define COPY_SIZE 8192
00026 
00027 ShortId CopyShortId(ShortId oldsid, /*OUT*/ int &errno_out,
00028                     Basics::uint64 n, Basics::uint64 *copied,
00029                     bool writable)
00030 {
00031     FdCache::OFlag oldofl;
00032     int oldfd = FdCache::open(oldsid, FdCache::any, &oldofl);
00033     if (oldfd < 0) {
00034         errno_out = errno;
00035         return NullShortId;
00036     }
00037     if (lseek(oldfd, 0L, SEEK_SET) < 0) {
00038         errno_out = errno;
00039         FdCache::close(oldsid, oldfd, oldofl);
00040         return NullShortId;
00041     }   
00042     ShortId newsid;
00043     int newfd = SourceOrDerived::fdcreate(newsid);
00044     if (newfd < 0) {
00045         errno_out = errno;
00046         FdCache::close(oldsid, oldfd, oldofl);
00047         return NullShortId;
00048     }
00049     struct stat st;
00050     if (fstat(oldfd, &st) < 0) {
00051         errno_out = errno;
00052         FdCache::close(oldsid, oldfd, oldofl);
00053         close(newfd);
00054         return NullShortId;
00055     }
00056     Basics::uint64 i = n;
00057     while (i > 0) {
00058         char buf[COPY_SIZE];
00059         int len = COPY_SIZE;
00060         if (len > i) len = i;
00061         len = read(oldfd, buf, len);
00062         if (len < 0) {
00063             errno_out = errno;
00064             FdCache::close(oldsid, oldfd, oldofl);
00065             close(newfd);
00066             return NullShortId;
00067         }
00068         if (len == 0) break;
00069         len = write(newfd, buf, len);
00070         if (len < 0) {
00071             errno_out = errno;
00072             FdCache::close(oldsid, oldfd, oldofl);
00073             close(newfd);
00074             return NullShortId;
00075         }
00076         i -= len;
00077         if (len < COPY_SIZE) break;
00078     }
00079     if(copied)
00080       *copied = (n - i);
00081 
00082     if(writable)
00083       fchmod(newfd, st.st_mode | 0200); // make writable
00084     else
00085       fchmod(newfd, st.st_mode & ~0222); // make read-only
00086     struct timeval tvp[2];
00087     tvp[0].tv_sec = st.st_atime;
00088     tvp[1].tv_sec = st.st_mtime;
00089 #if __digital__
00090     tvp[0].tv_usec = st.st_spare1;
00091     tvp[1].tv_usec = st.st_spare2;
00092 #else
00093     tvp[0].tv_usec = 0;
00094     tvp[1].tv_usec = 0;
00095 #endif
00096     char* path = ShortIdBlock::shortIdToName(newsid);
00097     if (utimes(path, tvp) < 0) {
00098         errno_out = errno;
00099         FdCache::close(oldsid, oldfd, oldofl);
00100         close(newfd);
00101         return NullShortId;
00102     }
00103     delete [] path;
00104     FdCache::close(oldsid, oldfd, oldofl);
00105     FdCache::close(newsid, newfd, FdCache::rw);
00106     return newsid;
00107   
00108 }

Generated on Mon May 8 00:48:43 2006 for Vesta by  doxygen 1.4.2