Warning, file /frameworks/kinit/src/kdeinit/proctitle.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* Based on setproctitle.c from OpenSSH 6.6p1 */ 0002 /* 0003 SPDX-FileCopyrightText: 2014 Alex Merry <alex.merry@kde.org> 0004 SPDX-FileCopyrightText: 2003 Damien Miller 0005 SPDX-FileCopyrightText: 1983, 1995-1997 Eric P. Allman 0006 SPDX-FileCopyrightText: 1988, 1993 The Regents of the University of California. All rights reserved. 0007 0008 SPDX-License-Identifier: BSD-3-Clause 0009 */ 0010 0011 #include "proctitle.h" 0012 #include <config-kdeinit.h> 0013 0014 #define PT_NONE 0 /* don't use it at all */ 0015 #define PT_PSTAT 1 /* use pstat(PSTAT_SETCMD, ...) */ 0016 #define PT_REUSEARGV 2 /* cover argv with title information */ 0017 #define PT_SETPROCTITLE 3 /* forward onto the native setproctitle */ 0018 0019 #include <stdarg.h> 0020 #include <stdio.h> 0021 #include <stdlib.h> 0022 #include <sys/types.h> 0023 #include <unistd.h> 0024 #include <string.h> 0025 0026 #if HAVE_SETPROCTITLE 0027 # define PT_TYPE PT_SETPROCTITLE 0028 // process title should get prepended automagically 0029 # define ADD_PROCTITLE 0 0030 #elif HAVE_SYS_PSTAT_H && HAVE_PSTAT 0031 # include <sys/pstat.h> 0032 # define PT_TYPE PT_PSTAT 0033 #elif CAN_CLOBBER_ARGV 0034 # define PT_TYPE PT_REUSEARGV 0035 #endif 0036 0037 #ifndef PT_TYPE 0038 # define PT_TYPE PT_NONE 0039 #endif 0040 #ifndef ADD_PROCTITLE 0041 # define ADD_PROCTITLE 1 0042 #endif 0043 0044 #if PT_TYPE == PT_REUSEARGV 0045 static char *argv_start = nullptr; 0046 static size_t argv_env_len = 0; 0047 #endif 0048 0049 #if HAVE___PROGNAME 0050 extern char *__progname; 0051 #else 0052 char *__progname; 0053 #endif 0054 0055 void 0056 proctitle_init(int argc, char *argv[]) 0057 { 0058 #if HAVE___PROGNAME 0059 // progname may be a reference to argv[0] 0060 __progname = strdup(__progname); 0061 #else 0062 if (argc == 0 || argv[0] == NULL) { 0063 __progname = "unknown"; /* XXX */ 0064 } else { 0065 char *p = strrchr(argv[0], '/'); 0066 if (p == NULL) 0067 p = argv[0]; 0068 else 0069 p++; 0070 0071 __progname = strdup(p); 0072 } 0073 #endif 0074 0075 #if PT_TYPE == PT_REUSEARGV 0076 if (argc == 0 || argv[0] == nullptr) 0077 return; 0078 0079 extern char **environ; 0080 char *lastargv = nullptr; 0081 char **envp = environ; 0082 int i; 0083 0084 /* 0085 * NB: This assumes that argv has already been copied out of the 0086 * way. This is true for kdeinit, but may not be true for other 0087 * programs. Beware. 0088 */ 0089 0090 /* Fail if we can't allocate room for the new environment */ 0091 for (i = 0; envp[i] != nullptr; i++) 0092 ; 0093 if ((environ = (char**)calloc(i + 1, sizeof(*environ))) == nullptr) { 0094 environ = envp; /* put it back */ 0095 return; 0096 } 0097 0098 /* 0099 * Find the last argv string or environment variable within 0100 * our process memory area. 0101 */ 0102 for (i = 0; i < argc; i++) { 0103 if (lastargv == nullptr || lastargv + 1 == argv[i]) 0104 lastargv = argv[i] + strlen(argv[i]); 0105 } 0106 for (i = 0; envp[i] != nullptr; i++) { 0107 if (lastargv + 1 == envp[i]) 0108 lastargv = envp[i] + strlen(envp[i]); 0109 } 0110 0111 argv[1] = nullptr; 0112 argv_start = argv[0]; 0113 argv_env_len = lastargv - argv[0] - 1; 0114 0115 /* 0116 * Copy environment 0117 * XXX - will truncate env on strdup fail 0118 */ 0119 for (i = 0; envp[i] != nullptr; i++) 0120 environ[i] = strdup(envp[i]); 0121 environ[i] = nullptr; 0122 #endif /* PT_REUSEARGV */ 0123 } 0124 0125 void 0126 proctitle_set(const char *fmt, ...) 0127 { 0128 #if PT_TYPE != PT_NONE 0129 #if PT_TYPE == PT_REUSEARGV 0130 if (argv_env_len <= 0) 0131 return; 0132 #endif 0133 0134 bool skip_proctitle = false; 0135 if (fmt != nullptr && fmt[0] == '-') { 0136 skip_proctitle = true; 0137 ++fmt; 0138 } 0139 char ptitle[1024]; 0140 memset(ptitle, '\0', sizeof(ptitle)); 0141 size_t len = 0; 0142 0143 #if ADD_PROCTITLE 0144 if (!skip_proctitle) { 0145 strncpy(ptitle, __progname, sizeof(ptitle)-1); 0146 len = strlen(ptitle); 0147 if (fmt != nullptr && sizeof(ptitle) - len > 2) { 0148 strcpy(ptitle + len, ": "); 0149 len += 2; 0150 } 0151 } 0152 #endif 0153 0154 if (fmt != nullptr) { 0155 int r = -1; 0156 if (len < sizeof(ptitle) - 1) { 0157 va_list ap; 0158 va_start(ap, fmt); 0159 r = vsnprintf(ptitle + len, sizeof(ptitle) - len , fmt, ap); 0160 va_end(ap); 0161 } 0162 if (r == -1 || (size_t)r >= sizeof(ptitle) - len) 0163 return; 0164 } 0165 0166 #if PT_TYPE == PT_PSTAT 0167 union pstun pst; 0168 pst.pst_command = ptitle; 0169 pstat(PSTAT_SETCMD, pst, strlen(ptitle), 0, 0); 0170 #elif PT_TYPE == PT_REUSEARGV 0171 strncpy(argv_start, ptitle, argv_env_len); 0172 argv_start[argv_env_len-1] = '\0'; 0173 #elif PT_TYPE == PT_SETPROCTITLE 0174 if (fmt == NULL) { 0175 setproctitle(NULL); 0176 #if defined(__FreeBSD__) 0177 } else if (skip_proctitle) { 0178 // setproctitle on FreeBSD allows skipping the process title 0179 setproctitle("-%s", ptitle); 0180 #endif 0181 } else { 0182 setproctitle("%s", ptitle); 0183 } 0184 #endif 0185 0186 #endif /* !PT_NONE */ 0187 }