Blame src/gl/progname.c

Packit aea12f
/* Program name management.
Packit Service 991b93
   Copyright (C) 2001-2003, 2005-2020 Free Software Foundation, Inc.
Packit aea12f
   Written by Bruno Haible <bruno@clisp.org>, 2001.
Packit aea12f
Packit aea12f
   This program is free software: you can redistribute it and/or modify
Packit aea12f
   it under the terms of the GNU General Public License as published by
Packit aea12f
   the Free Software Foundation; either version 3 of the License, or
Packit aea12f
   (at your option) any later version.
Packit aea12f
Packit aea12f
   This program is distributed in the hope that it will be useful,
Packit aea12f
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit aea12f
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit aea12f
   GNU General Public License for more details.
Packit aea12f
Packit aea12f
   You should have received a copy of the GNU General Public License
Packit aea12f
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
Packit aea12f
Packit aea12f
Packit aea12f
#include <config.h>
Packit aea12f
Packit aea12f
/* Specification.  */
Packit aea12f
#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
Packit aea12f
#include "progname.h"
Packit aea12f
Packit aea12f
#include <errno.h> /* get program_invocation_name declaration */
Packit aea12f
#include <stdio.h>
Packit aea12f
#include <stdlib.h>
Packit aea12f
#include <string.h>
Packit aea12f
Packit aea12f
Packit aea12f
/* String containing name the program is called with.
Packit aea12f
   To be initialized by main().  */
Packit aea12f
const char *program_name = NULL;
Packit aea12f
Packit aea12f
/* Set program_name, based on argv[0].
Packit aea12f
   argv0 must be a string allocated with indefinite extent, and must not be
Packit aea12f
   modified after this call.  */
Packit aea12f
void
Packit aea12f
set_program_name (const char *argv0)
Packit aea12f
{
Packit aea12f
  /* libtool creates a temporary executable whose name is sometimes prefixed
Packit aea12f
     with "lt-" (depends on the platform).  It also makes argv[0] absolute.
Packit aea12f
     But the name of the temporary executable is a detail that should not be
Packit aea12f
     visible to the end user and to the test suite.
Packit aea12f
     Remove this "<dirname>/.libs/" or "<dirname>/.libs/lt-" prefix here.  */
Packit aea12f
  const char *slash;
Packit aea12f
  const char *base;
Packit aea12f
Packit aea12f
  /* Sanity check.  POSIX requires the invoking process to pass a non-NULL
Packit aea12f
     argv[0].  */
Packit aea12f
  if (argv0 == NULL)
Packit aea12f
    {
Packit aea12f
      /* It's a bug in the invoking program.  Help diagnosing it.  */
Packit aea12f
      fputs ("A NULL argv[0] was passed through an exec system call.\n",
Packit aea12f
             stderr);
Packit aea12f
      abort ();
Packit aea12f
    }
Packit aea12f
Packit aea12f
  slash = strrchr (argv0, '/');
Packit aea12f
  base = (slash != NULL ? slash + 1 : argv0);
Packit aea12f
  if (base - argv0 >= 7 && strncmp (base - 7, "/.libs/", 7) == 0)
Packit aea12f
    {
Packit aea12f
      argv0 = base;
Packit aea12f
      if (strncmp (base, "lt-", 3) == 0)
Packit aea12f
        {
Packit aea12f
          argv0 = base + 3;
Packit aea12f
          /* On glibc systems, remove the "lt-" prefix from the variable
Packit aea12f
             program_invocation_short_name.  */
Packit aea12f
#if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
Packit aea12f
          program_invocation_short_name = (char *) argv0;
Packit aea12f
#endif
Packit aea12f
        }
Packit aea12f
    }
Packit aea12f
Packit aea12f
  /* But don't strip off a leading <dirname>/ in general, because when the user
Packit aea12f
     runs
Packit aea12f
         /some/hidden/place/bin/cp foo foo
Packit aea12f
     he should get the error message
Packit aea12f
         /some/hidden/place/bin/cp: `foo' and `foo' are the same file
Packit aea12f
     not
Packit aea12f
         cp: `foo' and `foo' are the same file
Packit aea12f
   */
Packit aea12f
Packit aea12f
  program_name = argv0;
Packit aea12f
Packit aea12f
  /* On glibc systems, the error() function comes from libc and uses the
Packit aea12f
     variable program_invocation_name, not program_name.  So set this variable
Packit aea12f
     as well.  */
Packit aea12f
#if HAVE_DECL_PROGRAM_INVOCATION_NAME
Packit aea12f
  program_invocation_name = (char *) argv0;
Packit aea12f
#endif
Packit aea12f
}