Annotation of embedaddon/libiconv/srclib/getprogname.c, revision 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>