2

Here are the standard exec* functions:

int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,  ..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);

It's the Unix convention to pass the program name to be executed as the first member of the argument array.

In what realistic context(s) (if any) does it make sense to diverge from the convention and not make path/file the same as arg/argv[0]?

Petr Skocik
  • 28,816

2 Answers2

3

Program can behave differently depend on which name it was called.

An example is bash, which will enter POSIX mode if invoked as sh:

$ bash -c 'set() { echo 1; }; set'
1

while:

$ ARGV0=sh bash -c 'set() { echo 1; }; set'
sh: `set': is a special builtin

(zsh use ARGV0 variable to pass argv[0])

cuonglm
  • 153,898
  • Honestly this should be the accepted answer. Not only are there programs which make extensive use of this (BusyBox/ToyBox/ToolBox use argv[0] to choose what program to act like, literally every traditional shell uses argv[0][0] == '-' as a way to know if it needs to act like a login shell, etc), but this was also probably one of the first uses of the zeroth argument, and is probably actually one of the reasons for why the zeroth argument exists - whereas the ps thing is a modern hack poorly working around a modern problem. – mtraceur Jul 05 '21 at 00:13
3

For one reason for another, the difference has been used to change the way the process appears in ps. Some of that has been obviated by changes to operating systems.

With this in mind, here are a few links to examples found:

  • why we pass same value in first 2 argument of execlp()
    In particular, @sami-kuhmonen comment about making symbolic links "look" like the real file.
  • hide.c /*---------------------------------------------------------------------------+ | Copyright (c) 1992 Oracle Corporation Belmont, California, USA | | All rights reserved | +---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------+ | FILENAME | | hide.c | | DESCRIPTION | | Hides arguments for programs on UNIX systems. | | Can be used as a program prefix: hide program arguments | | or as a symbolic link. If this program is not invoked as hide, it | | will hide its arguments and invoke the program name.hide | | The best way to use this is to rename your critical programs to | | program.hide, and create a symbolic link program to hide. | | mv sqlplus sqlplus.hide; ln -s hide sqlplus | | Thus when sqlplus is invoked, its arguments will be hidden | | NOTES | | This program works by padding 3000 '/' chars in argv[0]. This fools | | all known ps's. This will reduce the argument capacity of your | | program by 3000 chars. A good enhancement would be to reduce the | | padding if needed so that no arguments are lost - would require a | | method of determining the max argument size on the system. Some | | system's provide the E2BIG error on exec. | | There is some performace penalty for using this program, but it is | | minimal because this program is so small - the biggest cost is the | | extra exec required to get this program started. | | HISTORY | | 09/15/92 R Brodersen Created, based on D Beusee's hideargs() | | 09/17/92 D Beusee Fixed to compile on any system | +---------------------------------------------------------------------------*/
Thomas Dickey
  • 76,765