diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 08:42:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 08:42:27 +0000 |
commit | 95f5f6d1c3aec1cb62525f5162e71a4157aca717 (patch) | |
tree | 8633546094df32b27d719c7578537e6062aa52e3 /src/util/vstream.c | |
parent | Releasing progress-linux version 3.8.6-1~progress7.99u1. (diff) | |
download | postfix-95f5f6d1c3aec1cb62525f5162e71a4157aca717.tar.xz postfix-95f5f6d1c3aec1cb62525f5162e71a4157aca717.zip |
Merging upstream version 3.9.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | src/util/vstream.c | 34 |
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); |