setproctitle.cpp

00001 /*
00002  * Copyright (c) 1998 Sendmail, Inc.  All rights reserved.
00003  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
00004  * Copyright (c) 1988, 1993
00005  *  The Regents of the University of California.  All rights reserved.
00006  *
00007  * By using this file, you agree to the terms and conditions set
00008  * forth in the LICENSE file which can be found at the top level of
00009  * the sendmail distribution.
00010  *
00011  * A copy of the above mentioned LICENSE file can be found in
00012  * LICENSE.setproctitle.
00013  *
00014  * Ported for use with KDE by Waldo Bastian <bastian@kde.org>
00015  */
00016 
00017 #include "setproctitle.h"
00018 
00019 #ifdef HAVE_CONFIG_H
00020 #include <config.h>
00021 #endif
00022 
00023 /* _GNU_SOURCE might already be defined in <config.h> */
00024 #ifndef _GNU_SOURCE
00025 #  define _GNU_SOURCE
00026 #endif
00027 #include <stdio.h>
00028 #include <stdarg.h>
00029 #include <sys/ioctl.h>
00030 #include <sys/param.h>
00031 #include <limits.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <unistd.h>
00035 
00036 /* _PATH_KMEM should be defined in <paths.h> */
00037 #ifndef _PATH_KMEM
00038 # define _PATH_KMEM "/dev/kmem"
00039 #endif
00040 
00041 #define SPACELEFT(buf, ptr) (sizeof buf - ((ptr) - buf))
00042 
00043 
00044 /*
00045 **  SETPROCTITLE -- set process title for ps
00046 **
00047 **  Parameters:
00048 **      fmt -- a printf style format string.
00049 **      a, b, c -- possible parameters to fmt.
00050 **
00051 **  Returns:
00052 **      none.
00053 **
00054 **  Side Effects:
00055 **      Clobbers argv of our main procedure so ps(1) will
00056 **      display the title.
00057 */
00058 
00059 #define SPT_NONE    0   /* don't use it at all */
00060 #define SPT_REUSEARGV   1   /* cover argv with title information */
00061 #define SPT_BUILTIN 2   /* use libc builtin */
00062 #define SPT_PSTAT   3   /* use pstat(PSTAT_SETCMD, ...) */
00063 #define SPT_PSSTRINGS   4   /* use PS_STRINGS->... */
00064 #define SPT_SYSMIPS 5   /* use sysmips() supported by NEWS-OS 6 */
00065 #define SPT_SCO     6   /* write kernel u. area */
00066 #define SPT_CHANGEARGV  7   /* write our own strings into argv[] */
00067 
00068 #ifndef SPT_TYPE
00069 # define SPT_TYPE   SPT_REUSEARGV
00070 #endif
00071 
00072 #if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN
00073 
00074 # if SPT_TYPE == SPT_PSTAT
00075 #  include <sys/pstat.h>
00076 # endif
00077 # if SPT_TYPE == SPT_PSSTRINGS
00078 #  include <machine/vmparam.h>
00079 #  ifdef HAVE_SYS_EXEC_H
00080 #    include <sys/exec.h>
00081 #  endif
00082 #  ifndef PS_STRINGS    /* hmmmm....  apparently not available after all */
00083 #   undef SPT_TYPE
00084 #   define SPT_TYPE SPT_REUSEARGV
00085 #  else
00086 #   ifndef NKPDE            /* FreeBSD 2.0 */
00087 #    define NKPDE 63
00088 typedef unsigned int    *pt_entry_t;
00089 #   endif
00090 #  endif
00091 # endif
00092 
00093 # if SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV
00094 #  define SETPROC_STATIC    static
00095 # else
00096 #  define SETPROC_STATIC
00097 # endif
00098 
00099 # if SPT_TYPE == SPT_SYSMIPS
00100 #  include <sys/sysmips.h>
00101 #  include <sys/sysnews.h>
00102 # endif
00103 
00104 # if SPT_TYPE == SPT_SCO
00105 #  include <sys/immu.h>
00106 #  include <sys/dir.h>
00107 #  include <sys/user.h>
00108 #  include <sys/fs/s5param.h>
00109 #  if PSARGSZ > MAXLINE
00110 #   define SPT_BUFSIZE  PSARGSZ
00111 #  endif
00112 # endif
00113 
00114 # ifndef SPT_PADCHAR
00115 #  ifdef _AIX
00116 #   define SPT_PADCHAR  '\0'
00117 #  else
00118 #   define SPT_PADCHAR  ' '
00119 #  endif
00120 # endif
00121 
00122 #endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */
00123 
00124 # ifndef SPT_BUFSIZE
00125 #  define SPT_BUFSIZE   2048
00126 # endif
00127 
00128 /*
00129 **  Pointers for setproctitle.
00130 **  This allows "ps" listings to give more useful information.
00131 */
00132 
00133 char        **Argv = NULL;      /* pointer to argument vector */
00134 char        *LastArgv = NULL;   /* end of argv */
00135 
00136 void
00137 kdeinit_initsetproctitle(int argc, char **argv, char **envp)
00138 {
00139     register int i, envpsize = 0;
00140 #if !defined(HAVE_NSGETENVIRON) || !defined(HAVE_CRT_EXTERNS_H)
00141     extern char **environ;
00142 #endif
00143 
00144     /*
00145     **  Move the environment so setproctitle can use the space at
00146     **  the top of memory.
00147     */
00148 
00149     for (i = 0; envp[i] != NULL; i++)
00150         envpsize += strlen(envp[i]) + 1;
00151     environ = (char **) malloc(sizeof (char *) * (i + 1));
00152     if (environ == NULL)
00153             return;
00154 
00155     for (i = 0; envp[i] != NULL; i++)
00156         environ[i] = strdup(envp[i]);
00157     environ[i] = NULL;
00158 
00159     /*
00160     **  Save start and extent of argv for setproctitle.
00161     */
00162 
00163     Argv = argv;
00164 
00165     /*
00166     **  Determine how much space we can use for setproctitle.
00167     **  Use all contiguous argv and envp pointers starting at argv[0]
00168     */
00169     for (i = 0; i < argc; i++)
00170     {
00171         if (i==0 || LastArgv + 1 == argv[i])
00172             LastArgv = argv[i] + strlen(argv[i]);
00173         else
00174             continue;
00175     }
00176     for (i=0; envp[i] != NULL; i++)
00177     {
00178         if (LastArgv + 1 == envp[i])
00179             LastArgv = envp[i] + strlen(envp[i]);
00180         else
00181             continue;
00182     }
00183 }
00184 
00185 #if SPT_TYPE != SPT_BUILTIN
00186 
00187 /*VARARGS1*/
00188 static void
00189 setproctitle(const char *fmt, ...)
00190 {
00191 # if SPT_TYPE != SPT_NONE
00192     register char *p;
00193     register int i;
00194     SETPROC_STATIC char buf[SPT_BUFSIZE];
00195     va_list ap;
00196 #  if SPT_TYPE == SPT_PSTAT
00197     union pstun pst;
00198 #  endif
00199 #  if SPT_TYPE == SPT_SCO
00200     off_t seek_off;
00201     static int kmem = -1;
00202 #warning (rikkus) kmempid is declared as int, should be long
00203     static int kmempid = -1;
00204     struct user u;
00205 #  endif
00206 
00207     p = buf;
00208 
00209     /* print the argument string */
00210     va_start(ap, fmt);
00211     (void) vsnprintf(p, SPACELEFT(buf, p), fmt, ap);
00212     va_end(ap);
00213 
00214     i = strlen(buf);
00215 
00216 #  if SPT_TYPE == SPT_PSTAT
00217     pst.pst_command = buf;
00218     pstat(PSTAT_SETCMD, pst, i, 0, 0);
00219 #  endif
00220 #  if SPT_TYPE == SPT_PSSTRINGS
00221     PS_STRINGS->ps_nargvstr = 1;
00222     PS_STRINGS->ps_argvstr = buf;
00223 #  endif
00224 #  if SPT_TYPE == SPT_SYSMIPS
00225     sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf);
00226 #  endif
00227 #  if SPT_TYPE == SPT_SCO
00228     if (kmem < 0 || kmempid != getpid())
00229     {
00230         if (kmem >= 0)
00231             close(kmem);
00232         kmem = open(_PATH_KMEM, O_RDWR, 0);
00233         if (kmem < 0)
00234             return;
00235         (void) fcntl(kmem, F_SETFD, 1);
00236         kmempid = getpid();
00237     }
00238     buf[PSARGSZ - 1] = '\0';
00239     seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u;
00240     if (lseek(kmem, (off_t) seek_off, SEEK_SET) == seek_off)
00241         (void) write(kmem, buf, PSARGSZ);
00242 #  endif
00243 #  if SPT_TYPE == SPT_REUSEARGV
00244     if (i > LastArgv - Argv[0] - 2)
00245     {
00246         i = LastArgv - Argv[0] - 2;
00247         buf[i] = '\0';
00248     }
00249     (void) strcpy(Argv[0], buf);
00250     p = &Argv[0][i];
00251     while (p < LastArgv)
00252         *p++ = SPT_PADCHAR;
00253     Argv[1] = NULL;
00254 #  endif
00255 #  if SPT_TYPE == SPT_CHANGEARGV
00256     Argv[0] = buf;
00257     Argv[1] = 0;
00258 #  endif
00259 # endif /* SPT_TYPE != SPT_NONE */
00260 }
00261 
00262 #endif /* SPT_TYPE != SPT_BUILTIN */
00263 /*
00264 **  SM_SETPROCTITLE -- set process task and set process title for ps
00265 **
00266 **  Possibly set process status and call setproctitle() to
00267 **  change the ps display.
00268 **
00269 **  Parameters:
00270 **      status -- whether or not to store as process status
00271 **      fmt -- a printf style format string.
00272 **      a, b, c -- possible parameters to fmt.
00273 **
00274 **  Returns:
00275 **      none.
00276 */
00277 
00278 /*VARARGS2*/
00279 void
00280 kdeinit_setproctitle(const char *fmt, ...)
00281 {
00282     char buf[SPT_BUFSIZE];
00283 
00284     va_list ap;
00285     /* print the argument string */
00286     va_start(ap, fmt);
00287     (void) vsnprintf(buf, SPT_BUFSIZE, fmt, ap);
00288     va_end(ap);
00289 
00290     setproctitle("%s", buf);
00291 }
00292 
KDE Home | KDE Accessibility Home | Description of Access Keys