Blame lib/getprogname.c

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