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