WvStreams
wvatomicfile.cc
1/*
2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2005 Net Integration Technologies, Inc.
4 *
5 * Wrapper class for WvFile for automic file creation. Any files that
6 * are guaranteed to be automic will completely write over any existing
7 * file on close.
8*/
9
10#include "wvatomicfile.h"
11#include "wvfileutils.h"
12#include "wvstrutils.h"
13
14#include <sys/stat.h>
15
16WvAtomicFile::WvAtomicFile(WvStringParm filename, int flags, mode_t create_mode)
17 : tmp_file(WvString::null)
18{
19 open(filename, flags, create_mode);
20}
21
22WvAtomicFile::~WvAtomicFile()
23{
24 close();
25}
26
27
28/* Mimics behaviour of wvfile except that it uses a tmp file and stores the
29 real name */
30bool WvAtomicFile::open(WvStringParm filename, int flags, mode_t create_mode)
31{
32 close();
33
34 atomic_file = filename;
35
36 // Ensure that if the file exists it is a regular file
37 struct stat st;
38 if (lstat(atomic_file, &st) == 0 && !S_ISREG(st.st_mode))
39 return false;
40
41 WvString new_tmp_file("%s/WvXXXXXX", getdirname(filename));
42
43 // Get the current umask and guarantee that mkstemp() creates
44 // a file with maximal restrictions
45 mode_t old_umask = ::umask(077);
46 int tmp_fd = ::mkstemp(new_tmp_file.edit());
47 if (tmp_fd < 0)
48 seterr(errno);
49 ::umask(old_umask);
50 if (tmp_fd < 0)
51 return false;
52
53 // Set the permissions as specified using the original umask
54 // We will only possibly be adding permissions here...
55 if (::fchmod(tmp_fd, create_mode & ~old_umask) != 0)
56 seterr(errno);
57
58 if (!WvFile::open(tmp_fd))
59 {
60 ::close(tmp_fd);
61 return false;
62 }
63
64 tmp_file = new_tmp_file;
65
66 return true;
67}
68
69
71{
73
74 if (tmp_file)
75 {
76 if (::rename(tmp_file, atomic_file) != 0)
77 ::unlink(tmp_file);
78
79 tmp_file = WvString::null;
80 }
81}
82
83
84bool WvAtomicFile::chmod(mode_t mode)
85{
86 if (getfd() == -1) return false;
87
88 if (fchmod(getfd(), mode) != 0)
89 {
90 seterr(errno);
91 return false;
92 }
93
94 return true;
95}
96
97
98bool WvAtomicFile::chown(uid_t owner, gid_t group)
99{
100 if (getfd() == -1) return false;
101
102 if (fchown(getfd(), owner, group) != 0)
103 {
104 seterr(errno);
105 return false;
106 }
107
108 return true;
109}
void close()
Closes the file descriptors.
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
Definition wvstring.h:94
int getfd() const
Returns the Unix file descriptor for reading and writing.
Definition wvfdstream.h:81
virtual void close()
Closes the file descriptors.
virtual void seterr(int _errnum)
Override seterr() from WvError so that it auto-closes the stream.
Definition wvstream.cc:451
WvString is an implementation of a simple and efficient printable-string class.
Definition wvstring.h:330
Various little string functions.