Live data from Hacker News

Why bother with argv[0]?

wietzebeukema.nl

61–70 of 277 posts

Re: Why bother with argv[0]?

#61
post #16

"Windows’ own API calls for creating new processes (such as CreateProcess [6], ShellExecute [7]) do not allow you to set argv[0]: it sets it for you, based on how the path to the executable was provided." Isn't this contradicted by the docs? CreateProcess receives lpApplicationName and lpCommandLine, and they can be different.

Not the way I understand it. In the execv documentation[1], you pass the program name twice:

int execv(const char *path, char *const argv[]);

The argument path points to a pathname that identifies the new process image file.

The argument argv is an array of character pointers to null-terminated strings. [..] The value in argv[0] should point to a filename string that is associated with the process being started by one of the exec functions.

Windows does not allow you to do that, AFAIK.

[1]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/e...

Re: Why bother with argv[0]?

#62

Earlier quoted context omitted.

Also if you want a program to call itself, which is sometimes useful, this way lets you actually call the same program, rather than assuming the name and path.

There's no guarantee that the name and the path are still the same executable that is running, or that they even exist anymore.

I mean sure. All software is built on assumptions. Make sure the assumptions you’re making are appropriate in context.

Re: Why bother with argv[0]?

#63

So obviously claiming that there's no good reason for process to read argv[0] is either demonstrating the author's ignorance or needs a much stronger defense; I'd be fascinated to hear how they think busybox should work on an OpenWrt box with a 16MB root filesystem. However , I am willing to consider the discussion about whether there could be merit to restricting the ability to write that value; I could imagine a sy…

Restricting setting it would break login.

Not that it couldn't be fixed by changing how we handle login shells but still. Worth remembering.

Similarly the busybox situation could be solved by having busybox ship posix shell wrapper scripts which use `#!/bin/busybox sh` as the shebang and simply consist of a line like `exec /bin/busybox ls "$@"`.

Re: Why bother with argv[0]?

#64
For a command line utility, argv[0] is nice to see in error messages (e.g. `./tool: fatal: Could not open './file' for reading`). When the shell combines stdout and stderr, it's easier to spot exactly what you just typed as argv[0] from all the other output.

For most other things, definitely unnecessary.

Re: Why bother with argv[0]?

#65
post #51
post #23

Earlier quoted context omitted.

Don't do this - if you (reliably) want the path to the current executable there is no portable way to do it, but on Linux you need to readlink /proc/self/exe and on MacOS you call _NSGetExecutablePath. I forget the API on Windows.

I would not say it in such absolute way - /proc/self/exe has downsides as well. As this resolves all symlinks, so this breaks all the things that depend on argv[0], like nice help messages, python's virtualenv, name-based dispatch, and seeing if the program which was executed via symlink or not. A lot of times you know you never called chdir(), in which case I'd actually recommend executing argv[0], as this is nicest…

Those are all cases where you're using argv[0] as an argument to the program where it's appropriate. Using it as the path to spawn a child process is incorrect. You're free to re-use it as an argument.

I have fixed enough software that made this mistake that I'm confident to be absolute about it. It's a very easy mistake to make but it's really annoying when software makes it and someone needs to deal with it at a higher level. It's better for developers to know that argv[0] isn't the path to the executable it's what was used to invoke the executable.

Re: Why bother with argv[0]?

#66
I don't think the argv was made with security in mind.

If we want something to be used in security field, the design since day 0 should consider it. Trying to retrofit something will break a lot of things.

Re: Why bother with argv[0]?

#67
> Today however, disk space is no longer considered an issue; this is evidenced by macOS Sonoma, where shutdown and reboot are two separate executables.

Try running `ls -li /usr/bin` on macOS and you might be surprised to learn that all of these are a single executable: DeRez, GetFileInfo, Rez, SetFile, SplitForks, ar, as, asa, ... yacc. There's 77 different entries in `/usr/bin` (including `git` and `python3`) that are all links to the same binary (`com.apple.dt.xcode_select.tool-shim`). It's a wrapper that implements the `xcode-select` concept to locate and run the real executable provided by either the Command Line Tools package or a particular Xcode version you may have installed.

And that's not the only one. There's another 68 links starting with `binhex.pl` and ending with `zipdetails` that are a single 811 byte wrapper-script around perl.

Altogether, I see that there are 26 different names that are multiply linked:

  ls -li /usr/bin |
  awk '{print $1}' | 
  sort | uniq -c | 
  sort -n | grep -v "\s*1\s" | wc -l
Some of the other examples: less & more, bc & dc, atrm & batch, stat & readlink.

Having a program behave dynamically based on argv[0] is a useful tool in the Unix toolbox. The alternative would be compiling 77 different versions of `tool-shim,` creating 68 different versions of that perl wrapper, etc.

The `git` binary uses this concept too. You can create an executable named `git-foo`, put it anywhere in your PATH, and then call it as `git foo`.

In the end, argv[0] is just an argument that can be used to improve CLI ergonomics and reduce code duplication. It's not solely about disk space. I think that makes it a more common and useful concept than you give it credit for.

As to the rest of the post: I'm not really sure how argv[0] being in the caller's control is any different than the rest of the execution context being in the caller's control: the remaining arguments, the environment, limits on file descriptors, which file descriptors are open, the program's real and effective uid and gid, signals it might receive and so on. These all amount to untrusted input any executable has to be cognizant of, more or less so depending upon what privileges the executable has and what its goals are.

Re: Why bother with argv[0]?

#68

> “Should a program be allowed to behave differently based on its name?” I don’t see why not. It’s allowed to behave differently based on the arguments that follow it. I personally think the genericity of including the program name itself as one of its own calling arguments is really meta cool.

One other historical reason for this (also the reason that older unix utilities tend to have such short names) is that people often interacted with unix machines over slow terminals or even paper teletypes. Typing "rm" instead of "remove" or "reboot" instead of "systemctl --reboot" was legitimately more convenient.

I mean, it's still more convenient to type `rm` rather than `Remove-Item` when doing day-to-day computer tasks on your computer (yes I'm one of those people who lives in a terminal).

It's also certainly better from a readability standpoint to have `Remove-Item` rather than `rm` in a script.

Likewise, I would much rather type `ls -Al` rather than `ls --almost-all --long-listing` (N.B. --long-listing is not the long option for -l, -l has no long option, I just made up an appropriate name) when listing a directory but would probably appreciate the long form in a script.

I think just like we have long options and short options, it would be helpful to have long commands and short commands.

Re: Why bother with argv[0]?

#69

So obviously claiming that there's no good reason for process to read argv[0] is either demonstrating the author's ignorance or needs a much stronger defense; I'd be fascinated to hear how they think busybox should work on an OpenWrt box with a 16MB root filesystem. However , I am willing to consider the discussion about whether there could be merit to restricting the ability to write that value; I could imagine a sy…

That seems unnecessarily harsh. I don't think that's the gist of the article, but the throwaway suggestion of 'just make lots of copies, who cares about diskspace' is insufficient and thus distracts. It's.. a single line about solutions in an article that isn't _about_ solving problems, it's about highlighting a problem exists and that it's worth solving. I read the article more as: There is __often__ no good reason…

> highlighting a problem exists

Coding bugs into your programs is not a problem it’s a bug. None of the weird arg[0] examples can happen on the shell (without escaping), only when using system calls.

The more I read the article the more I feel this is a reaction to a behavior the author did not expect and fancy them as smart therefore the last 20 years of use age of this feature are obviously wrong.

Re: Why bother with argv[0]?

#70

So obviously claiming that there's no good reason for process to read argv[0] is either demonstrating the author's ignorance or needs a much stronger defense; I'd be fascinated to hear how they think busybox should work on an OpenWrt box with a 16MB root filesystem. However , I am willing to consider the discussion about whether there could be merit to restricting the ability to write that value; I could imagine a sy…

[deleted]
Post reply on HN