• Main Page
  • Modules
  • Classes
  • Files
  • File List
  • File Members

wvatomicfile.cc

00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2005 Net Integration Technologies, Inc.
00004  *
00005  * Wrapper class for WvFile for automic file creation.  Any files that
00006  *  are guaranteed to be automic will completely write over any existing
00007  *  file on close.
00008 */
00009 
00010 #include "wvatomicfile.h"
00011 #include "wvfileutils.h"
00012 #include "wvstrutils.h"
00013 #include <sys/stat.h>
00014 
00015 WvAtomicFile::WvAtomicFile(WvStringParm filename, int flags, mode_t create_mode)
00016     : tmp_file(WvString::null)
00017 {
00018     open(filename, flags, create_mode);
00019 }
00020 
00021 WvAtomicFile::~WvAtomicFile()
00022 {
00023     close();
00024 }
00025 
00026 
00027 /* Mimics behaviour of wvfile except that it uses a tmp file and stores the
00028    real name */
00029 bool WvAtomicFile::open(WvStringParm filename, int flags, mode_t create_mode)
00030 {
00031     close();
00032 
00033     atomic_file = filename;
00034 
00035     // Ensure that if the file exists it is a regular file
00036     struct stat st;
00037     if (lstat(atomic_file, &st) == 0 && !S_ISREG(st.st_mode))
00038         return false;
00039  
00040     WvString new_tmp_file("%s/WvXXXXXX", getdirname(filename));
00041     
00042     // Get the current umask and guarantee that mkstemp() creates
00043     // a file with maximal restrictions
00044     mode_t old_umask = ::umask(077);
00045     int tmp_fd = ::mkstemp(new_tmp_file.edit());
00046     if (tmp_fd < 0)
00047         seterr(errno);
00048     ::umask(old_umask);
00049     if (tmp_fd < 0)
00050          return false;
00051  
00052     // Set the permissions as specified using the original umask
00053     // We will only possibly be adding permissions here...
00054     if (::fchmod(tmp_fd, create_mode & ~old_umask) != 0)
00055         seterr(errno);
00056 
00057     if (!WvFile::open(tmp_fd))
00058     {
00059         ::close(tmp_fd);
00060         return false;
00061     }
00062     
00063     tmp_file = new_tmp_file;
00064 
00065     return true;
00066 }
00067 
00068 
00069 void WvAtomicFile::close()
00070 {
00071     WvFdStream::close();
00072     
00073     if (tmp_file)
00074     {
00075         if (::rename(tmp_file, atomic_file) != 0)
00076             ::unlink(tmp_file);
00077         
00078         tmp_file = WvString::null;
00079     }
00080 }
00081 
00082 
00083 bool WvAtomicFile::chmod(mode_t mode)
00084 {
00085     if (getfd() == -1) return false;
00086     
00087     if (fchmod(getfd(), mode) != 0)
00088     {
00089         seterr(errno);
00090         return false;
00091     }
00092     
00093     return true;
00094 }
00095 
00096 
00097 bool WvAtomicFile::chown(uid_t owner, gid_t group)
00098 {
00099     if (getfd() == -1) return false;
00100     
00101     if (fchown(getfd(), owner, group) != 0)
00102     {
00103         seterr(errno);
00104         return false;
00105     }
00106     
00107     return true;
00108 }

Generated on Thu Aug 12 2010 11:33:09 for WvStreams by  doxygen 1.7.1