Blame lib/getprogname.c

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