File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libiconv / srclib / getprogname.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 13:38:46 2021 UTC (3 years, 3 months ago) by misho
Branches: libiconv, MAIN
CVS tags: v1_16p0, HEAD
libiconv 1.16

    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>