Kevin Steves | 8848b24 | 2000-10-18 13:11:44 +0000 | [diff] [blame] | 1 | /* |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 2 | * Based on src/backend/utils/misc/pg_status.c from |
| 3 | * PostgreSQL Database Management System |
| 4 | * |
| 5 | * Portions Copyright (c) 1996-2001, The PostgreSQL Global Development Group |
| 6 | * |
| 7 | * Portions Copyright (c) 1994, The Regents of the University of California |
| 8 | * |
| 9 | * Permission to use, copy, modify, and distribute this software and its |
| 10 | * documentation for any purpose, without fee, and without a written agreement |
| 11 | * is hereby granted, provided that the above copyright notice and this |
| 12 | * paragraph and the following two paragraphs appear in all copies. |
| 13 | * |
| 14 | * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR |
| 15 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING |
| 16 | * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS |
| 17 | * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE |
| 18 | * POSSIBILITY OF SUCH DAMAGE. |
| 19 | * |
| 20 | * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, |
| 21 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY |
| 22 | * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
| 23 | * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO |
| 24 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
Kevin Steves | 8848b24 | 2000-10-18 13:11:44 +0000 | [diff] [blame] | 25 | */ |
| 26 | |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 27 | /*-------------------------------------------------------------------- |
| 28 | * ps_status.c |
Kevin Steves | 8848b24 | 2000-10-18 13:11:44 +0000 | [diff] [blame] | 29 | * |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 30 | * Routines to support changing the ps display of PostgreSQL backends |
| 31 | * to contain some useful information. Mechanism differs wildly across |
| 32 | * platforms. |
Kevin Steves | 8848b24 | 2000-10-18 13:11:44 +0000 | [diff] [blame] | 33 | * |
Damien Miller | 140344b | 2003-01-20 13:15:10 +1100 | [diff] [blame] | 34 | * $Header: /var/cvs/openssh/openbsd-compat/setproctitle.c,v 1.5 2003/01/20 02:15:11 djm Exp $ |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 35 | * |
| 36 | * Copyright 2000 by PostgreSQL Global Development Group |
| 37 | * various details abducted from various places |
| 38 | *-------------------------------------------------------------------- |
Kevin Steves | 8848b24 | 2000-10-18 13:11:44 +0000 | [diff] [blame] | 39 | */ |
| 40 | |
Kevin Steves | 8848b24 | 2000-10-18 13:11:44 +0000 | [diff] [blame] | 41 | #include "includes.h" |
| 42 | |
Ben Lindstrom | 49a79c0 | 2000-11-17 03:47:20 +0000 | [diff] [blame] | 43 | #ifndef HAVE_SETPROCTITLE |
| 44 | |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 45 | #include <unistd.h> |
| 46 | #ifdef HAVE_SYS_PSTAT_H |
| 47 | #include <sys/pstat.h> /* for HP-UX */ |
| 48 | #endif |
| 49 | #ifdef HAVE_PS_STRINGS |
| 50 | #include <machine/vmparam.h> /* for old BSD */ |
| 51 | #include <sys/exec.h> |
Kevin Steves | 8848b24 | 2000-10-18 13:11:44 +0000 | [diff] [blame] | 52 | #endif |
| 53 | |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 54 | /*------ |
| 55 | * Alternative ways of updating ps display: |
| 56 | * |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 57 | * SETPROCTITLE_STRATEGY == PS_USE_PSTAT |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 58 | * use the pstat(PSTAT_SETCMD, ) |
| 59 | * (HPUX) |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 60 | * SETPROCTITLE_STRATEGY == PS_USE_PS_STRINGS |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 61 | * assign PS_STRINGS->ps_argvstr = "string" |
| 62 | * (some BSD systems) |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 63 | * SETPROCTITLE_STRATEGY == PS_USE_CHANGE_ARGV |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 64 | * assign argv[0] = "string" |
| 65 | * (some other BSD systems) |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 66 | * SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 67 | * write over the argv and environment area |
| 68 | * (most SysV-like systems) |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 69 | * SETPROCTITLE_STRATEGY == PS_USE_NONE |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 70 | * don't update ps display |
| 71 | * (This is the default, as it is safest.) |
| 72 | */ |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 73 | |
| 74 | #define PS_USE_NONE 0 |
| 75 | #define PS_USE_PSTAT 1 |
| 76 | #define PS_USE_PS_STRINGS 2 |
| 77 | #define PS_USE_CHANGE_ARGV 3 |
| 78 | #define PS_USE_CLOBBER_ARGV 4 |
| 79 | |
| 80 | #ifndef SETPROCTITLE_STRATEGY |
| 81 | # define SETPROCTITLE_STRATEGY PS_USE_NONE |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 82 | #endif |
| 83 | |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 84 | #ifndef SETPROCTITLE_PS_PADDING |
| 85 | # define SETPROCTITLE_PS_PADDING ' ' |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 86 | #endif |
Damien Miller | 140344b | 2003-01-20 13:15:10 +1100 | [diff] [blame] | 87 | #endif /* HAVE_SETPROCTITLE */ |
| 88 | |
| 89 | extern char **environ; |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 90 | |
| 91 | /* |
| 92 | * argv clobbering uses existing argv space, all other methods need a buffer |
| 93 | */ |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 94 | #if SETPROCTITLE_STRATEGY != PS_USE_CLOBBER_ARGV |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 95 | static char ps_buffer[256]; |
| 96 | static const size_t ps_buffer_size = sizeof(ps_buffer); |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 97 | #else |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 98 | static char *ps_buffer; /* will point to argv area */ |
| 99 | static size_t ps_buffer_size; /* space determined at run time */ |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 100 | #endif |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 101 | |
| 102 | /* save the original argv[] location here */ |
| 103 | static int save_argc; |
| 104 | static char **save_argv; |
Kevin Steves | 8848b24 | 2000-10-18 13:11:44 +0000 | [diff] [blame] | 105 | |
Kevin Steves | 8848b24 | 2000-10-18 13:11:44 +0000 | [diff] [blame] | 106 | extern char *__progname; |
Kevin Steves | 8848b24 | 2000-10-18 13:11:44 +0000 | [diff] [blame] | 107 | |
Damien Miller | 140344b | 2003-01-20 13:15:10 +1100 | [diff] [blame] | 108 | #ifndef HAVE_SETPROCTITLE |
Kevin Steves | 8848b24 | 2000-10-18 13:11:44 +0000 | [diff] [blame] | 109 | /* |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 110 | * Call this to update the ps status display to a fixed prefix plus an |
| 111 | * indication of what you're currently doing passed in the argument. |
Kevin Steves | 8848b24 | 2000-10-18 13:11:44 +0000 | [diff] [blame] | 112 | */ |
Kevin Steves | 8848b24 | 2000-10-18 13:11:44 +0000 | [diff] [blame] | 113 | void |
| 114 | setproctitle(const char *fmt, ...) |
| 115 | { |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 116 | #if SETPROCTITLE_STRATEGY == PS_USE_PSTAT |
Kevin Steves | 8848b24 | 2000-10-18 13:11:44 +0000 | [diff] [blame] | 117 | union pstun pst; |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 118 | #endif |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 119 | #if SETPROCTITLE_STRATEGY != PS_USE_NONE |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 120 | ssize_t used; |
| 121 | va_list ap; |
| 122 | |
| 123 | /* no ps display if you didn't call save_ps_display_args() */ |
| 124 | if (save_argv == NULL) |
| 125 | return; |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 126 | #if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 127 | /* If ps_buffer is a pointer, it might still be null */ |
| 128 | if (ps_buffer == NULL) |
| 129 | return; |
| 130 | #endif /* PS_USE_CLOBBER_ARGV */ |
| 131 | |
| 132 | /* |
| 133 | * Overwrite argv[] to point at appropriate space, if needed |
| 134 | */ |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 135 | #if SETPROCTITLE_STRATEGY == PS_USE_CHANGE_ARGV |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 136 | save_argv[0] = ps_buffer; |
| 137 | save_argv[1] = NULL; |
| 138 | #endif /* PS_USE_CHANGE_ARGV */ |
| 139 | |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 140 | #if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 141 | save_argv[1] = NULL; |
| 142 | #endif /* PS_USE_CLOBBER_ARGV */ |
| 143 | |
| 144 | /* |
| 145 | * Make fixed prefix of ps display. |
| 146 | */ |
Kevin Steves | 8848b24 | 2000-10-18 13:11:44 +0000 | [diff] [blame] | 147 | |
| 148 | va_start(ap, fmt); |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 149 | if (fmt == NULL) |
| 150 | snprintf(ps_buffer, ps_buffer_size, "%s", __progname); |
| 151 | else { |
| 152 | used = snprintf(ps_buffer, ps_buffer_size, "%s: ", __progname); |
| 153 | if (used == -1 || used >= ps_buffer_size) |
| 154 | used = ps_buffer_size; |
| 155 | vsnprintf(ps_buffer + used, ps_buffer_size - used, fmt, ap); |
| 156 | } |
Kevin Steves | 8848b24 | 2000-10-18 13:11:44 +0000 | [diff] [blame] | 157 | va_end(ap); |
Kevin Steves | 8848b24 | 2000-10-18 13:11:44 +0000 | [diff] [blame] | 158 | |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 159 | #if SETPROCTITLE_STRATEGY == PS_USE_PSTAT |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 160 | pst.pst_command = ps_buffer; |
| 161 | pstat(PSTAT_SETCMD, pst, strlen(ps_buffer), 0, 0); |
| 162 | #endif /* PS_USE_PSTAT */ |
| 163 | |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 164 | #if SETPROCTITLE_STRATEGY == PS_USE_PS_STRINGS |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 165 | PS_STRINGS->ps_nargvstr = 1; |
| 166 | PS_STRINGS->ps_argvstr = ps_buffer; |
| 167 | #endif /* PS_USE_PS_STRINGS */ |
| 168 | |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 169 | #if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 170 | /* pad unused memory */ |
| 171 | used = strlen(ps_buffer); |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 172 | memset(ps_buffer + used, SETPROCTITLE_PS_PADDING, |
| 173 | ps_buffer_size - used); |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 174 | #endif /* PS_USE_CLOBBER_ARGV */ |
| 175 | |
| 176 | #endif /* PS_USE_NONE */ |
Kevin Steves | 8848b24 | 2000-10-18 13:11:44 +0000 | [diff] [blame] | 177 | } |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 178 | |
Kevin Steves | 8848b24 | 2000-10-18 13:11:44 +0000 | [diff] [blame] | 179 | #endif /* HAVE_SETPROCTITLE */ |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 180 | |
| 181 | /* |
| 182 | * Call this early in startup to save the original argc/argv values. |
| 183 | * |
| 184 | * argv[] will not be overwritten by this routine, but may be overwritten |
| 185 | * during setproctitle. Also, the physical location of the environment |
| 186 | * strings may be moved, so this should be called before any code that |
| 187 | * might try to hang onto a getenv() result. |
| 188 | */ |
| 189 | void |
| 190 | compat_init_setproctitle(int argc, char *argv[]) |
| 191 | { |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 192 | #if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 193 | char *end_of_area = NULL; |
| 194 | char **new_environ; |
| 195 | int i; |
| 196 | #endif |
| 197 | |
| 198 | save_argc = argc; |
| 199 | save_argv = argv; |
| 200 | |
Damien Miller | ec20196 | 2003-01-13 10:04:58 +1100 | [diff] [blame] | 201 | #if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV |
Damien Miller | a8ed44b | 2003-01-10 09:53:12 +1100 | [diff] [blame] | 202 | /* |
| 203 | * If we're going to overwrite the argv area, count the available |
| 204 | * space. Also move the environment to make additional room. |
| 205 | */ |
| 206 | |
| 207 | /* |
| 208 | * check for contiguous argv strings |
| 209 | */ |
| 210 | for (i = 0; i < argc; i++) { |
| 211 | if (i == 0 || end_of_area + 1 == argv[i]) |
| 212 | end_of_area = argv[i] + strlen(argv[i]); |
| 213 | } |
| 214 | |
| 215 | /* probably can't happen? */ |
| 216 | if (end_of_area == NULL) { |
| 217 | ps_buffer = NULL; |
| 218 | ps_buffer_size = 0; |
| 219 | return; |
| 220 | } |
| 221 | |
| 222 | /* |
| 223 | * check for contiguous environ strings following argv |
| 224 | */ |
| 225 | for (i = 0; environ[i] != NULL; i++) { |
| 226 | if (end_of_area + 1 == environ[i]) |
| 227 | end_of_area = environ[i] + strlen(environ[i]); |
| 228 | } |
| 229 | |
| 230 | ps_buffer = argv[0]; |
| 231 | ps_buffer_size = end_of_area - argv[0] - 1; |
| 232 | |
| 233 | /* |
| 234 | * Duplicate and move the environment out of the way |
| 235 | */ |
| 236 | new_environ = malloc(sizeof(char *) * (i + 1)); |
| 237 | for (i = 0; environ[i] != NULL; i++) |
| 238 | new_environ[i] = strdup(environ[i]); |
| 239 | new_environ[i] = NULL; |
| 240 | environ = new_environ; |
| 241 | #endif /* PS_USE_CLOBBER_ARGV */ |
| 242 | } |
| 243 | |