Blame lib/progname.c

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