LCOV - code coverage report
Current view: top level - src/backend/utils/misc - ps_status.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 74.0 % 146 108
Test Date: 2026-01-26 10:56:24 Functions: 87.5 % 8 7
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 64.8 % 91 59

             Branch data     Line data    Source code
       1                 :             : /*--------------------------------------------------------------------
       2                 :             :  * ps_status.c
       3                 :             :  *
       4                 :             :  * Routines to support changing the ps display of PostgreSQL backends
       5                 :             :  * to contain some useful information. Mechanism differs wildly across
       6                 :             :  * platforms.
       7                 :             :  *
       8                 :             :  * src/backend/utils/misc/ps_status.c
       9                 :             :  *
      10                 :             :  * Copyright (c) 2000-2026, PostgreSQL Global Development Group
      11                 :             :  * various details abducted from various places
      12                 :             :  *--------------------------------------------------------------------
      13                 :             :  */
      14                 :             : 
      15                 :             : #include "postgres.h"
      16                 :             : 
      17                 :             : #include <unistd.h>
      18                 :             : #if defined(__darwin__)
      19                 :             : #include <crt_externs.h>
      20                 :             : #endif
      21                 :             : 
      22                 :             : #include "miscadmin.h"
      23                 :             : #include "utils/guc.h"
      24                 :             : #include "utils/ps_status.h"
      25                 :             : 
      26                 :             : #if !defined(WIN32)
      27                 :             : extern char **environ;
      28                 :             : #endif
      29                 :             : 
      30                 :             : /* GUC variable */
      31                 :             : bool            update_process_title = DEFAULT_UPDATE_PROCESS_TITLE;
      32                 :             : 
      33                 :             : /*
      34                 :             :  * Alternative ways of updating ps display:
      35                 :             :  *
      36                 :             :  * PS_USE_SETPROCTITLE_FAST
      37                 :             :  *         use the function setproctitle_fast(const char *, ...)
      38                 :             :  *         (FreeBSD)
      39                 :             :  * PS_USE_SETPROCTITLE
      40                 :             :  *         use the function setproctitle(const char *, ...)
      41                 :             :  *         (other BSDs)
      42                 :             :  * PS_USE_CLOBBER_ARGV
      43                 :             :  *         write over the argv and environment area
      44                 :             :  *         (Linux and most SysV-like systems)
      45                 :             :  * PS_USE_WIN32
      46                 :             :  *         push the string out as the name of a Windows event
      47                 :             :  * PS_USE_NONE
      48                 :             :  *         don't update ps display
      49                 :             :  *         (This is the default, as it is safest.)
      50                 :             :  */
      51                 :             : #if defined(HAVE_SETPROCTITLE_FAST)
      52                 :             : #define PS_USE_SETPROCTITLE_FAST
      53                 :             : #elif defined(HAVE_SETPROCTITLE)
      54                 :             : #define PS_USE_SETPROCTITLE
      55                 :             : #elif defined(__linux__) || defined(__sun) || defined(__darwin__) || defined(__GNU__)
      56                 :             : #define PS_USE_CLOBBER_ARGV
      57                 :             : #elif defined(WIN32)
      58                 :             : #define PS_USE_WIN32
      59                 :             : #else
      60                 :             : #define PS_USE_NONE
      61                 :             : #endif
      62                 :             : 
      63                 :             : 
      64                 :             : /* Different systems want the buffer padded differently */
      65                 :             : #if defined(__linux__) || defined(__darwin__) || defined(__GNU__)
      66                 :             : #define PS_PADDING '\0'
      67                 :             : #else
      68                 :             : #define PS_PADDING ' '
      69                 :             : #endif
      70                 :             : 
      71                 :             : 
      72                 :             : #ifndef PS_USE_NONE
      73                 :             : 
      74                 :             : #ifndef PS_USE_CLOBBER_ARGV
      75                 :             : /* all but one option need a buffer to write their ps line in */
      76                 :             : #define PS_BUFFER_SIZE 256
      77                 :             : static char ps_buffer[PS_BUFFER_SIZE];
      78                 :             : static const size_t ps_buffer_size = PS_BUFFER_SIZE;
      79                 :             : #else                                                   /* PS_USE_CLOBBER_ARGV */
      80                 :             : static char *ps_buffer;                 /* will point to argv area */
      81                 :             : static size_t ps_buffer_size;   /* space determined at run time */
      82                 :             : static size_t last_status_len;  /* use to minimize length of clobber */
      83                 :             : #endif                                                  /* PS_USE_CLOBBER_ARGV */
      84                 :             : 
      85                 :             : static size_t ps_buffer_cur_len;        /* nominal strlen(ps_buffer) */
      86                 :             : 
      87                 :             : static size_t ps_buffer_fixed_size; /* size of the constant prefix */
      88                 :             : 
      89                 :             : /*
      90                 :             :  * Length of ps_buffer before the suffix was appended to the end, or 0 if we
      91                 :             :  * didn't set a suffix.
      92                 :             :  */
      93                 :             : static size_t ps_buffer_nosuffix_len;
      94                 :             : 
      95                 :             : static void flush_ps_display(void);
      96                 :             : 
      97                 :             : #endif                                                  /* not PS_USE_NONE */
      98                 :             : 
      99                 :             : /* save the original argv[] location here */
     100                 :             : static int      save_argc;
     101                 :             : static char **save_argv;
     102                 :             : 
     103                 :             : /*
     104                 :             :  * Valgrind seems not to consider the global "environ" variable as a valid
     105                 :             :  * root pointer; so when we allocate a new environment array, it claims that
     106                 :             :  * data is leaked.  To fix that, keep our own statically-allocated copy of the
     107                 :             :  * pointer.  (Oddly, this doesn't seem to be a problem for "argv".)
     108                 :             :  */
     109                 :             : #if defined(PS_USE_CLOBBER_ARGV) && defined(USE_VALGRIND)
     110                 :             : extern char **ps_status_new_environ;
     111                 :             : char      **ps_status_new_environ;
     112                 :             : #endif
     113                 :             : 
     114                 :             : 
     115                 :             : /*
     116                 :             :  * Call this early in startup to save the original argc/argv values.
     117                 :             :  * If needed, we make a copy of the original argv[] array to preserve it
     118                 :             :  * from being clobbered by subsequent ps_display actions.
     119                 :             :  *
     120                 :             :  * (The original argv[] will not be overwritten by this routine, but may be
     121                 :             :  * overwritten during init_ps_display.  Also, the physical location of the
     122                 :             :  * environment strings may be moved, so this should be called before any code
     123                 :             :  * that might try to hang onto a getenv() result.  But see hack for musl
     124                 :             :  * within.)
     125                 :             :  *
     126                 :             :  * Note that in case of failure this cannot call elog() as that is not
     127                 :             :  * initialized yet.  We rely on write_stderr() instead.
     128                 :             :  */
     129                 :             : char      **
     130                 :           8 : save_ps_display_args(int argc, char **argv)
     131                 :             : {
     132                 :           8 :         save_argc = argc;
     133                 :           8 :         save_argv = argv;
     134                 :             : 
     135                 :             : #if defined(PS_USE_CLOBBER_ARGV)
     136                 :             : 
     137                 :             :         /*
     138                 :             :          * If we're going to overwrite the argv area, count the available space.
     139                 :             :          * Also move the environment strings to make additional room.
     140                 :             :          */
     141                 :             :         {
     142                 :           8 :                 char       *end_of_area = NULL;
     143                 :           8 :                 char      **new_environ;
     144                 :           8 :                 int                     i;
     145                 :             : 
     146                 :             :                 /*
     147                 :             :                  * check for contiguous argv strings
     148                 :             :                  */
     149         [ +  + ]:          70 :                 for (i = 0; i < argc; i++)
     150                 :             :                 {
     151   [ +  +  -  + ]:          62 :                         if (i == 0 || end_of_area + 1 == argv[i])
     152                 :          62 :                                 end_of_area = argv[i] + strlen(argv[i]);
     153                 :          62 :                 }
     154                 :             : 
     155         [ +  - ]:           8 :                 if (end_of_area == NULL)        /* probably can't happen? */
     156                 :             :                 {
     157                 :           0 :                         ps_buffer = NULL;
     158                 :           0 :                         ps_buffer_size = 0;
     159                 :           0 :                         return argv;
     160                 :             :                 }
     161                 :             : 
     162                 :             :                 /*
     163                 :             :                  * check for contiguous environ strings following argv
     164                 :             :                  */
     165         [ +  + ]:         377 :                 for (i = 0; environ[i] != NULL; i++)
     166                 :             :                 {
     167         [ -  + ]:         369 :                         if (end_of_area + 1 == environ[i])
     168                 :             :                         {
     169                 :             :                                 /*
     170                 :             :                                  * The musl dynamic linker keeps a static pointer to the
     171                 :             :                                  * initial value of LD_LIBRARY_PATH, if that is defined in the
     172                 :             :                                  * process's environment. Therefore, we must not overwrite the
     173                 :             :                                  * value of that setting and thus cannot advance end_of_area
     174                 :             :                                  * beyond it.  Musl does not define any identifying compiler
     175                 :             :                                  * symbol, so we have to do this unless we see a symbol
     176                 :             :                                  * identifying a Linux libc we know is safe.
     177                 :             :                                  */
     178                 :             : #if defined(__linux__) && (!defined(__GLIBC__) && !defined(__UCLIBC__))
     179                 :             :                                 if (strncmp(environ[i], "LD_LIBRARY_PATH=", 16) == 0)
     180                 :             :                                 {
     181                 :             :                                         /*
     182                 :             :                                          * We can overwrite the name, but stop at the equals sign.
     183                 :             :                                          * Future loop iterations will not find any more
     184                 :             :                                          * contiguous space, but we don't break early because we
     185                 :             :                                          * need to count the total number of environ[] entries.
     186                 :             :                                          */
     187                 :             :                                         end_of_area = environ[i] + 15;
     188                 :             :                                 }
     189                 :             :                                 else
     190                 :             : #endif
     191                 :             :                                 {
     192                 :         369 :                                         end_of_area = environ[i] + strlen(environ[i]);
     193                 :             :                                 }
     194                 :         369 :                         }
     195                 :         369 :                 }
     196                 :             : 
     197                 :           8 :                 ps_buffer = argv[0];
     198                 :           8 :                 last_status_len = ps_buffer_size = end_of_area - argv[0];
     199                 :             : 
     200                 :             :                 /*
     201                 :             :                  * move the environment out of the way
     202                 :             :                  */
     203                 :           8 :                 new_environ = (char **) malloc((i + 1) * sizeof(char *));
     204         [ +  - ]:           8 :                 if (!new_environ)
     205                 :             :                 {
     206                 :           0 :                         write_stderr("out of memory\n");
     207                 :           0 :                         exit(1);
     208                 :             :                 }
     209         [ +  + ]:         377 :                 for (i = 0; environ[i] != NULL; i++)
     210                 :             :                 {
     211                 :         369 :                         new_environ[i] = strdup(environ[i]);
     212         [ +  - ]:         369 :                         if (!new_environ[i])
     213                 :             :                         {
     214                 :           0 :                                 write_stderr("out of memory\n");
     215                 :           0 :                                 exit(1);
     216                 :             :                         }
     217                 :         369 :                 }
     218                 :           8 :                 new_environ[i] = NULL;
     219                 :           8 :                 environ = new_environ;
     220                 :             : 
     221                 :             :                 /* See notes about Valgrind above. */
     222                 :             : #ifdef USE_VALGRIND
     223                 :             :                 ps_status_new_environ = new_environ;
     224                 :             : #endif
     225      [ -  -  + ]:           8 :         }
     226                 :             : 
     227                 :             :         /*
     228                 :             :          * If we're going to change the original argv[] then make a copy for
     229                 :             :          * argument parsing purposes.
     230                 :             :          *
     231                 :             :          * NB: do NOT think to remove the copying of argv[], even though
     232                 :             :          * postmaster.c finishes looking at argv[] long before we ever consider
     233                 :             :          * changing the ps display.  On some platforms, getopt() keeps pointers
     234                 :             :          * into the argv array, and will get horribly confused when it is
     235                 :             :          * re-called to analyze a subprocess' argument string if the argv storage
     236                 :             :          * has been clobbered meanwhile.  Other platforms have other dependencies
     237                 :             :          * on argv[].
     238                 :             :          */
     239                 :             :         {
     240                 :           8 :                 char      **new_argv;
     241                 :           8 :                 int                     i;
     242                 :             : 
     243                 :           8 :                 new_argv = (char **) malloc((argc + 1) * sizeof(char *));
     244         [ +  - ]:           8 :                 if (!new_argv)
     245                 :             :                 {
     246                 :           0 :                         write_stderr("out of memory\n");
     247                 :           0 :                         exit(1);
     248                 :             :                 }
     249         [ +  + ]:          70 :                 for (i = 0; i < argc; i++)
     250                 :             :                 {
     251                 :          62 :                         new_argv[i] = strdup(argv[i]);
     252         [ +  - ]:          62 :                         if (!new_argv[i])
     253                 :             :                         {
     254                 :           0 :                                 write_stderr("out of memory\n");
     255                 :           0 :                                 exit(1);
     256                 :             :                         }
     257                 :          62 :                 }
     258                 :           8 :                 new_argv[argc] = NULL;
     259                 :             : 
     260                 :             : #if defined(__darwin__)
     261                 :             : 
     262                 :             :                 /*
     263                 :             :                  * macOS has a static copy of the argv pointer, which we may fix like
     264                 :             :                  * so:
     265                 :             :                  */
     266                 :           8 :                 *_NSGetArgv() = new_argv;
     267                 :             : #endif
     268                 :             : 
     269                 :           8 :                 argv = new_argv;
     270                 :           8 :         }
     271                 :             : #endif                                                  /* PS_USE_CLOBBER_ARGV */
     272                 :             : 
     273                 :           8 :         return argv;
     274                 :           8 : }
     275                 :             : 
     276                 :             : /*
     277                 :             :  * Call this once during subprocess startup to set the identification
     278                 :             :  * values.
     279                 :             :  *
     280                 :             :  * If fixed_part is NULL, a default will be obtained from MyBackendType.
     281                 :             :  *
     282                 :             :  * At this point, the original argv[] array may be overwritten.
     283                 :             :  */
     284                 :             : void
     285                 :         804 : init_ps_display(const char *fixed_part)
     286                 :             : {
     287                 :             : #ifndef PS_USE_NONE
     288                 :         804 :         bool            save_update_process_title;
     289                 :             : #endif
     290                 :             : 
     291   [ +  +  +  - ]:         804 :         Assert(fixed_part || MyBackendType);
     292         [ +  + ]:         804 :         if (!fixed_part)
     293                 :          10 :                 fixed_part = GetBackendTypeDesc(MyBackendType);
     294                 :             : 
     295                 :             : #ifndef PS_USE_NONE
     296                 :             :         /* no ps display for stand-alone backend */
     297         [ +  - ]:         804 :         if (!IsUnderPostmaster)
     298                 :           0 :                 return;
     299                 :             : 
     300                 :             :         /* no ps display if you didn't call save_ps_display_args() */
     301         [ +  - ]:         804 :         if (!save_argv)
     302                 :           0 :                 return;
     303                 :             : 
     304                 :             : #ifdef PS_USE_CLOBBER_ARGV
     305                 :             :         /* If ps_buffer is a pointer, it might still be null */
     306         [ +  - ]:         804 :         if (!ps_buffer)
     307                 :           0 :                 return;
     308                 :             : 
     309                 :             :         /* make extra argv slots point at end_of_area (a NUL) */
     310         [ +  + ]:        3305 :         for (int i = 1; i < save_argc; i++)
     311                 :        2501 :                 save_argv[i] = ps_buffer + ps_buffer_size;
     312                 :             : #endif                                                  /* PS_USE_CLOBBER_ARGV */
     313                 :             : 
     314                 :             :         /*
     315                 :             :          * Make fixed prefix of ps display.
     316                 :             :          */
     317                 :             : 
     318                 :             : #if defined(PS_USE_SETPROCTITLE) || defined(PS_USE_SETPROCTITLE_FAST)
     319                 :             : 
     320                 :             :         /*
     321                 :             :          * apparently setproctitle() already adds a `progname:' prefix to the ps
     322                 :             :          * line
     323                 :             :          */
     324                 :             : #define PROGRAM_NAME_PREFIX ""
     325                 :             : #else
     326                 :             : #define PROGRAM_NAME_PREFIX "postgres: "
     327                 :             : #endif
     328                 :             : 
     329         [ +  + ]:         804 :         if (*cluster_name == '\0')
     330                 :             :         {
     331                 :          48 :                 snprintf(ps_buffer, ps_buffer_size,
     332                 :             :                                  PROGRAM_NAME_PREFIX "%s ",
     333                 :          24 :                                  fixed_part);
     334                 :          24 :         }
     335                 :             :         else
     336                 :             :         {
     337                 :        1560 :                 snprintf(ps_buffer, ps_buffer_size,
     338                 :             :                                  PROGRAM_NAME_PREFIX "%s: %s ",
     339                 :         780 :                                  cluster_name, fixed_part);
     340                 :             :         }
     341                 :             : 
     342                 :         804 :         ps_buffer_cur_len = ps_buffer_fixed_size = strlen(ps_buffer);
     343                 :             : 
     344                 :             :         /*
     345                 :             :          * On the first run, force the update.
     346                 :             :          */
     347                 :         804 :         save_update_process_title = update_process_title;
     348                 :         804 :         update_process_title = true;
     349                 :         804 :         set_ps_display("");
     350                 :         804 :         update_process_title = save_update_process_title;
     351                 :             : #endif                                                  /* not PS_USE_NONE */
     352         [ -  + ]:         804 : }
     353                 :             : 
     354                 :             : #ifndef PS_USE_NONE
     355                 :             : /*
     356                 :             :  * update_ps_display_precheck
     357                 :             :  *              Helper function to determine if updating the process title is
     358                 :             :  *              something that we need to do.
     359                 :             :  */
     360                 :             : static bool
     361                 :      120426 : update_ps_display_precheck(void)
     362                 :             : {
     363                 :             :         /* update_process_title=off disables updates */
     364         [ -  + ]:      120426 :         if (!update_process_title)
     365                 :           0 :                 return false;
     366                 :             : 
     367                 :             :         /* no ps display for stand-alone backend */
     368         [ +  + ]:      120426 :         if (!IsUnderPostmaster)
     369                 :        1581 :                 return false;
     370                 :             : 
     371                 :             : #ifdef PS_USE_CLOBBER_ARGV
     372                 :             :         /* If ps_buffer is a pointer, it might still be null */
     373         [ +  - ]:      118845 :         if (!ps_buffer)
     374                 :           0 :                 return false;
     375                 :             : #endif
     376                 :             : 
     377                 :      118845 :         return true;
     378                 :      120426 : }
     379                 :             : #endif                                                  /* not PS_USE_NONE */
     380                 :             : 
     381                 :             : /*
     382                 :             :  * set_ps_display_suffix
     383                 :             :  *              Adjust the process title to append 'suffix' onto the end with a space
     384                 :             :  *              between it and the current process title.
     385                 :             :  */
     386                 :             : void
     387                 :          43 : set_ps_display_suffix(const char *suffix)
     388                 :             : {
     389                 :             : #ifndef PS_USE_NONE
     390                 :          43 :         size_t          len;
     391                 :             : 
     392                 :             :         /* first, check if we need to update the process title */
     393         [ +  - ]:          43 :         if (!update_ps_display_precheck())
     394                 :           0 :                 return;
     395                 :             : 
     396                 :             :         /* if there's already a suffix, overwrite it */
     397         [ -  + ]:          43 :         if (ps_buffer_nosuffix_len > 0)
     398                 :           0 :                 ps_buffer_cur_len = ps_buffer_nosuffix_len;
     399                 :             :         else
     400                 :          43 :                 ps_buffer_nosuffix_len = ps_buffer_cur_len;
     401                 :             : 
     402                 :          43 :         len = strlen(suffix);
     403                 :             : 
     404                 :             :         /* check if we have enough space to append the suffix */
     405         [ -  + ]:          43 :         if (ps_buffer_cur_len + len + 1 >= ps_buffer_size)
     406                 :             :         {
     407                 :             :                 /* not enough space.  Check the buffer isn't full already */
     408         [ #  # ]:           0 :                 if (ps_buffer_cur_len < ps_buffer_size - 1)
     409                 :             :                 {
     410                 :             :                         /* append a space before the suffix */
     411                 :           0 :                         ps_buffer[ps_buffer_cur_len++] = ' ';
     412                 :             : 
     413                 :             :                         /* just add what we can and fill the ps_buffer */
     414                 :           0 :                         memcpy(ps_buffer + ps_buffer_cur_len, suffix,
     415                 :             :                                    ps_buffer_size - ps_buffer_cur_len - 1);
     416                 :           0 :                         ps_buffer[ps_buffer_size - 1] = '\0';
     417                 :           0 :                         ps_buffer_cur_len = ps_buffer_size - 1;
     418                 :           0 :                 }
     419                 :           0 :         }
     420                 :             :         else
     421                 :             :         {
     422                 :          43 :                 ps_buffer[ps_buffer_cur_len++] = ' ';
     423                 :          43 :                 memcpy(ps_buffer + ps_buffer_cur_len, suffix, len + 1);
     424                 :          43 :                 ps_buffer_cur_len = ps_buffer_cur_len + len;
     425                 :             :         }
     426                 :             : 
     427         [ +  - ]:          43 :         Assert(strlen(ps_buffer) == ps_buffer_cur_len);
     428                 :             : 
     429                 :             :         /* and set the new title */
     430                 :          43 :         flush_ps_display();
     431                 :             : #endif                                                  /* not PS_USE_NONE */
     432         [ -  + ]:          43 : }
     433                 :             : 
     434                 :             : /*
     435                 :             :  * set_ps_display_remove_suffix
     436                 :             :  *              Remove the process display suffix added by set_ps_display_suffix
     437                 :             :  */
     438                 :             : void
     439                 :          42 : set_ps_display_remove_suffix(void)
     440                 :             : {
     441                 :             : #ifndef PS_USE_NONE
     442                 :             :         /* first, check if we need to update the process title */
     443         [ -  + ]:          42 :         if (!update_ps_display_precheck())
     444                 :           0 :                 return;
     445                 :             : 
     446                 :             :         /* check we added a suffix */
     447         [ +  - ]:          42 :         if (ps_buffer_nosuffix_len == 0)
     448                 :           0 :                 return;                                 /* no suffix */
     449                 :             : 
     450                 :             :         /* remove the suffix from ps_buffer */
     451                 :          42 :         ps_buffer[ps_buffer_nosuffix_len] = '\0';
     452                 :          42 :         ps_buffer_cur_len = ps_buffer_nosuffix_len;
     453                 :          42 :         ps_buffer_nosuffix_len = 0;
     454                 :             : 
     455         [ +  - ]:          42 :         Assert(ps_buffer_cur_len == strlen(ps_buffer));
     456                 :             : 
     457                 :             :         /* and set the new title */
     458                 :          42 :         flush_ps_display();
     459                 :             : #endif                                                  /* not PS_USE_NONE */
     460                 :          42 : }
     461                 :             : 
     462                 :             : /*
     463                 :             :  * Call this to update the ps status display to a fixed prefix plus an
     464                 :             :  * indication of what you're currently doing passed in the argument.
     465                 :             :  *
     466                 :             :  * 'len' must be the same as strlen(activity)
     467                 :             :  */
     468                 :             : void
     469                 :      120341 : set_ps_display_with_len(const char *activity, size_t len)
     470                 :             : {
     471         [ +  - ]:      120341 :         Assert(strlen(activity) == len);
     472                 :             : 
     473                 :             : #ifndef PS_USE_NONE
     474                 :             :         /* first, check if we need to update the process title */
     475         [ +  + ]:      120341 :         if (!update_ps_display_precheck())
     476                 :        1581 :                 return;
     477                 :             : 
     478                 :             :         /* wipe out any suffix when the title is completely changed */
     479                 :      118760 :         ps_buffer_nosuffix_len = 0;
     480                 :             : 
     481                 :             :         /* Update ps_buffer to contain both fixed part and activity */
     482         [ -  + ]:      118760 :         if (ps_buffer_fixed_size + len >= ps_buffer_size)
     483                 :             :         {
     484                 :             :                 /* handle the case where ps_buffer doesn't have enough space */
     485                 :           0 :                 memcpy(ps_buffer + ps_buffer_fixed_size, activity,
     486                 :             :                            ps_buffer_size - ps_buffer_fixed_size - 1);
     487                 :           0 :                 ps_buffer[ps_buffer_size - 1] = '\0';
     488                 :           0 :                 ps_buffer_cur_len = ps_buffer_size - 1;
     489                 :           0 :         }
     490                 :             :         else
     491                 :             :         {
     492                 :      118760 :                 memcpy(ps_buffer + ps_buffer_fixed_size, activity, len + 1);
     493                 :      118760 :                 ps_buffer_cur_len = ps_buffer_fixed_size + len;
     494                 :             :         }
     495         [ +  - ]:      118760 :         Assert(strlen(ps_buffer) == ps_buffer_cur_len);
     496                 :             : 
     497                 :             :         /* Transmit new setting to kernel, if necessary */
     498                 :      118760 :         flush_ps_display();
     499                 :             : #endif                                                  /* not PS_USE_NONE */
     500                 :      120341 : }
     501                 :             : 
     502                 :             : #ifndef PS_USE_NONE
     503                 :             : static void
     504                 :      118845 : flush_ps_display(void)
     505                 :             : {
     506                 :             : #ifdef PS_USE_SETPROCTITLE
     507                 :             :         setproctitle("%s", ps_buffer);
     508                 :             : #elif defined(PS_USE_SETPROCTITLE_FAST)
     509                 :             :         setproctitle_fast("%s", ps_buffer);
     510                 :             : #endif
     511                 :             : 
     512                 :             : #ifdef PS_USE_CLOBBER_ARGV
     513                 :             :         /* pad unused memory; need only clobber remainder of old status string */
     514         [ +  + ]:      118845 :         if (last_status_len > ps_buffer_cur_len)
     515   [ +  +  +  +  :       59205 :                 MemSet(ps_buffer + ps_buffer_cur_len, PS_PADDING,
          +  -  +  +  +  
                      + ]
     516                 :             :                            last_status_len - ps_buffer_cur_len);
     517                 :      118845 :         last_status_len = ps_buffer_cur_len;
     518                 :             : #endif                                                  /* PS_USE_CLOBBER_ARGV */
     519                 :             : 
     520                 :             : #ifdef PS_USE_WIN32
     521                 :             :         {
     522                 :             :                 /*
     523                 :             :                  * Win32 does not support showing any changed arguments. To make it at
     524                 :             :                  * all possible to track which backend is doing what, we create a
     525                 :             :                  * named object that can be viewed with for example Process Explorer.
     526                 :             :                  */
     527                 :             :                 static HANDLE ident_handle = INVALID_HANDLE_VALUE;
     528                 :             :                 char            name[PS_BUFFER_SIZE + 32];
     529                 :             : 
     530                 :             :                 if (ident_handle != INVALID_HANDLE_VALUE)
     531                 :             :                         CloseHandle(ident_handle);
     532                 :             : 
     533                 :             :                 sprintf(name, "pgident(%d): %s", MyProcPid, ps_buffer);
     534                 :             : 
     535                 :             :                 ident_handle = CreateEvent(NULL, TRUE, FALSE, name);
     536                 :             :         }
     537                 :             : #endif                                                  /* PS_USE_WIN32 */
     538                 :      118845 : }
     539                 :             : #endif                                                  /* not PS_USE_NONE */
     540                 :             : 
     541                 :             : /*
     542                 :             :  * Returns what's currently in the ps display, in case someone needs
     543                 :             :  * it.  Note that only the activity part is returned.  On some platforms
     544                 :             :  * the string will not be null-terminated, so return the effective
     545                 :             :  * length into *displen.
     546                 :             :  */
     547                 :             : const char *
     548                 :           0 : get_ps_display(int *displen)
     549                 :             : {
     550                 :             : #ifdef PS_USE_CLOBBER_ARGV
     551                 :             :         /* If ps_buffer is a pointer, it might still be null */
     552         [ #  # ]:           0 :         if (!ps_buffer)
     553                 :             :         {
     554                 :           0 :                 *displen = 0;
     555                 :           0 :                 return "";
     556                 :             :         }
     557                 :             : #endif
     558                 :             : 
     559                 :             : #ifndef PS_USE_NONE
     560                 :           0 :         *displen = (int) (ps_buffer_cur_len - ps_buffer_fixed_size);
     561                 :             : 
     562                 :           0 :         return ps_buffer + ps_buffer_fixed_size;
     563                 :             : #else
     564                 :             :         *displen = 0;
     565                 :             :         return "";
     566                 :             : #endif
     567                 :           0 : }
        

Generated by: LCOV version 2.3.2-1