diff options
Diffstat (limited to 'openbsd-compat/setproctitle.c')
-rw-r--r-- | openbsd-compat/setproctitle.c | 288 |
1 files changed, 218 insertions, 70 deletions
diff --git a/openbsd-compat/setproctitle.c b/openbsd-compat/setproctitle.c index e165dd13c..5439bd07e 100644 --- a/openbsd-compat/setproctitle.c +++ b/openbsd-compat/setproctitle.c @@ -1,102 +1,250 @@ /* - * Modified for OpenSSH by Kevin Steves - * October 2000 + * Based on src/backend/utils/misc/pg_status.c from + * PostgreSQL Database Management System + * + * Portions Copyright (c) 1996-2001, The PostgreSQL Global Development Group + * + * Portions Copyright (c) 1994, The Regents of the University of California + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without a written agreement + * is hereby granted, provided that the above copyright notice and this + * paragraph and the following two paragraphs appear in all copies. + * + * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING + * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS + * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -/* - * Copyright (c) 1994, 1995 Christopher G. Demetriou - * All rights reserved. +/*-------------------------------------------------------------------- + * ps_status.c + * + * Routines to support changing the ps display of PostgreSQL backends + * to contain some useful information. Mechanism differs wildly across + * platforms. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Christopher G. Demetriou - * for the NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission + * $Header: /var/cvs/openssh/openbsd-compat/setproctitle.c,v 1.3 2003/01/09 22:53:13 djm Exp $ * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * Copyright 2000 by PostgreSQL Global Development Group + * various details abducted from various places + *-------------------------------------------------------------------- */ -#if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: setproctitle.c,v 1.8 2001/11/06 19:21:40 art Exp $"; -#endif /* LIBC_SCCS and not lint */ - #include "includes.h" #ifndef HAVE_SETPROCTITLE -#define SPT_NONE 0 -#define SPT_PSTAT 1 +#include <unistd.h> +#ifdef HAVE_SYS_PSTAT_H +#include <sys/pstat.h> /* for HP-UX */ +#endif +#ifdef HAVE_PS_STRINGS +#include <machine/vmparam.h> /* for old BSD */ +#include <sys/exec.h> +#endif + +extern char **environ; -#ifndef SPT_TYPE -#define SPT_TYPE SPT_NONE +/*------ + * Alternative ways of updating ps display: + * + * PS_USE_PSTAT + * use the pstat(PSTAT_SETCMD, ) + * (HPUX) + * PS_USE_PS_STRINGS + * assign PS_STRINGS->ps_argvstr = "string" + * (some BSD systems) + * PS_USE_CHANGE_ARGV + * assign argv[0] = "string" + * (some other BSD systems) + * PS_USE_CLOBBER_ARGV + * write over the argv and environment area + * (most SysV-like systems) + * PS_USE_NONE + * don't update ps display + * (This is the default, as it is safest.) + */ +#if defined(HAVE_PSTAT) && defined(PSTAT_SETCMD) +#define PS_USE_PSTAT +#elif defined(HAVE_PS_STRINGS) +#define PS_USE_PS_STRINGS +#elif defined(BSD) || defined(__bsdi__) || defined(__hurd__) +#define PS_USE_CHANGE_ARGV +#elif defined(__linux__) || defined(_AIX) +#define PS_USE_CLOBBER_ARGV +#else +#define PS_USE_NONE #endif -#if SPT_TYPE == SPT_PSTAT -#include <sys/param.h> -#include <sys/pstat.h> -#endif /* SPT_TYPE == SPT_PSTAT */ +/* Different systems want the buffer padded differently */ +#if defined(_AIX) || defined(__linux__) || defined(__QNX__) || defined(__svr4__) +#define PS_PADDING '\0' +#else +#define PS_PADDING ' ' +#endif -#define MAX_PROCTITLE 2048 +/* + * argv clobbering uses existing argv space, all other methods need a buffer + */ +#ifndef PS_USE_CLOBBER_ARGV +static char ps_buffer[256]; +static const size_t ps_buffer_size = sizeof(ps_buffer); +#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 */ +#endif /* PS_USE_CLOBBER_ARGV */ + +/* save the original argv[] location here */ +static int save_argc; +static char **save_argv; extern char *__progname; /* - * Set Process Title (SPT) defines. Modeled after sendmail's - * SPT type definition strategy. - * - * SPT_TYPE: - * - * SPT_NONE: Don't set the process title. Default. - * SPT_PSTAT: Use pstat(PSTAT_SETCMD). HP-UX specific. + * Call this to update the ps status display to a fixed prefix plus an + * indication of what you're currently doing passed in the argument. */ - void setproctitle(const char *fmt, ...) { -#if SPT_TYPE != SPT_NONE +#ifdef PS_USE_PSTAT + union pstun pst; +#endif +#ifndef PS_USE_NONE + ssize_t used; va_list ap; - - char buf[MAX_PROCTITLE]; - size_t used; -#if SPT_TYPE == SPT_PSTAT - union pstun pst; -#endif /* SPT_TYPE == SPT_PSTAT */ + /* no ps display if you didn't call save_ps_display_args() */ + if (save_argv == NULL) + return; +#ifdef PS_USE_CLOBBER_ARGV + /* If ps_buffer is a pointer, it might still be null */ + if (ps_buffer == NULL) + return; +#endif /* PS_USE_CLOBBER_ARGV */ + + /* + * 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 + save_argv[1] = NULL; +#endif /* PS_USE_CLOBBER_ARGV */ + + /* + * Make fixed prefix of ps display. + */ va_start(ap, fmt); - if (fmt != NULL) { - used = snprintf(buf, MAX_PROCTITLE, "%s: ", __progname); - if (used >= MAX_PROCTITLE) - used = MAX_PROCTITLE - 1; - (void)vsnprintf(buf + used, MAX_PROCTITLE - used, fmt, ap); - } else - (void)snprintf(buf, MAX_PROCTITLE, "%s", __progname); + if (fmt == NULL) + snprintf(ps_buffer, ps_buffer_size, "%s", __progname); + else { + used = snprintf(ps_buffer, ps_buffer_size, "%s: ", __progname); + if (used == -1 || used >= ps_buffer_size) + used = ps_buffer_size; + vsnprintf(ps_buffer + used, ps_buffer_size - used, fmt, ap); + } va_end(ap); - used = strlen(buf); -#if SPT_TYPE == SPT_PSTAT - pst.pst_command = buf; - pstat(PSTAT_SETCMD, pst, used, 0, 0); -#endif /* SPT_TYPE == SPT_PSTAT */ +#if 0 + error("XXXXXXXXX %s", __progname); + error("XXXXXXXXX %d", ps_buffer_size); + error("XXXXXXXXX %s", ps_buffer); +#endif + +#ifdef PS_USE_PSTAT + pst.pst_command = ps_buffer; + pstat(PSTAT_SETCMD, pst, strlen(ps_buffer), 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 */ -#endif /* SPT_TYPE != SPT_NONE */ +#ifdef PS_USE_CLOBBER_ARGV + /* pad unused memory */ + used = strlen(ps_buffer); + memset(ps_buffer + used, PS_PADDING, ps_buffer_size - used); +#endif /* PS_USE_CLOBBER_ARGV */ + +#endif /* PS_USE_NONE */ } + #endif /* HAVE_SETPROCTITLE */ + +/* + * Call this early in startup to save the original argc/argv values. + * + * argv[] will not be overwritten by this routine, but may be overwritten + * during setproctitle. Also, the physical location of the environment + * strings may be moved, so this should be called before any code that + * might try to hang onto a getenv() result. + */ +void +compat_init_setproctitle(int argc, char *argv[]) +{ +#ifdef PS_USE_CLOBBER_ARGV + char *end_of_area = NULL; + char **new_environ; + int i; +#endif + + save_argc = argc; + save_argv = argv; + +#ifdef 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. + */ + + /* + * 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]); + } + + /* probably can't happen? */ + if (end_of_area == NULL) { + ps_buffer = NULL; + ps_buffer_size = 0; + return; + } + + /* + * 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]; + ps_buffer_size = end_of_area - argv[0] - 1; + + /* + * Duplicate and move the environment out of the way + */ + new_environ = malloc(sizeof(char *) * (i + 1)); + 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 */ +} + |