Blame lib/progname.c

Packit Service fdd496
/* Program name management.
Packit Service fdd496
   Copyright (C) 2001-2003, 2005-2017 Free Software Foundation, Inc.
Packit Service fdd496
   Written by Bruno Haible <bruno@clisp.org>, 2001.
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
Packit Service fdd496
#include <config.h>
Packit Service fdd496
Packit Service fdd496
/* Specification.  */
Packit Service fdd496
#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
Packit Service fdd496
#include "progname.h"
Packit Service fdd496
Packit Service fdd496
#include <errno.h> /* get program_invocation_name declaration */
Packit Service fdd496
#include <stdio.h>
Packit Service fdd496
#include <stdlib.h>
Packit Service fdd496
#include <string.h>
Packit Service fdd496
Packit Service fdd496
Packit Service fdd496
/* String containing name the program is called with.
Packit Service fdd496
   To be initialized by main().  */
Packit Service fdd496
const char *program_name = NULL;
Packit Service fdd496
Packit Service fdd496
/* Set program_name, based on argv[0].
Packit Service fdd496
   argv0 must be a string allocated with indefinite extent, and must not be
Packit Service fdd496
   modified after this call.  */
Packit Service fdd496
void
Packit Service fdd496
set_program_name (const char *argv0)
Packit Service fdd496
{
Packit Service fdd496
  /* libtool creates a temporary executable whose name is sometimes prefixed
Packit Service fdd496
     with "lt-" (depends on the platform).  It also makes argv[0] absolute.
Packit Service fdd496
     But the name of the temporary executable is a detail that should not be
Packit Service fdd496
     visible to the end user and to the test suite.
Packit Service fdd496
     Remove this "<dirname>/.libs/" or "<dirname>/.libs/lt-" prefix here.  */
Packit Service fdd496
  const char *slash;
Packit Service fdd496
  const char *base;
Packit Service fdd496
Packit Service fdd496
  /* Sanity check.  POSIX requires the invoking process to pass a non-NULL
Packit Service fdd496
     argv[0].  */
Packit Service fdd496
  if (argv0 == NULL)
Packit Service fdd496
    {
Packit Service fdd496
      /* It's a bug in the invoking program.  Help diagnosing it.  */
Packit Service fdd496
      fputs ("A NULL argv[0] was passed through an exec system call.\n",
Packit Service fdd496
             stderr);
Packit Service fdd496
      abort ();
Packit Service fdd496
    }
Packit Service fdd496
Packit Service fdd496
  slash = strrchr (argv0, '/');
Packit Service fdd496
  base = (slash != NULL ? slash + 1 : argv0);
Packit Service fdd496
  if (base - argv0 >= 7 && strncmp (base - 7, "/.libs/", 7) == 0)
Packit Service fdd496
    {
Packit Service fdd496
      argv0 = base;
Packit Service fdd496
      if (strncmp (base, "lt-", 3) == 0)
Packit Service fdd496
        {
Packit Service fdd496
          argv0 = base + 3;
Packit Service fdd496
          /* On glibc systems, remove the "lt-" prefix from the variable
Packit Service fdd496
             program_invocation_short_name.  */
Packit Service fdd496
#if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
Packit Service fdd496
          program_invocation_short_name = (char *) argv0;
Packit Service fdd496
#endif
Packit Service fdd496
        }
Packit Service fdd496
    }
Packit Service fdd496
Packit Service fdd496
  /* But don't strip off a leading <dirname>/ in general, because when the user
Packit Service fdd496
     runs
Packit Service fdd496
         /some/hidden/place/bin/cp foo foo
Packit Service fdd496
     he should get the error message
Packit Service fdd496
         /some/hidden/place/bin/cp: `foo' and `foo' are the same file
Packit Service fdd496
     not
Packit Service fdd496
         cp: `foo' and `foo' are the same file
Packit Service fdd496
   */
Packit Service fdd496
Packit Service fdd496
  program_name = argv0;
Packit Service fdd496
Packit Service fdd496
  /* On glibc systems, the error() function comes from libc and uses the
Packit Service fdd496
     variable program_invocation_name, not program_name.  So set this variable
Packit Service fdd496
     as well.  */
Packit Service fdd496
#if HAVE_DECL_PROGRAM_INVOCATION_NAME
Packit Service fdd496
  program_invocation_name = (char *) argv0;
Packit Service fdd496
#endif
Packit Service fdd496
}