Header And Logo

PostgreSQL
| The world's most advanced open source database.

Functions | Variables

ps_status.h File Reference

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

char ** save_ps_display_args (int argc, char **argv)
void init_ps_display (const char *username, const char *dbname, const char *host_info, const char *initial_str)
void set_ps_display (const char *activity, bool force)
const char * get_ps_display (int *displen)

Variables

bool update_process_title

Function Documentation

const char* get_ps_display ( int *  displen  ) 

Definition at line 368 of file ps_status.c.

References ps_buffer, ps_buffer_cur_len, and ps_buffer_fixed_size.

Referenced by log_line_prefix(), ResolveRecoveryConflictWithVirtualXIDs(), SyncRepWaitForLSN(), WaitOnLock(), and write_csvlog().

{
#ifdef PS_USE_CLOBBER_ARGV
    /* If ps_buffer is a pointer, it might still be null */
    if (!ps_buffer)
    {
        *displen = 0;
        return "";
    }
#endif

    *displen = (int) (ps_buffer_cur_len - ps_buffer_fixed_size);

    return ps_buffer + ps_buffer_fixed_size;
}

void init_ps_display ( const char *  username,
const char *  dbname,
const char *  host_info,
const char *  initial_str 
)

Definition at line 216 of file ps_status.c.

References Assert, i, IsUnderPostmaster, ps_buffer, ps_buffer_cur_len, ps_buffer_fixed_size, ps_buffer_size, save_argc, save_argv, set_ps_display(), and snprintf().

Referenced by AutoVacLauncherMain(), AutoVacWorkerMain(), AuxiliaryProcessMain(), BackendInitialize(), do_start_bgworker(), PgArchiverMain(), PgstatCollectorMain(), and SysLoggerMain().

{
    Assert(username);
    Assert(dbname);
    Assert(host_info);

#ifndef PS_USE_NONE
    /* no ps display for stand-alone backend */
    if (!IsUnderPostmaster)
        return;

    /* no ps display if you didn't call save_ps_display_args() */
    if (!save_argv)
        return;

#ifdef PS_USE_CLOBBER_ARGV
    /* If ps_buffer is a pointer, it might still be null */
    if (!ps_buffer)
        return;
#endif

    /*
     * Overwrite argv[] to point at appropriate space, if needed
     */

#ifdef PS_USE_CHANGE_ARGV
    save_argv[0] = ps_buffer;
    save_argv[1] = NULL;
#endif   /* PS_USE_CHANGE_ARGV */

#ifdef PS_USE_CLOBBER_ARGV
    {
        int         i;

        /* make extra argv slots point at end_of_area (a NUL) */
        for (i = 1; i < save_argc; i++)
            save_argv[i] = ps_buffer + ps_buffer_size;
    }
#endif   /* PS_USE_CLOBBER_ARGV */

    /*
     * Make fixed prefix of ps display.
     */

#ifdef PS_USE_SETPROCTITLE

    /*
     * apparently setproctitle() already adds a `progname:' prefix to the ps
     * line
     */
    snprintf(ps_buffer, ps_buffer_size,
             "%s %s %s ",
             username, dbname, host_info);
#else
    snprintf(ps_buffer, ps_buffer_size,
             "postgres: %s %s %s ",
             username, dbname, host_info);
#endif

    ps_buffer_cur_len = ps_buffer_fixed_size = strlen(ps_buffer);

    set_ps_display(initial_str, true);
#endif   /* not PS_USE_NONE */
}

char** save_ps_display_args ( int  argc,
char **  argv 
)

Definition at line 117 of file ps_status.c.

References environ, i, malloc, NULL, ps_buffer, ps_buffer_size, save_argc, and save_argv.

Referenced by main().

{
    save_argc = argc;
    save_argv = argv;

#if defined(PS_USE_CLOBBER_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;
    }
#endif   /* PS_USE_CLOBBER_ARGV */

#if defined(PS_USE_CHANGE_ARGV) || defined(PS_USE_CLOBBER_ARGV)

    /*
     * 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;

#if defined(__darwin__)

        /*
         * Darwin (and perhaps other NeXT-derived platforms?) has a static
         * copy of the argv pointer, which we may fix like so:
         */
        *_NSGetArgv() = new_argv;
#endif

        argv = new_argv;
    }
#endif   /* PS_USE_CHANGE_ARGV or PS_USE_CLOBBER_ARGV */

    return argv;
}

void set_ps_display ( const char *  activity,
bool  force 
)

Definition at line 289 of file ps_status.c.

References FALSE, IsUnderPostmaster, MemSet, MyProcPid, name, NULL, ps_buffer, ps_buffer_cur_len, ps_buffer_fixed_size, PS_BUFFER_SIZE, ps_buffer_size, PS_PADDING, strlcpy(), TRUE, and update_process_title.

Referenced by AutoVacWorkerMain(), exec_bind_message(), exec_execute_message(), exec_parse_message(), exec_simple_query(), init_ps_display(), PerformAuthentication(), pgarch_archiveXlog(), PostgresMain(), ProcessIncomingNotify(), ResolveRecoveryConflictWithVirtualXIDs(), SendBaseBackup(), SyncRepWaitForLSN(), WaitOnLock(), WalRcvWaitForStartPosition(), XLogFileRead(), XLogSend(), and XLogWalRcvFlush().

{
#ifndef PS_USE_NONE
    /* 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;

#ifdef PS_USE_CLOBBER_ARGV
    /* If ps_buffer is a pointer, it might still be null */
    if (!ps_buffer)
        return;
#endif

    /* 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);

    /* Transmit new setting to kernel, if necessary */

#ifdef PS_USE_SETPROCTITLE
    setproctitle("%s", ps_buffer);
#endif

#ifdef PS_USE_PSTAT
    {
        union pstun pst;

        pst.pst_command = ps_buffer;
        pstat(PSTAT_SETCMD, pst, ps_buffer_cur_len, 0, 0);
    }
#endif   /* PS_USE_PSTAT */

#ifdef PS_USE_PS_STRINGS
    PS_STRINGS->ps_nargvstr = 1;
    PS_STRINGS->ps_argvstr = ps_buffer;
#endif   /* PS_USE_PS_STRINGS */

#ifdef PS_USE_CLOBBER_ARGV
    /* 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 PS_USE_WIN32
    {
        /*
         * Win32 does not support showing any changed arguments. To make it at
         * all possible to track which backend is doing what, we create a
         * named object that can be viewed with for example Process Explorer.
         */
        static HANDLE ident_handle = INVALID_HANDLE_VALUE;
        char        name[PS_BUFFER_SIZE + 32];

        if (ident_handle != INVALID_HANDLE_VALUE)
            CloseHandle(ident_handle);

        sprintf(name, "pgident(%d): %s", MyProcPid, ps_buffer);

        ident_handle = CreateEvent(NULL, TRUE, FALSE, name);
    }
#endif   /* PS_USE_WIN32 */
#endif   /* not PS_USE_NONE */
}


Variable Documentation