• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KInit

proctitle.cpp

Go to the documentation of this file.
00001 /*
00002  * ProFTPD - FTP server daemon
00003  * Copyright (c) 2007 The ProFTPD Project team           //krazy:exclude=copyright
00004  * Copyright (c) 2007 Alex Merry <alex.merry@kdemail.net>
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the
00018  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA  02110-1301  USA
00020  */
00021 
00022 #include "proctitle.h"
00023 #include <config.h>
00024 #include <config-kdeinit.h>
00025 
00026 #include <string.h>
00027 #include <stdio.h>
00028 #include <stdarg.h>
00029 #include <stdlib.h>
00030 
00031 #define PF_ARGV_NONE      0
00032 #define PF_ARGV_NEW       1
00033 #define PF_ARGV_WRITEABLE 2
00034 #define PF_ARGV_PSTAT     3
00035 #define PF_ARGV_PSSTRINGS 4
00036 
00037 #ifdef HAVE_SETPROCTITLE
00038 #  define PF_ARGV_TYPE PF_ARGV_NONE
00039 #  ifdef HAVE_SYS_TYPES_H
00040 #    include <sys/types.h>
00041 #  endif /* HAVE_SYS_TYPES_H */
00042 #  ifdef HAVE_UNISTD_H
00043 #    include <unistd.h>
00044 #  endif /* HAVE_UNISTD_H */
00045 
00046 #else /* HAVE_SETPROCTITLE */
00047 #  ifdef __GNU_HURD__
00048 #    define PF_ARGV_TYPE PF_ARGV_NEW
00049 #  else /* __GNU_HURD__ */
00050 #    define PF_ARGV_TYPE PF_ARGV_WRITEABLE
00051 
00052 #    if defined(HAVE_SYS_PSTAT_H) && defined(HAVE_PSTAT)
00053 #      include <sys/pstat.h>
00054 #      undef PF_ARGV_TYPE
00055 #      define PF_ARGV_TYPE PF_ARGV_PSTAT
00056 #    endif /* HAVE_SYS_PSTAT_H && HAVE_PSTAT */
00057 
00058 #    ifdef HAVE_SYS_EXEC_H
00059 #      include <sys/exec.h>
00060 #      ifdef PS_STRINGS
00061 #        include <machine/vmparam.h>
00062 #        undef PF_ARGV_TYPE
00063 #        define PF_ARGV_TYPE PF_ARGV_PSSTRINGS
00064 #      endif /* PS_STRINGS */
00065 #    endif /* HAVE_SYS_EXEC_H */
00066 
00067 #  endif /* !__GNU_HURD__ */
00068 
00069 #endif /* !HAVE_SETPROCTITLE */
00070 
00071 #ifdef HAVE___PROGNAME
00072 extern char *__progname;
00073 #endif /* HAVE___PROGNAME */
00074 #ifdef HAVE___PROGNAME_FULL
00075 extern char *__progname_full;
00076 #endif /* HAVE___PROGNAME_FULL */
00077 extern char **environ;
00078 
00079 static char **Argv = NULL;
00080 
00081 #if PF_ARGV_TYPE == PF_ARGV_WRITEABLE   /* Only this mode uses LastArgv */
00082 static char *LastArgv = NULL;
00083 #endif
00084 
00088 void proctitle_init(int argc, char *argv[], char *envp[]) {
00089     register int i, envpsize;
00090     char **p;
00091 
00092     /* Move the environment so proctitle_set can use the space. */
00093     for ( i = envpsize = 0; envp[i] != NULL; i++ ) {
00094         envpsize += strlen(envp[i]) + 1;
00095     }
00096 
00097     if ((p = (char **) malloc((i + 1) * sizeof(char *))) != NULL) {
00098         environ = p;
00099 
00100         for (i = 0; envp[i] != NULL; i++) {
00101             if ((environ[i] = static_cast<char *>(malloc(strlen(envp[i]) + 1))) != NULL) {
00102                 strcpy(environ[i], envp[i]);
00103             }
00104         }
00105 
00106         environ[i] = NULL;
00107     }
00108 
00109     Argv = argv;
00110 
00111 # if PF_ARGV_TYPE == PF_ARGV_WRITEABLE   /* Only this mode uses LastArgv */
00112     for (i = 0; i < argc; i++) {
00113         if (!i || (LastArgv + 1 == argv[i])) {
00114             LastArgv = argv[i] + strlen(argv[i]);
00115         }
00116     }
00117 
00118     for (i = 0; envp[i] != NULL; i++) {
00119         /* must not overwrite XDG_SESSION_COOKIE */
00120         if (!strncmp(envp[i], "XDG_", 4))
00121             break;
00122         if ((LastArgv + 1) == envp[i]) {
00123             LastArgv = envp[i] + strlen(envp[i]);
00124         }
00125     }
00126 #endif
00127 
00128 # ifdef HAVE___PROGNAME
00129     /* Set the __progname variable so glibc and company
00130      * don't go nuts.
00131      */
00132     __progname = strdup("kdeinit4");
00133 # endif /* HAVE___PROGNAME */
00134 # ifdef HAVE___PROGNAME_FULL
00135     /* __progname_full too */
00136     __progname_full = strdup(argv[0]);
00137 # endif /* HAVE___PROGNAME_FULL */
00138 }
00139 
00140 void proctitle_set(const char *fmt, ...) {
00141     va_list msg;
00142     static char statbuf[BUFSIZ];
00143 
00144 #ifndef HAVE_SETPROCTITLE
00145 # if PF_ARGV_TYPE == PF_ARGV_PSTAT
00146     union pstun pst;
00147 # endif /* PF_ARGV_PSTAT */
00148     char *p;
00149     int i;
00150 #endif /* HAVE_SETPROCTITLE */
00151 
00152     if ( !fmt ) {
00153         return;
00154     }
00155 
00156     va_start(msg, fmt);
00157 
00158     memset(statbuf, 0, sizeof(statbuf));
00159 
00160 #ifdef HAVE_SETPROCTITLE
00161 # if __FreeBSD__ >= 4 && !defined(FREEBSD4_0) && !defined(FREEBSD4_1)
00162     /* FreeBSD's setproctitle() automatically prepends the process name. */
00163     vsnprintf(statbuf, sizeof(statbuf), fmt, msg);
00164 
00165 # else /* FREEBSD4 */
00166     /* Manually append the process name for non-FreeBSD platforms. */
00167     snprintf(statbuf, sizeof(statbuf), "%s", "kdeinit4: ");
00168     vsnprintf(statbuf + strlen(statbuf),
00169               sizeof(statbuf) - strlen(statbuf),
00170               fmt,
00171               msg);
00172 
00173 # endif /* FREEBSD4 */
00174     setproctitle("%s", statbuf);
00175 
00176 #else /* HAVE_SETPROCTITLE */
00177     /* Manually append the process name for non-setproctitle() platforms. */
00178     snprintf(statbuf, sizeof(statbuf), "%s", "kdeinit4: ");
00179     vsnprintf(statbuf + strlen(statbuf),
00180               sizeof(statbuf) - strlen(statbuf),
00181               fmt,
00182               msg);
00183 
00184 #endif /* HAVE_SETPROCTITLE */
00185 
00186     va_end(msg);
00187 
00188 #ifdef HAVE_SETPROCTITLE
00189     return;
00190 #else
00191     i = strlen(statbuf);
00192 
00193 # if PF_ARGV_TYPE == PF_ARGV_NEW
00194     /* We can just replace argv[] arguments.  Nice and easy. */
00195     Argv[0] = statbuf;
00196     Argv[1] = NULL;
00197 # endif /* PF_ARGV_NEW */
00198 
00199 # if PF_ARGV_TYPE == PF_ARGV_WRITEABLE
00200     const int maxlen = (LastArgv - Argv[0]) - 1;
00201     /* We can overwrite individual argv[] arguments.  Semi-nice. */
00202     snprintf(Argv[0], maxlen, "%s", statbuf);
00203     p = &Argv[0][i];
00204 
00205     /* null terminate it, but don't clear the rest of the
00206        memory that is usually used for environment variables. Some
00207        tools, like ConsoleKit must have access to the process'es initial
00208        environment (more exact, the XDG_SESSION_COOKIE variable stored there).
00209        If this code causes another side effect, we have to specifically
00210        always append those variables to our environment. */
00211 
00212     if (p < LastArgv)
00213         *p = '\0';
00214 
00215     Argv[1] = NULL;
00216 # endif /* PF_ARGV_WRITEABLE */
00217 
00218 # if PF_ARGV_TYPE == PF_ARGV_PSTAT
00219     pst.pst_command = statbuf;
00220     pstat(PSTAT_SETCMD, pst, i, 0, 0);
00221 # endif /* PF_ARGV_PSTAT */
00222 
00223 # if PF_ARGV_TYPE == PF_ARGV_PSSTRINGS
00224     PS_STRINGS->ps_nargvstr = 1;
00225     PS_STRINGS->ps_argvstr = statbuf;
00226 # endif /* PF_ARGV_PSSTRINGS */
00227 
00228 #endif /* HAVE_SETPROCTITLE */
00229 }

KInit

Skip menu "KInit"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal