Live data from Hacker News

Why bother with argv[0]?

wietzebeukema.nl

11–20 of 277 posts

Re: Why bother with argv[0]?

#11
post #4

It is sometimes used to allow one binary to be the symlink target of hundreds of commands. Android does this for most common shell commands. Toybox and busybox are examples of such implementations. https://github.com/landley/toybox https://en.m.wikipedia.org/wiki/BusyBox

I just learned that rustup/rustc/cargo etc. work like this too. I couldn't understand why the gentoo formula was symlinking the same binary to a bunch of aliases.

Re: Why bother with argv[0]?

#13
post #2

Wait until he finds out about busybox! Also claiming that the windows API to call a new process is good… wow… I guess he's never had to pass a filename with quotes and spaces in its name. The API expects you to do the escaping yourself. Yes it needs to be escaped, because it's all one single string.

There are a number of good things about CreateProcess, but argument passing is not one of them. It's a very longstanding misfeature in the design of CMD.EXE and almost certainly dates from MSDOS and therefore CP/M.

A side effect of that is that programs do their own unescaping. Unix users who are used to quotes being stripped for them may be surprised by this.

Re: Why bother with argv[0]?

#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.

Re: Why bother with argv[0]?

#17
post #4

It is sometimes used to allow one binary to be the symlink target of hundreds of commands. Android does this for most common shell commands. Toybox and busybox are examples of such implementations. https://github.com/landley/toybox https://en.m.wikipedia.org/wiki/BusyBox

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.

Beware TOC TOU problems when doing this.

Re: Why bother with argv[0]?

#18

I also use argv[0] for the -h help text, to show examples how to use the command.

There is also a neat little BSD extension, also supported on a number of other Unix-like systems and GNU userspace (i.e. glibc, but also other libcs like Musl):

    extern char *__progname;
which holds the program name without the (optional) invocation path in front of it. Basically the last path component of argv[0].

Re: Why bother with argv[0]?

#19
post #4

It is sometimes used to allow one binary to be the symlink target of hundreds of commands. Android does this for most common shell commands. Toybox and busybox are examples of such implementations. https://github.com/landley/toybox https://en.m.wikipedia.org/wiki/BusyBox

I just learned that rustup/rustc/cargo etc. work like this too. I couldn't understand why the gentoo formula was symlinking the same binary to a bunch of aliases.

On my system, these are hardlinks (regular files with a link count >1 and the same inode) rather than symlinks, though I'm not sure why.

Re: Why bother with argv[0]?

#20
post #4

It is sometimes used to allow one binary to be the symlink target of hundreds of commands. Android does this for most common shell commands. Toybox and busybox are examples of such implementations. https://github.com/landley/toybox https://en.m.wikipedia.org/wiki/BusyBox

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.

You can do this without assuming the name by execing /proc/$PID/exe. Then you're not vulnerable to the argv[0] spoofing described in the article. (But of course since argv[0] does exist, you should set it properly and pass through your own argv[0] unchanged.)
Post reply on HN