]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - db/metadump.c
xfs_db: fix metadump redirection (again)
[thirdparty/xfsprogs-dev.git] / db / metadump.c
index 67bdf14e37d8630471f6a9c6e503f86dea784ef3..3967df64588029decaaf86a42cd2a29b74fb1b78 100644 (file)
@@ -78,6 +78,7 @@ static int            obfuscate = 1;
 static int             zero_stale_data = 1;
 static int             show_warnings = 0;
 static int             progress_since_warning = 0;
+static bool            stdout_metadump;
 
 void
 metadump_init(void)
@@ -137,7 +138,7 @@ print_progress(const char *fmt, ...)
        va_end(ap);
        buf[sizeof(buf)-1] = '\0';
 
-       f = (outf == stdout) ? stderr : stdout;
+       f = stdout_metadump ? stderr : stdout;
        fprintf(f, "\r%-59s", buf);
        fflush(f);
        progress_since_warning = 1;
@@ -2750,7 +2751,8 @@ metadump_f(
        xfs_agnumber_t  agno;
        int             c;
        int             start_iocur_sp;
-       bool            stdout_metadump = false;
+       int             outfd = -1;
+       int             ret;
        char            *p;
 
        exitcode = 1;
@@ -2870,16 +2872,35 @@ metadump_f(
                 * metadump operation so that dbprintf and other messages
                 * are sent to the console instead of polluting the
                 * metadump stream.
+                *
+                * We get to do this the hard way because musl doesn't
+                * allow reassignment of stdout.
                 */
-               outf = stdout;
-               stdout = stderr;
+               fflush(stdout);
+               outfd = dup(STDOUT_FILENO);
+               if (outfd < 0) {
+                       perror("opening dump stream");
+                       goto out;
+               }
+               ret = dup2(STDERR_FILENO, STDOUT_FILENO);
+               if (ret < 0) {
+                       perror("redirecting stdout");
+                       close(outfd);
+                       goto out;
+               }
+               outf = fdopen(outfd, "a");
+               if (outf == NULL) {
+                       fprintf(stderr, "cannot create dump stream\n");
+                       dup2(outfd, STDOUT_FILENO);
+                       close(outfd);
+                       goto out;
+               }
                stdout_metadump = true;
        } else {
                outf = fopen(argv[optind], "wb");
                if (outf == NULL) {
                        print_warning("cannot create dump file");
-                       free(metablock);
-                       return 0;
+                       goto out;
                }
        }
 
@@ -2907,15 +2928,19 @@ metadump_f(
        if (progress_since_warning)
                fputc('\n', stdout_metadump ? stderr : stdout);
 
-       if (stdout_metadump)
-               stdout = outf;
-       else
-               fclose(outf);
+       if (stdout_metadump) {
+               fflush(outf);
+               fflush(stdout);
+               ret = dup2(outfd, STDOUT_FILENO);
+               if (ret < 0)
+                       perror("un-redirecting stdout");
+       }
+       fclose(outf);
 
        /* cleanup iocur stack */
        while (iocur_sp > start_iocur_sp)
                pop_cur();
-
+out:
        free(metablock);
 
        return 0;