Blame lib/progname.c

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