(root)/
tar-1.35/
gnu/
progname.c
       1  /* Program name management.
       2     Copyright (C) 2001-2003, 2005-2023 Free Software Foundation, Inc.
       3     Written by Bruno Haible <bruno@clisp.org>, 2001.
       4  
       5     This program is free software: you can redistribute it and/or modify
       6     it under the terms of the GNU General Public License as published by
       7     the Free Software Foundation, either version 3 of the License, or
       8     (at your option) any later version.
       9  
      10     This program is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13     GNU General Public License for more details.
      14  
      15     You should have received a copy of the GNU General Public License
      16     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      17  
      18  
      19  #include <config.h>
      20  
      21  /* Specification.  */
      22  #undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
      23  #include "progname.h"
      24  
      25  #include <errno.h> /* get program_invocation_name declaration */
      26  #include <stdio.h>
      27  #include <stdlib.h>
      28  #include <string.h>
      29  
      30  
      31  /* String containing name the program is called with.
      32     To be initialized by main().  */
      33  const char *program_name = NULL;
      34  
      35  /* Set program_name, based on argv[0].
      36     argv0 must be a string allocated with indefinite extent, and must not be
      37     modified after this call.  */
      38  void
      39  set_program_name (const char *argv0)
      40  {
      41    /* libtool creates a temporary executable whose name is sometimes prefixed
      42       with "lt-" (depends on the platform).  It also makes argv[0] absolute.
      43       But the name of the temporary executable is a detail that should not be
      44       visible to the end user and to the test suite.
      45       Remove this "<dirname>/.libs/" or "<dirname>/.libs/lt-" prefix here.  */
      46    const char *slash;
      47    const char *base;
      48  
      49    /* Sanity check.  POSIX requires the invoking process to pass a non-NULL
      50       argv[0].  */
      51    if (argv0 == NULL)
      52      {
      53        /* It's a bug in the invoking program.  Help diagnosing it.  */
      54        fputs ("A NULL argv[0] was passed through an exec system call.\n",
      55               stderr);
      56        abort ();
      57      }
      58  
      59    slash = strrchr (argv0, '/');
      60    base = (slash != NULL ? slash + 1 : argv0);
      61    if (base - argv0 >= 7 && strncmp (base - 7, "/.libs/", 7) == 0)
      62      {
      63        argv0 = base;
      64        if (strncmp (base, "lt-", 3) == 0)
      65          {
      66            argv0 = base + 3;
      67            /* On glibc systems, remove the "lt-" prefix from the variable
      68               program_invocation_short_name.  */
      69  #if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
      70            program_invocation_short_name = (char *) argv0;
      71  #endif
      72          }
      73      }
      74  
      75    /* But don't strip off a leading <dirname>/ in general, because when the user
      76       runs
      77           /some/hidden/place/bin/cp foo foo
      78       he should get the error message
      79           /some/hidden/place/bin/cp: `foo' and `foo' are the same file
      80       not
      81           cp: `foo' and `foo' are the same file
      82     */
      83  
      84    program_name = argv0;
      85  
      86    /* On glibc systems, the error() function comes from libc and uses the
      87       variable program_invocation_name, not program_name.  So set this variable
      88       as well.  */
      89  #if HAVE_DECL_PROGRAM_INVOCATION_NAME
      90    program_invocation_name = (char *) argv0;
      91  #endif
      92  }