00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "wvatomicfile.h"
00011 #include "wvfileutils.h"
00012 #include "wvstrutils.h"
00013
00014 WvAtomicFile::WvAtomicFile(WvStringParm filename, int flags, mode_t create_mode)
00015 : tmp_file(WvString::null)
00016 {
00017 open(filename, flags, create_mode);
00018 }
00019
00020 WvAtomicFile::~WvAtomicFile()
00021 {
00022 close();
00023 }
00024
00025
00026
00027
00028 bool WvAtomicFile::open(WvStringParm filename, int flags, mode_t create_mode)
00029 {
00030 close();
00031
00032 atomic_file = filename;
00033
00034
00035 struct stat st;
00036 if (lstat(atomic_file, &st) == 0 && !S_ISREG(st.st_mode))
00037 return false;
00038
00039 WvString new_tmp_file("%s/WvXXXXXX", getdirname(filename));
00040
00041
00042
00043 mode_t old_umask = ::umask(077);
00044 int tmp_fd = ::mkstemp(new_tmp_file.edit());
00045 if (tmp_fd < 0)
00046 seterr(errno);
00047 ::umask(old_umask);
00048 if (tmp_fd < 0)
00049 return false;
00050
00051
00052
00053 if (::fchmod(tmp_fd, create_mode & ~old_umask) != 0)
00054 seterr(errno);
00055
00056 if (!WvFile::open(tmp_fd))
00057 {
00058 ::close(tmp_fd);
00059 return false;
00060 }
00061
00062 tmp_file = new_tmp_file;
00063
00064 return true;
00065 }
00066
00067
00068 void WvAtomicFile::close()
00069 {
00070 WvFdStream::close();
00071
00072 if (tmp_file)
00073 {
00074 if (::rename(tmp_file, atomic_file) != 0)
00075 ::unlink(tmp_file);
00076
00077 tmp_file = WvString::null;
00078 }
00079 }
00080
00081
00082 bool WvAtomicFile::chmod(mode_t mode)
00083 {
00084 if (getfd() == -1) return false;
00085
00086 if (fchmod(getfd(), mode) != 0)
00087 {
00088 seterr(errno);
00089 return false;
00090 }
00091
00092 return true;
00093 }
00094
00095
00096 bool WvAtomicFile::chown(uid_t owner, gid_t group)
00097 {
00098 if (getfd() == -1) return false;
00099
00100 if (fchown(getfd(), owner, group) != 0)
00101 {
00102 seterr(errno);
00103 return false;
00104 }
00105
00106 return true;
00107 }