186 lines
6.1 KiB
C++
186 lines
6.1 KiB
C++
#include "ProcessRename.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
|
|
typedef size_t Size;
|
|
#define LONG_ALIGN_MASK (sizeof(long) - 1)
|
|
#define MEMSET_LOOP_LIMIT 1024
|
|
#define MemSet(start, val, len) \
|
|
do \
|
|
{ \
|
|
/* must be void* because we don't know if it is integer aligned yet */ \
|
|
void *_vstart = (void *) (start); \
|
|
int _val = (val); \
|
|
Size _len = (len); \
|
|
\
|
|
if ((((long) _vstart) & LONG_ALIGN_MASK) == 0 && \
|
|
(_len & LONG_ALIGN_MASK) == 0 && \
|
|
_val == 0 && \
|
|
_len <= MEMSET_LOOP_LIMIT && \
|
|
/* \
|
|
* If MEMSET_LOOP_LIMIT == 0, optimizer should find \
|
|
* the whole "if" false at compile time. \
|
|
*/ \
|
|
MEMSET_LOOP_LIMIT != 0) \
|
|
{ \
|
|
long *_start = (long *) _vstart; \
|
|
long *_stop = (long *) ((char *) _start + _len); \
|
|
while (_start < _stop) \
|
|
*_start++ = 0; \
|
|
} \
|
|
else \
|
|
memset(_vstart, _val, _len); \
|
|
} while (0)
|
|
|
|
#define PS_PADDING '\0'
|
|
|
|
extern char **environ;
|
|
bool update_process_title = true;
|
|
|
|
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 */
|
|
static size_t ps_buffer_cur_len; /* nominal strlen(ps_buffer) */
|
|
static size_t ps_buffer_fixed_size; /* size of the constant prefix */
|
|
|
|
static int save_argc;
|
|
static char **save_argv;
|
|
|
|
size_t strlcpy(char *dst, const char *src, size_t siz)
|
|
{
|
|
char *d = dst;
|
|
const char *s = src;
|
|
size_t n = siz;
|
|
|
|
/* Copy as many bytes as will fit */
|
|
if (n != 0)
|
|
{
|
|
while (--n != 0)
|
|
{
|
|
if ((*d++ = *s++) == '\0')
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Not enough room in dst, add NUL and traverse rest of src */
|
|
if (n == 0)
|
|
{
|
|
if (siz != 0)
|
|
*d = '\0'; /* NUL-terminate dst */
|
|
while (*s++)
|
|
;
|
|
}
|
|
|
|
return (s - src - 1); /* count does not include NUL */
|
|
}
|
|
|
|
|
|
void set_ps_display(const char *activity, bool force)
|
|
{
|
|
/* update_process_title=off disables updates, unless force = true */
|
|
if (!force && !update_process_title)
|
|
return;
|
|
|
|
/* no ps display for stand-alone backend */
|
|
//if (!IsUnderPostmaster)
|
|
// return;
|
|
|
|
/* If ps_buffer is a pointer, it might still be null */
|
|
if (!ps_buffer)
|
|
return;
|
|
/* Update ps_buffer to contain both fixed part and activity */
|
|
strlcpy(ps_buffer + ps_buffer_fixed_size, activity,
|
|
ps_buffer_size - ps_buffer_fixed_size);
|
|
ps_buffer_cur_len = strlen(ps_buffer);
|
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
|
char ** save_ps_display_args(int argc, char **argv)
|
|
{
|
|
save_argc = argc;
|
|
save_argv = argv;
|
|
|
|
/*
|
|
* If we're going to overwrite the argv area, count the available space.
|
|
* Also move the environment to make additional room.
|
|
*/
|
|
{
|
|
char *end_of_area = NULL;
|
|
char **new_environ;
|
|
int i;
|
|
|
|
/*
|
|
* check for contiguous argv strings
|
|
*/
|
|
for (i = 0; i < argc; i++)
|
|
{
|
|
if (i == 0 || end_of_area + 1 == argv[i])
|
|
end_of_area = argv[i] + strlen(argv[i]);
|
|
}
|
|
|
|
if (end_of_area == NULL) /* probably can't happen? */
|
|
{
|
|
ps_buffer = NULL;
|
|
ps_buffer_size = 0;
|
|
return argv;
|
|
}
|
|
|
|
/*
|
|
* check for contiguous environ strings following argv
|
|
*/
|
|
for (i = 0; environ[i] != NULL; i++)
|
|
{
|
|
if (end_of_area + 1 == environ[i])
|
|
end_of_area = environ[i] + strlen(environ[i]);
|
|
}
|
|
|
|
ps_buffer = argv[0];
|
|
last_status_len = ps_buffer_size = end_of_area - argv[0];
|
|
|
|
/*
|
|
* move the environment out of the way
|
|
*/
|
|
new_environ = (char **) malloc((i + 1) * sizeof(char *));
|
|
for (i = 0; environ[i] != NULL; i++)
|
|
new_environ[i] = strdup(environ[i]);
|
|
new_environ[i] = NULL;
|
|
environ = new_environ;
|
|
}
|
|
|
|
/*
|
|
* If we're going to change the original argv[] then make a copy for
|
|
* argument parsing purposes.
|
|
*
|
|
* (NB: do NOT think to remove the copying of argv[], even though
|
|
* postmaster.c finishes looking at argv[] long before we ever consider
|
|
* changing the ps display. On some platforms, getopt() keeps pointers
|
|
* into the argv array, and will get horribly confused when it is
|
|
* re-called to analyze a subprocess' argument string if the argv storage
|
|
* has been clobbered meanwhile. Other platforms have other dependencies
|
|
* on argv[].
|
|
*/
|
|
{
|
|
char **new_argv;
|
|
int i;
|
|
|
|
new_argv = (char **) malloc((argc + 1) * sizeof(char *));
|
|
for (i = 0; i < argc; i++)
|
|
new_argv[i] = strdup(argv[i]);
|
|
new_argv[argc] = NULL;
|
|
|
|
argv = new_argv;
|
|
}
|
|
|
|
return argv;
|
|
|
|
}
|
|
|