pg_upgrade: adjust umask() calls
authorBruce Momjian <bruce@momjian.us>
Thu, 25 Jul 2013 15:33:15 +0000 (11:33 -0400)
committerBruce Momjian <bruce@momjian.us>
Thu, 25 Jul 2013 15:33:15 +0000 (11:33 -0400)
Since pg_upgrade -j on Windows uses threads, calling umask()
before/after opening a file via fopen_priv() is no longer possible, so
set umask() as we enter the thread-creating loop, and reset it on exit.
Also adjust internal fopen_priv() calls to just use fopen().
Backpatch to 9.3beta.

contrib/pg_upgrade/dump.c
contrib/pg_upgrade/exec.c

index 8bf726b4c8d5404718cd3369386f2f167eed6dfa..2504c84a8e2210cb2e8a9d54ca447ec1efe45901 100644 (file)
@@ -17,6 +17,7 @@ void
 generate_old_dump(void)
 {
    int         dbnum;
+   mode_t      old_umask;
 
    prep_status("Creating dump of global objects");
 
@@ -31,6 +32,13 @@ generate_old_dump(void)
 
    prep_status("Creating dump of database schemas\n");
 
+   /*
+    * Set umask for this function, all functions it calls, and all
+    * subprocesses/threads it creates.  We can't use fopen_priv()
+    * as Windows uses threads and umask is process-global.
+    */
+   old_umask = umask(S_IRWXG | S_IRWXO);
+
    /* create per-db dump files */
    for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
    {
@@ -54,6 +62,8 @@ generate_old_dump(void)
    while (reap_child(true) == true)
        ;
 
+   umask(old_umask);
+
    end_progress_output();
    check_ok();
 }
index 005ded4af4995b805ecc72209f222a070b11b162..ef123a8eef3e8845b3ece12a5338fae2bbf7ac81 100644 (file)
@@ -47,12 +47,9 @@ exec_prog(const char *log_file, const char *opt_log_file,
 
 #define MAXCMDLEN (2 * MAXPGPATH)
    char        cmd[MAXCMDLEN];
-   mode_t      old_umask = 0;
    FILE       *log;
    va_list     ap;
 
-   old_umask = umask(S_IRWXG | S_IRWXO);
-
    written = strlcpy(cmd, SYSTEMQUOTE, sizeof(cmd));
    va_start(ap, fmt);
    written += vsnprintf(cmd + written, MAXCMDLEN - written, fmt, ap);
@@ -64,7 +61,7 @@ exec_prog(const char *log_file, const char *opt_log_file,
    if (written >= MAXCMDLEN)
        pg_log(PG_FATAL, "command too long\n");
 
-   log = fopen_priv(log_file, "a");
+   log = fopen(log_file, "a");
 
 #ifdef WIN32
    {
@@ -80,7 +77,7 @@ exec_prog(const char *log_file, const char *opt_log_file,
        for (iter = 0; iter < 4 && log == NULL; iter++)
        {
            sleep(1);
-           log = fopen_priv(log_file, "a");
+           log = fopen(log_file, "a");
        }
    }
 #endif
@@ -101,8 +98,6 @@ exec_prog(const char *log_file, const char *opt_log_file,
 
    result = system(cmd);
 
-   umask(old_umask);
-
    if (result != 0)
    {
        /* we might be in on a progress status line, so go to the next line */
@@ -131,7 +126,7 @@ exec_prog(const char *log_file, const char *opt_log_file,
     * never reused while the server is running, so it works fine.  We could
     * log these commands to a third file, but that just adds complexity.
     */
-   if ((log = fopen_priv(log_file, "a")) == NULL)
+   if ((log = fopen(log_file, "a")) == NULL)
        pg_log(PG_FATAL, "cannot write to log file %s\n", log_file);
    fprintf(log, "\n\n");
    fclose(log);