00001
00002
00003
00004
00005
00006
00007
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
00028
00029 bool WvAtomicFile::open(WvStringParm filename, int flags, mode_t create_mode)
00030 {
00031 close();
00032
00033 atomic_file = filename;
00034
00035
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
00043
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
00053
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 }