]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add fr_bio_fd_reopen() API
authorAlan T. DeKok <aland@freeradius.org>
Thu, 3 Oct 2024 14:29:52 +0000 (10:29 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 8 Oct 2024 13:52:46 +0000 (09:52 -0400)
so that we can re-open a file BIO

src/lib/bio/fd.h
src/lib/bio/fd_open.c

index 04b2ac56dfbf635ee3cfcd252dbfc343664b3a64..d132988e5b4ea20975ff73966793b8a75cb7d235 100644 (file)
@@ -130,3 +130,5 @@ fr_bio_fd_info_t const *fr_bio_fd_info(fr_bio_t *bio) CC_HINT(nonnull);
 int            fr_bio_fd_open(fr_bio_t *bio, fr_bio_fd_config_t const *cfg) CC_HINT(nonnull);
 
 int            fr_bio_fd_write_only(fr_bio_t *bio);
+
+int            fr_bio_fd_reopen(fr_bio_t *bio);
index e12676d82d57298987f360a568d4bccd43d3e66d..899e313a7eb84a64eec4303e3fffa490228d6476 100644 (file)
@@ -799,16 +799,12 @@ int fr_bio_fd_open(fr_bio_t *bio, fr_bio_fd_config_t const *cfg)
                        fd = dup(STDERR_FILENO);
 
                } else {
-                       if (!cfg->mkdir) {
-                               fd = open(cfg->filename, cfg->flags, cfg->perm);
-                       } else {
-                               if (fr_mkdir(&fd, cfg->filename, fr_mkdir_chown, &(fr_mkdir_chown_t) {
-                                                       .uid = cfg->uid,
-                                                       .gid = cfg->gid,
-                                               }) < 0) {
-                                       return -1;
-                               }
-                       }
+                       /*
+                        *      Minor hacks so that we have only _one_ source of open / mkdir
+                        */
+                       my->info.socket.fd = -1;
+
+                       fd = fr_bio_fd_reopen(bio);
                }
                if (fd < 0) {
                        fr_strerror_printf("Failed opening file %s: %s", cfg->filename, fr_syserror(errno));
@@ -966,3 +962,54 @@ int fr_bio_fd_open(fr_bio_t *bio, fr_bio_fd_config_t const *cfg)
 
        return 0;
 }
+
+/** Reopen a file BIO
+ *
+ *  e.g. for log files.
+ */
+int fr_bio_fd_reopen(fr_bio_t *bio)
+{
+       fr_bio_fd_t *my = talloc_get_type_abort(bio, fr_bio_fd_t);
+       fr_bio_fd_config_t const *cfg = my->info.cfg;
+       int fd;
+
+       if (my->info.socket.af != AF_FILE_BIO) {
+               fr_strerror_const("Cannot reopen a non-file BIO");
+               return -1;
+       }
+
+       if (!cfg->mkdir) {
+               fd = open(cfg->filename, cfg->flags, cfg->perm);
+               if (fd < 0) {
+                       fr_strerror_printf("Failed opening file %s: %s", cfg->filename, fr_syserror(errno));
+                       return -1;
+               }
+
+       } else if (fr_mkdir(&fd, cfg->filename, strlen(cfg->filename), cfg->perm,
+                           fr_mkdir_chown, &(fr_mkdir_chown_t) {
+                                   .uid = cfg->uid,
+                                   .gid = cfg->gid,
+                           }) < 0) {
+               return -1;
+       }
+
+       /*
+        *      We're boot-strapping, just set the new FD and return.
+        */
+       if (my->info.socket.fd < 0) {
+               return fd;
+       }
+
+       /*
+        *      Replace the FD rather than swapping it out with a new one.  This is potentially more
+        *      thread-safe.
+        */
+       if (dup2(fd, my->info.socket.fd) < 0) {
+               close(fd);
+               fr_strerror_printf("Failed reopening file - %s", fr_syserror(errno));
+               return -1;
+       }
+
+       close(fd);
+       return my->info.socket.fd;
+}