Blame lib/getprogname.c

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