gsasl  1.10.0
About: GNU SASL is an implementation of the Simple Authentication and Security Layer (SASL). Development version.
  Fossies Dox: gsasl-1.10.0.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

getprogname.c
Go to the documentation of this file.
1 /* Program name management.
2  Copyright (C) 2016-2021 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 #if defined __SCO_VERSION__ || defined __sysv5__
55 # include <fcntl.h>
56 # include <stdlib.h>
57 # include <string.h>
58 #endif
59 
60 #include "basename-lgpl.h"
61 
62 #ifndef HAVE_GETPROGNAME /* not Mac OS X, FreeBSD, NetBSD, OpenBSD >= 5.4, Cygwin */
63 char const *
65 {
66 # if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME /* glibc, BeOS */
67  /* https://www.gnu.org/software/libc/manual/html_node/Error-Messages.html */
68  return program_invocation_short_name;
69 # elif HAVE_DECL_PROGRAM_INVOCATION_NAME /* glibc, BeOS */
70  /* https://www.gnu.org/software/libc/manual/html_node/Error-Messages.html */
71  return last_component (program_invocation_name);
72 # elif HAVE_GETEXECNAME /* Solaris */
73  /* https://docs.oracle.com/cd/E19253-01/816-5168/6mbb3hrb1/index.html */
74  const char *p = getexecname ();
75  if (!p)
76  p = "?";
77  return last_component (p);
78 # elif HAVE_DECL___ARGV /* mingw, MSVC */
79  /* https://docs.microsoft.com/en-us/cpp/c-runtime-library/argc-argv-wargv */
80  const char *p = __argv && __argv[0] ? __argv[0] : "?";
81  return last_component (p);
82 # elif HAVE_VAR___PROGNAME /* OpenBSD, Android, QNX */
83  /* https://man.openbsd.org/style.9 */
84  /* http://www.qnx.de/developers/docs/6.5.0/index.jsp?topic=%2Fcom.qnx.doc.neutrino_lib_ref%2Fp%2F__progname.html */
85  /* Be careful to declare this only when we absolutely need it
86  (OpenBSD 5.1), rather than when it's available. Otherwise,
87  its mere declaration makes program_invocation_short_name
88  malfunction (have zero length) with Fedora 25's glibc. */
89  extern char *__progname;
90  const char *p = __progname;
91 # if defined __ANDROID__
92  return last_component (p);
93 # else
94  return p && p[0] ? p : "?";
95 # endif
96 # elif _AIX /* AIX */
97  /* Idea by Bastien ROUCARIÈS,
98  https://lists.gnu.org/r/bug-gnulib/2010-12/msg00095.html
99  Reference: https://www.ibm.com/support/knowledgecenter/en/ssw_aix_61/com.ibm.aix.basetrf1/getprocs.htm
100  */
101  static char *p;
102  static int first = 1;
103  if (first)
104  {
105  first = 0;
106  pid_t pid = getpid ();
107  struct procentry64 procs;
108  p = (0 < getprocs64 (&procs, sizeof procs, NULL, 0, &pid, 1)
109  ? strdup (procs.pi_comm)
110  : NULL);
111  if (!p)
112  p = "?";
113  }
114  return p;
115 # elif defined __hpux
116  static char *p;
117  static int first = 1;
118  if (first)
119  {
120  first = 0;
121  pid_t pid = getpid ();
122  struct pst_status status;
123  if (pstat_getproc (&status, sizeof status, 0, pid) > 0)
124  {
125  char *ucomm = status.pst_ucomm;
126  char *cmd = status.pst_cmd;
127  if (strlen (ucomm) < PST_UCOMMLEN - 1)
128  p = ucomm;
129  else
130  {
131  /* ucomm is truncated to length PST_UCOMMLEN - 1.
132  Look at cmd instead. */
133  char *space = strchr (cmd, ' ');
134  if (space != NULL)
135  *space = '\0';
136  p = strrchr (cmd, '/');
137  if (p != NULL)
138  p++;
139  else
140  p = cmd;
141  if (strlen (p) > PST_UCOMMLEN - 1
142  && memcmp (p, ucomm, PST_UCOMMLEN - 1) == 0)
143  /* p is less truncated than ucomm. */
144  ;
145  else
146  p = ucomm;
147  }
148  p = strdup (p);
149  }
150  else
151  {
152 # if !defined __LP64__
153  /* Support for 32-bit programs running in 64-bit HP-UX.
154  The documented way to do this is to use the same source code
155  as above, but in a compilation unit where '#define _PSTAT64 1'
156  is in effect. I prefer a single compilation unit; the struct
157  size and the offsets are not going to change. */
158  char status64[1216];
159  if (__pstat_getproc64 (status64, sizeof status64, 0, pid) > 0)
160  {
161  char *ucomm = status64 + 288;
162  char *cmd = status64 + 168;
163  if (strlen (ucomm) < PST_UCOMMLEN - 1)
164  p = ucomm;
165  else
166  {
167  /* ucomm is truncated to length PST_UCOMMLEN - 1.
168  Look at cmd instead. */
169  char *space = strchr (cmd, ' ');
170  if (space != NULL)
171  *space = '\0';
172  p = strrchr (cmd, '/');
173  if (p != NULL)
174  p++;
175  else
176  p = cmd;
177  if (strlen (p) > PST_UCOMMLEN - 1
178  && memcmp (p, ucomm, PST_UCOMMLEN - 1) == 0)
179  /* p is less truncated than ucomm. */
180  ;
181  else
182  p = ucomm;
183  }
184  p = strdup (p);
185  }
186  else
187 # endif
188  p = NULL;
189  }
190  if (!p)
191  p = "?";
192  }
193  return p;
194 # elif __MVS__ /* z/OS */
195  /* https://www.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.bpxbd00/rtwgetp.htm */
196  static char *p = "?";
197  static int first = 1;
198  if (first)
199  {
200  pid_t pid = getpid ();
201  int token;
202  W_PSPROC buf;
203  first = 0;
204  memset (&buf, 0, sizeof(buf));
205  buf.ps_cmdptr = (char *) malloc (buf.ps_cmdlen = PS_CMDBLEN_LONG);
206  buf.ps_conttyptr = (char *) malloc (buf.ps_conttylen = PS_CONTTYBLEN);
207  buf.ps_pathptr = (char *) malloc (buf.ps_pathlen = PS_PATHBLEN);
208  if (buf.ps_cmdptr && buf.ps_conttyptr && buf.ps_pathptr)
209  {
210  for (token = 0; token >= 0;
211  token = w_getpsent (token, &buf, sizeof(buf)))
212  {
213  if (token > 0 && buf.ps_pid == pid)
214  {
215  char *s = strdup (last_component (buf.ps_pathptr));
216  if (s)
217  p = s;
218  break;
219  }
220  }
221  }
222  free (buf.ps_cmdptr);
223  free (buf.ps_conttyptr);
224  free (buf.ps_pathptr);
225  }
226  return p;
227 # elif defined __sgi /* IRIX */
228  char filename[50];
229  int fd;
230 
231  sprintf (filename, "/proc/pinfo/%d", (int) getpid ());
232  fd = open (filename, O_RDONLY | O_CLOEXEC);
233  if (0 <= fd)
234  {
235  prpsinfo_t buf;
236  int ioctl_ok = 0 <= ioctl (fd, PIOCPSINFO, &buf);
237  close (fd);
238  if (ioctl_ok)
239  {
240  char *name = buf.pr_fname;
241  size_t namesize = sizeof buf.pr_fname;
242  /* It may not be NUL-terminated. */
243  char *namenul = memchr (name, '\0', namesize);
244  size_t namelen = namenul ? namenul - name : namesize;
245  char *namecopy = malloc (namelen + 1);
246  if (namecopy)
247  {
248  namecopy[namelen] = '\0';
249  return memcpy (namecopy, name, namelen);
250  }
251  }
252  }
253  return NULL;
254 # elif defined __SCO_VERSION__ || defined __sysv5__ /* SCO OpenServer6/UnixWare */
255  char buf[80];
256  int fd;
257  sprintf (buf, "/proc/%d/cmdline", getpid());
258  fd = open (buf, O_RDONLY);
259  if (0 <= fd)
260  {
261  size_t n = read (fd, buf, 79);
262  if (n > 0)
263  {
264  buf[n] = '\0'; /* Guarantee null-termination */
265  char *progname;
266  progname = strrchr (buf, '/');
267  if (progname)
268  {
269  progname = progname + 1; /* Skip the '/' */
270  }
271  else
272  {
273  progname = buf;
274  }
275  char *ret;
276  ret = malloc (strlen (progname) + 1);
277  if (ret)
278  {
279  strcpy (ret, progname);
280  return ret;
281  }
282  }
283  close (fd);
284  }
285  return "?";
286 # else
287 # error "getprogname module not ported to this OS"
288 # endif
289 }
290 
291 #endif
292 
293 /*
294  * Hey Emacs!
295  * Local Variables:
296  * coding: utf-8
297  * End:
298  */
char * last_component(char const *name)
Definition: basename-lgpl.c:30
char const * getprogname(void)
Definition: getprogname.c:64
#define O_CLOEXEC
Definition: fcntl.in.h:291
void * memchr(void const *s, int c_in, size_t n)
Definition: memchr.c:59
int open(const char *filename, int flags,...)
Definition: open.c:59
#define NULL
Definition: stddef.in.h:72
int ioctl(int fd, int request,...)
Definition: ioctl.c:76
const char * name
Definition: error.c:43
const char * p
Definition: mbrtowc-impl.h:42
char buf[4]
Definition: mbrtowc-impl.h:39
char * strdup(const char *s)
Definition: strdup.c:39