summaryrefslogtreecommitdiffstats
path: root/src/util/vstream.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 08:41:51 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 08:41:51 +0000
commit3e160e27e4686620d16477a9ea9cf00141e52ce7 (patch)
tree884561d26afa36d7653aa4dc43410e1ae479d43e /src/util/vstream.c
parentAdding upstream version 3.8.6. (diff)
downloadpostfix-3e160e27e4686620d16477a9ea9cf00141e52ce7.tar.xz
postfix-3e160e27e4686620d16477a9ea9cf00141e52ce7.zip
Adding upstream version 3.9.0.upstream/3.9.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/util/vstream.c')
-rw-r--r--src/util/vstream.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/src/util/vstream.c b/src/util/vstream.c
index b4f9fbb..affbcc0 100644
--- a/src/util/vstream.c
+++ b/src/util/vstream.c
@@ -522,6 +522,7 @@
/* System library. */
#include <sys_defs.h>
+#include <sys/stat.h>
#include <stdlib.h> /* 44BSD stdarg.h uses abort() */
#include <stdarg.h>
#include <stddef.h>
@@ -1386,7 +1387,38 @@ VSTREAM *vstream_fopen(const char *path, int flags, mode_t mode)
VSTREAM *stream;
int fd;
- if ((fd = open(path, flags, mode)) < 0) {
+ /*
+ * To set permissions on new files only, we need to distinguish between
+ * creating a new file and opening an existing one.
+ */
+#define open_create(path, flags, mode) \
+ open((path), (flags) | (O_CREAT | O_EXCL), (mode))
+#define open_exist(path, flags, mode) \
+ open((path), (flags) & ~(O_CREAT | O_EXCL), (mode))
+
+ switch (flags & (O_CREAT | O_EXCL)) {
+ case O_CREAT:
+ fd = open_exist(path, flags, mode);
+ if (fd < 0 && errno == ENOENT) {
+ fd = open_create(path, flags, mode);
+ if (fd >= 0) {
+ if (fchmod(fd, mode) < 0) /* can't uncreate */
+ msg_warn("fchmod %s 0%o: %m", path, (unsigned) mode);
+ } else if ( /* fd < 0 && */ errno == EEXIST)
+ fd = open_exist(path, flags, mode);
+ }
+ break;
+ case O_CREAT | O_EXCL:
+ fd = open(path, flags, mode);
+ if (fd >= 0)
+ if (fchmod(fd, mode) < 0) /* can't uncreate */
+ msg_warn("fchmod %s 0%o: %m", path, (unsigned) mode);
+ break;
+ default:
+ fd = open(path, flags, mode);
+ break;
+ }
+ if (fd < 0) {
return (0);
} else {
stream = vstream_fdopen(fd, flags);