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