Blame lib/getprogname.c

Packit 33f14e
/* Program name management.
Packit 33f14e
   Copyright (C) 2016-2017 Free Software Foundation, Inc.
Packit 33f14e
Packit 33f14e
   This program is free software: you can redistribute it and/or modify
Packit 33f14e
   it under the terms of the GNU General Public License as published by
Packit 33f14e
   the Free Software Foundation; either version 3 of the License, or
Packit 33f14e
   (at your option) any later version.
Packit 33f14e
Packit 33f14e
   This program is distributed in the hope that it will be useful,
Packit 33f14e
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 33f14e
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 33f14e
   GNU General Public License for more details.
Packit 33f14e
Packit 33f14e
   You should have received a copy of the GNU General Public License
Packit 33f14e
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit 33f14e
Packit 33f14e
#include <config.h>
Packit 33f14e
Packit 33f14e
/* Specification.  */
Packit 33f14e
#include "getprogname.h"
Packit 33f14e
Packit 33f14e
#include <errno.h> /* get program_invocation_name declaration */
Packit 33f14e
#include <stdlib.h> /* get __argv declaration */
Packit 33f14e
Packit 33f14e
#ifdef _AIX
Packit 33f14e
# include <unistd.h>
Packit 33f14e
# include <procinfo.h>
Packit 33f14e
# include <string.h>
Packit 33f14e
#endif
Packit 33f14e
Packit 33f14e
#ifdef __MVS__
Packit 33f14e
# ifndef _OPEN_SYS
Packit 33f14e
#  define _OPEN_SYS
Packit 33f14e
# endif
Packit 33f14e
# include <string.h>
Packit 33f14e
# include <sys/ps.h>
Packit 33f14e
#endif
Packit 33f14e
Packit 33f14e
#ifdef __hpux
Packit 33f14e
# include <unistd.h>
Packit 33f14e
# include <sys/param.h>
Packit 33f14e
# include <sys/pstat.h>
Packit 33f14e
# include <string.h>
Packit 33f14e
#endif
Packit 33f14e
Packit 33f14e
#ifdef __sgi
Packit 33f14e
# include <string.h>
Packit 33f14e
# include <unistd.h>
Packit 33f14e
# include <stdio.h>
Packit 33f14e
# include <fcntl.h>
Packit 33f14e
# include <sys/procfs.h>
Packit 33f14e
#endif
Packit 33f14e
Packit 33f14e
#include "dirname.h"
Packit 33f14e
Packit 33f14e
#ifndef HAVE_GETPROGNAME             /* not Mac OS X, FreeBSD, NetBSD, OpenBSD >= 5.4, Cygwin */
Packit 33f14e
char const *
Packit 33f14e
getprogname (void)
Packit 33f14e
{
Packit 33f14e
# if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME                /* glibc, BeOS */
Packit 33f14e
  /* https://www.gnu.org/software/libc/manual/html_node/Error-Messages.html */
Packit 33f14e
  return program_invocation_short_name;
Packit 33f14e
# elif HAVE_DECL_PROGRAM_INVOCATION_NAME                    /* glibc, BeOS */
Packit 33f14e
  /* https://www.gnu.org/software/libc/manual/html_node/Error-Messages.html */
Packit 33f14e
  return last_component (program_invocation_name);
Packit 33f14e
# elif HAVE_GETEXECNAME                                     /* Solaris */
Packit 33f14e
  /* http://docs.oracle.com/cd/E19253-01/816-5168/6mbb3hrb1/index.html */
Packit 33f14e
  const char *p = getexecname ();
Packit 33f14e
  if (!p)
Packit 33f14e
    p = "?";
Packit 33f14e
  return last_component (p);
Packit 33f14e
# elif HAVE_DECL___ARGV                                     /* mingw, MSVC */
Packit 33f14e
  /* https://msdn.microsoft.com/en-us/library/dn727674.aspx */
Packit 33f14e
  const char *p = __argv && __argv[0] ? __argv[0] : "?";
Packit 33f14e
  return last_component (p);
Packit 33f14e
# elif HAVE_VAR___PROGNAME                                  /* OpenBSD, QNX */
Packit 33f14e
  /* http://man.openbsd.org/style.9 */
Packit 33f14e
  /* http://www.qnx.de/developers/docs/6.5.0/index.jsp?topic=%2Fcom.qnx.doc.neutrino_lib_ref%2Fp%2F__progname.html */
Packit 33f14e
  /* Be careful to declare this only when we absolutely need it
Packit 33f14e
     (OpenBSD 5.1), rather than when it's available.  Otherwise,
Packit 33f14e
     its mere declaration makes program_invocation_short_name
Packit 33f14e
     malfunction (have zero length) with Fedora 25's glibc.  */
Packit 33f14e
  extern char *__progname;
Packit 33f14e
  const char *p = __progname;
Packit 33f14e
  return p && p[0] ? p : "?";
Packit 33f14e
# elif _AIX                                                 /* AIX */
Packit 33f14e
  /* Idea by Bastien ROUCARIÈS,
Packit 33f14e
     http://lists.gnu.org/archive/html/bug-gnulib/2010-12/msg00095.html
Packit 33f14e
     Reference: http://
Packit 33f14e
   ibm.biz/knowctr#ssw_aix_53/com.ibm.aix.basetechref/doc/basetrf1/getprocs.htm
Packit 33f14e
  */
Packit 33f14e
  static char *p;
Packit 33f14e
  static int first = 1;
Packit 33f14e
  if (first)
Packit 33f14e
    {
Packit 33f14e
      first = 0;
Packit 33f14e
      pid_t pid = getpid ();
Packit 33f14e
      struct procentry64 procs;
Packit 33f14e
      p = (0 < getprocs64 (&procs, sizeof procs, NULL, 0, &pid, 1)
Packit 33f14e
           ? strdup (procs.pi_comm)
Packit 33f14e
           : NULL);
Packit 33f14e
      if (!p)
Packit 33f14e
        p = "?";
Packit 33f14e
    }
Packit 33f14e
  return p;
Packit 33f14e
# elif defined __hpux
Packit 33f14e
  static char *p;
Packit 33f14e
  static int first = 1;
Packit 33f14e
  if (first)
Packit 33f14e
    {
Packit 33f14e
      first = 0;
Packit 33f14e
      pid_t pid = getpid ();
Packit 33f14e
      struct pst_status status;
Packit 33f14e
      p = (0 < pstat_getproc (&status, sizeof status, 0, pid)
Packit 33f14e
           ? strdup (status.pst_ucomm)
Packit 33f14e
           : NULL);
Packit 33f14e
      if (!p)
Packit 33f14e
        p = "?";
Packit 33f14e
    }
Packit 33f14e
  return p;
Packit 33f14e
# elif __MVS__                                              /* z/OS */
Packit 33f14e
  /* https://www.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.bpxbd00/rtwgetp.htm */
Packit 33f14e
  static char *p = "?";
Packit 33f14e
  static int first = 1;
Packit 33f14e
  if (first)
Packit 33f14e
    {
Packit 33f14e
      pid_t pid = getpid ();
Packit 33f14e
      int token;
Packit 33f14e
      W_PSPROC buf;
Packit 33f14e
      first = 0;
Packit 33f14e
      memset (&buf, 0, sizeof(buf));
Packit 33f14e
      buf.ps_cmdptr    = (char *) malloc (buf.ps_cmdlen    = PS_CMDBLEN_LONG);
Packit 33f14e
      buf.ps_conttyptr = (char *) malloc (buf.ps_conttylen = PS_CONTTYBLEN);
Packit 33f14e
      buf.ps_pathptr   = (char *) malloc (buf.ps_pathlen   = PS_PATHBLEN);
Packit 33f14e
      if (buf.ps_cmdptr && buf.ps_conttyptr && buf.ps_pathptr)
Packit 33f14e
        {
Packit 33f14e
          for (token = 0; token >= 0;
Packit 33f14e
               token = w_getpsent (token, &buf, sizeof(buf)))
Packit 33f14e
            {
Packit 33f14e
              if (token > 0 && buf.ps_pid == pid)
Packit 33f14e
                {
Packit 33f14e
                  char *s = strdup (last_component (buf.ps_pathptr));
Packit 33f14e
                  if (s)
Packit 33f14e
                    p = s;
Packit 33f14e
                  break;
Packit 33f14e
                }
Packit 33f14e
            }
Packit 33f14e
        }
Packit 33f14e
      free (buf.ps_cmdptr);
Packit 33f14e
      free (buf.ps_conttyptr);
Packit 33f14e
      free (buf.ps_pathptr);
Packit 33f14e
    }
Packit 33f14e
  return p;
Packit 33f14e
# elif defined __sgi                                        /* IRIX */
Packit 33f14e
  char filename[50];
Packit 33f14e
  int fd;
Packit 33f14e
Packit 33f14e
  sprintf (filename, "/proc/pinfo/%d", (int) getpid ());
Packit 33f14e
  fd = open (filename, O_RDONLY);
Packit 33f14e
  if (0 <= fd)
Packit 33f14e
    {
Packit 33f14e
      prpsinfo_t buf;
Packit 33f14e
      int ioctl_ok = 0 <= ioctl (fd, PIOCPSINFO, &buf;;
Packit 33f14e
      close (fd);
Packit 33f14e
      if (ioctl_ok)
Packit 33f14e
        {
Packit 33f14e
          char *name = buf.pr_fname;
Packit 33f14e
          char *namesize = sizeof buf.pr_fname;
Packit 33f14e
          char *namenul = memchr (name, '\0', namesize);
Packit 33f14e
          size_t namelen = namenul ? namenul - name : namesize;
Packit 33f14e
          char *namecopy = malloc (namelen + 1);
Packit 33f14e
          if (namecopy)
Packit 33f14e
            {
Packit 33f14e
              namecopy[namelen] = 0;
Packit 33f14e
              return memcpy (namecopy, name, namelen);
Packit 33f14e
            }
Packit 33f14e
        }
Packit 33f14e
    }
Packit 33f14e
  return NULL;
Packit 33f14e
# else
Packit 33f14e
#  error "getprogname module not ported to this OS"
Packit 33f14e
# endif
Packit 33f14e
}
Packit 33f14e
Packit 33f14e
#endif