]> granicus.if.org Git - postgresql/commitdiff
Change ps_status.c to explicitly track the current logical length of ps_buffer.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 27 May 2010 19:20:06 +0000 (19:20 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 27 May 2010 19:20:06 +0000 (19:20 +0000)
This saves cycles in get_ps_display() on many popular platforms, and more
importantly ensures that get_ps_display() will correctly return an empty
string if init_ps_display() hasn't been called yet.  Per trouble report
from Ray Stell, in which log_line_prefix %i produced junk early in backend
startup.

Back-patch to 8.0.  7.4 doesn't have %i and its version of get_ps_display()
makes no pretense of avoiding pad junk anyhow.

src/backend/utils/misc/ps_status.c

index cfc857de0a4407ceb65779986c3ffb8a4fcf0f26..224dab65b06e352ea298fbecc36839fe9f0e4d0a 100644 (file)
@@ -5,7 +5,7 @@
  * to contain some useful information. Mechanism differs wildly across
  * platforms.
  *
- * $PostgreSQL: pgsql/src/backend/utils/misc/ps_status.c,v 1.26.2.1 2005/11/22 18:23:25 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/misc/ps_status.c,v 1.26.2.2 2010/05/27 19:20:06 tgl Exp $
  *
  * Copyright (c) 2000-2005, PostgreSQL Global Development Group
  * various details abducted from various places
@@ -88,8 +88,11 @@ static const size_t ps_buffer_size = PS_BUFFER_SIZE;
 #else                                                  /* PS_USE_CLOBBER_ARGV */
 static char *ps_buffer;                        /* will point to argv area */
 static size_t ps_buffer_size;  /* space determined at run time */
+static size_t last_status_len; /* use to minimize length of clobber */
 #endif   /* PS_USE_CLOBBER_ARGV */
 
+static size_t ps_buffer_cur_len;               /* nominal strlen(ps_buffer) */
+
 static size_t ps_buffer_fixed_size;            /* size of the constant prefix */
 
 /* save the original argv[] location here */
@@ -174,7 +177,7 @@ save_ps_display_args(int argc, char **argv)
                }
 
                ps_buffer = argv[0];
-               ps_buffer_size = end_of_area - argv[0];
+               last_status_len = ps_buffer_size = end_of_area - argv[0];
 
                /*
                 * move the environment out of the way
@@ -290,7 +293,7 @@ init_ps_display(const char *username, const char *dbname,
                         username, dbname, host_info);
 #endif
 
-       ps_buffer_fixed_size = strlen(ps_buffer);
+       ps_buffer_cur_len = ps_buffer_fixed_size = strlen(ps_buffer);
 
 #ifdef WIN32
        pgwin32_update_ident(ps_buffer);
@@ -321,6 +324,7 @@ set_ps_display(const char *activity)
        /* Update ps_buffer to contain both fixed part and activity */
        StrNCpy(ps_buffer + ps_buffer_fixed_size, activity,
                        ps_buffer_size - ps_buffer_fixed_size);
+       ps_buffer_cur_len = strlen(ps_buffer);
 
        /* Transmit new setting to kernel, if necessary */
 
@@ -333,7 +337,7 @@ set_ps_display(const char *activity)
                union pstun pst;
 
                pst.pst_command = ps_buffer;
-               pstat(PSTAT_SETCMD, pst, strlen(ps_buffer), 0, 0);
+               pstat(PSTAT_SETCMD, pst, ps_buffer_cur_len, 0, 0);
        }
 #endif   /* PS_USE_PSTAT */
 
@@ -343,13 +347,11 @@ set_ps_display(const char *activity)
 #endif   /* PS_USE_PS_STRINGS */
 
 #ifdef PS_USE_CLOBBER_ARGV
-       {
-               int                     buflen;
-
-               /* pad unused memory */
-               buflen = strlen(ps_buffer);
-               MemSet(ps_buffer + buflen, PS_PADDING, ps_buffer_size - buflen);
-       }
+       /* pad unused memory; need only clobber remainder of old status string */
+       if (last_status_len > ps_buffer_cur_len)
+               MemSet(ps_buffer + ps_buffer_cur_len, PS_PADDING,
+                          last_status_len - ps_buffer_cur_len);
+       last_status_len = ps_buffer_cur_len;
 #endif   /* PS_USE_CLOBBER_ARGV */
 
 #ifdef WIN32
@@ -369,24 +371,15 @@ const char *
 get_ps_display(int *displen)
 {
 #ifdef PS_USE_CLOBBER_ARGV
-       size_t          offset;
-
        /* If ps_buffer is a pointer, it might still be null */
        if (!ps_buffer)
        {
                *displen = 0;
                return "";
        }
-
-       /* Remove any trailing spaces to offset the effect of PS_PADDING */
-       offset = ps_buffer_size;
-       while (offset > ps_buffer_fixed_size && ps_buffer[offset - 1] == PS_PADDING)
-               offset--;
-
-       *displen = offset - ps_buffer_fixed_size;
-#else
-       *displen = strlen(ps_buffer + ps_buffer_fixed_size);
 #endif
 
+       *displen = (int) (ps_buffer_cur_len - ps_buffer_fixed_size);
+
        return ps_buffer + ps_buffer_fixed_size;
 }