1 /* -*- buffer-read-only: t -*- vi: set ro: */
2 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3 /* Program name management.
4 Copyright (C) 2016-2019 Free Software Foundation, Inc.
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <https://www.gnu.org/licenses/>. */
18
19 #include <config.h>
20
21 /* Specification. */
22 #include "getprogname.h"
23
24 #include <errno.h> /* get program_invocation_name declaration */
25 #include <stdlib.h> /* get __argv declaration */
26
27 #ifdef _AIX
28 # include <unistd.h>
29 # include <procinfo.h>
30 # include <string.h>
31 #endif
32
33 #ifdef __MVS__
34 # ifndef _OPEN_SYS
35 # define _OPEN_SYS
36 # endif
37 # include <string.h>
38 # include <sys/ps.h>
39 #endif
40
41 #ifdef __hpux
42 # include <unistd.h>
43 # include <sys/param.h>
44 # include <sys/pstat.h>
45 # include <string.h>
46 #endif
47
48 #ifdef __sgi
49 # include <string.h>
50 # include <unistd.h>
51 # include <stdio.h>
52 # include <fcntl.h>
53 # include <sys/procfs.h>
54 #endif
55
56 #include "dirname.h"
57
58 #ifndef HAVE_GETPROGNAME /* not Mac OS X, FreeBSD, NetBSD, OpenBSD >= 5.4, Cygwin */
59 char const *
getprogname(void)60 getprogname (void)
61 {
62 # if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME /* glibc, BeOS */
63 /* https://www.gnu.org/software/libc/manual/html_node/Error-Messages.html */
64 return program_invocation_short_name;
65 # elif HAVE_DECL_PROGRAM_INVOCATION_NAME /* glibc, BeOS */
66 /* https://www.gnu.org/software/libc/manual/html_node/Error-Messages.html */
67 return last_component (program_invocation_name);
68 # elif HAVE_GETEXECNAME /* Solaris */
69 /* https://docs.oracle.com/cd/E19253-01/816-5168/6mbb3hrb1/index.html */
70 const char *p = getexecname ();
71 if (!p)
72 p = "?";
73 return last_component (p);
74 # elif HAVE_DECL___ARGV /* mingw, MSVC */
75 /* https://docs.microsoft.com/en-us/cpp/c-runtime-library/argc-argv-wargv */
76 const char *p = __argv && __argv[0] ? __argv[0] : "?";
77 return last_component (p);
78 # elif HAVE_VAR___PROGNAME /* OpenBSD, Android, QNX */
79 /* https://man.openbsd.org/style.9 */
80 /* http://www.qnx.de/developers/docs/6.5.0/index.jsp?topic=%2Fcom.qnx.doc.neutrino_lib_ref%2Fp%2F__progname.html */
81 /* Be careful to declare this only when we absolutely need it
82 (OpenBSD 5.1), rather than when it's available. Otherwise,
83 its mere declaration makes program_invocation_short_name
84 malfunction (have zero length) with Fedora 25's glibc. */
85 extern char *__progname;
86 const char *p = __progname;
87 # if defined __ANDROID__
88 return last_component (p);
89 # else
90 return p && p[0] ? p : "?";
91 # endif
92 # elif _AIX /* AIX */
93 /* Idea by Bastien ROUCARIÈS,
94 https://lists.gnu.org/r/bug-gnulib/2010-12/msg00095.html
95 Reference: https://www.ibm.com/support/knowledgecenter/en/ssw_aix_61/com.ibm.aix.basetrf1/getprocs.htm
96 */
97 static char *p;
98 static int first = 1;
99 if (first)
100 {
101 first = 0;
102 pid_t pid = getpid ();
103 struct procentry64 procs;
104 p = (0 < getprocs64 (&procs, sizeof procs, NULL, 0, &pid, 1)
105 ? strdup (procs.pi_comm)
106 : NULL);
107 if (!p)
108 p = "?";
109 }
110 return p;
111 # elif defined __hpux
112 static char *p;
113 static int first = 1;
114 if (first)
115 {
116 first = 0;
117 pid_t pid = getpid ();
118 struct pst_status status;
119 if (pstat_getproc (&status, sizeof status, 0, pid) > 0)
120 {
121 char *ucomm = status.pst_ucomm;
122 char *cmd = status.pst_cmd;
123 if (strlen (ucomm) < PST_UCOMMLEN - 1)
124 p = ucomm;
125 else
126 {
127 /* ucomm is truncated to length PST_UCOMMLEN - 1.
128 Look at cmd instead. */
129 char *space = strchr (cmd, ' ');
130 if (space != NULL)
131 *space = '\0';
132 p = strrchr (cmd, '/');
133 if (p != NULL)
134 p++;
135 else
136 p = cmd;
137 if (strlen (p) > PST_UCOMMLEN - 1
138 && memcmp (p, ucomm, PST_UCOMMLEN - 1) == 0)
139 /* p is less truncated than ucomm. */
140 ;
141 else
142 p = ucomm;
143 }
144 p = strdup (p);
145 }
146 else
147 {
148 # if !defined __LP64__
149 /* Support for 32-bit programs running in 64-bit HP-UX.
150 The documented way to do this is to use the same source code
151 as above, but in a compilation unit where '#define _PSTAT64 1'
152 is in effect. I prefer a single compilation unit; the struct
153 size and the offsets are not going to change. */
154 char status64[1216];
155 if (__pstat_getproc64 (status64, sizeof status64, 0, pid) > 0)
156 {
157 char *ucomm = status64 + 288;
158 char *cmd = status64 + 168;
159 if (strlen (ucomm) < PST_UCOMMLEN - 1)
160 p = ucomm;
161 else
162 {
163 /* ucomm is truncated to length PST_UCOMMLEN - 1.
164 Look at cmd instead. */
165 char *space = strchr (cmd, ' ');
166 if (space != NULL)
167 *space = '\0';
168 p = strrchr (cmd, '/');
169 if (p != NULL)
170 p++;
171 else
172 p = cmd;
173 if (strlen (p) > PST_UCOMMLEN - 1
174 && memcmp (p, ucomm, PST_UCOMMLEN - 1) == 0)
175 /* p is less truncated than ucomm. */
176 ;
177 else
178 p = ucomm;
179 }
180 p = strdup (p);
181 }
182 else
183 # endif
184 p = NULL;
185 }
186 if (!p)
187 p = "?";
188 }
189 return p;
190 # elif __MVS__ /* z/OS */
191 /* https://www.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.bpxbd00/rtwgetp.htm */
192 static char *p = "?";
193 static int first = 1;
194 if (first)
195 {
196 pid_t pid = getpid ();
197 int token;
198 W_PSPROC buf;
199 first = 0;
200 memset (&buf, 0, sizeof(buf));
201 buf.ps_cmdptr = (char *) malloc (buf.ps_cmdlen = PS_CMDBLEN_LONG);
202 buf.ps_conttyptr = (char *) malloc (buf.ps_conttylen = PS_CONTTYBLEN);
203 buf.ps_pathptr = (char *) malloc (buf.ps_pathlen = PS_PATHBLEN);
204 if (buf.ps_cmdptr && buf.ps_conttyptr && buf.ps_pathptr)
205 {
206 for (token = 0; token >= 0;
207 token = w_getpsent (token, &buf, sizeof(buf)))
208 {
209 if (token > 0 && buf.ps_pid == pid)
210 {
211 char *s = strdup (last_component (buf.ps_pathptr));
212 if (s)
213 p = s;
214 break;
215 }
216 }
217 }
218 free (buf.ps_cmdptr);
219 free (buf.ps_conttyptr);
220 free (buf.ps_pathptr);
221 }
222 return p;
223 # elif defined __sgi /* IRIX */
224 char filename[50];
225 int fd;
226
227 sprintf (filename, "/proc/pinfo/%d", (int) getpid ());
228 fd = open (filename, O_RDONLY);
229 if (0 <= fd)
230 {
231 prpsinfo_t buf;
232 int ioctl_ok = 0 <= ioctl (fd, PIOCPSINFO, &buf);
233 close (fd);
234 if (ioctl_ok)
235 {
236 char *name = buf.pr_fname;
237 size_t namesize = sizeof buf.pr_fname;
238 char *namenul = memchr (name, '\0', namesize);
239 size_t namelen = namenul ? namenul - name : namesize;
240 char *namecopy = malloc (namelen + 1);
241 if (namecopy)
242 {
243 namecopy[namelen] = 0;
244 return memcpy (namecopy, name, namelen);
245 }
246 }
247 }
248 return NULL;
249 # else
250 # error "getprogname module not ported to this OS"
251 # endif
252 }
253
254 #endif
255
256 /*
257 * Hey Emacs!
258 * Local Variables:
259 * coding: utf-8
260 * End:
261 */
262