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>