Live data from Hacker News

Why bother with argv[0]?

wietzebeukema.nl

151–160 of 277 posts

Re: Why bother with argv[0]?

#151

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…

Not an author, but there's a good alternative. If busybox was edited to ignore argv[2], then applets could be called via shebangs, instead of symlinks: $ echo '#!/path/to/busybox echo' > myecho $ chmod +x myecho $ ./myecho 123 ./myecho 123 Right now this doesn't work properly, because "./myecho" (argv[0]) gets placed into argv[2] of the process. Otherwise, this technique IMHO is better than symlinks: - Each applet us…

Well that would be inefficient. For each command you run the kernel has to read the file, detect that it has a shebang, parse the shebang line, and then finally load the actual executable in memory. That could be a performance problem, since busybox is used typically in embedded systems that doesn't have a lot of resources: imagine a shell script that runs a command in a loop, it has to do a lot of extra work.

Finally, symlinks can be relative, while the solution you proposed is not. This is particularly useful for distributing software, e.g. distributing a tar file with the busybox itself and their symlinks.

In fact, you don't even need symlinks at all: you can even have hard links, that could even save disk space on embedded filesystems, that are readonly images anyway.

Re: Why bother with argv[0]?

#152

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…

Not an author, but there's a good alternative. If busybox was edited to ignore argv[2], then applets could be called via shebangs, instead of symlinks: $ echo '#!/path/to/busybox echo' > myecho $ chmod +x myecho $ ./myecho 123 ./myecho 123 Right now this doesn't work properly, because "./myecho" (argv[0]) gets placed into argv[2] of the process. Otherwise, this technique IMHO is better than symlinks: - Each applet us…

> Each applet uses the same amount of disk space (0 blocks, i.e. the content fits into inode).

Is that really the case? AFAIK, OpenWRT uses SquashFS by default, and a quick web search tells me that "[...] In addition, inode and directory data are highly compacted, and packed on byte boundaries. Each compressed inode is on average 8 bytes in length [...]" (https://www.kernel.org/doc/html/latest/filesystems/squashfs....). That is, even if the content fits into the inode, it will make the inode use more space (they're variable-size, unlike on traditional filesystems with fixed-size inodes).

And using hardlinks (traditionally, we use hardlinks with busybox, not symlinks) goes even further: all commands use a single inode, the only extra space needed is for the directory entry (which you need anyway).

Re: Why bother with argv[0]?

#153
post #53

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…

For busybox/toybox the argv[0] thing is great, and seems to be the prime example of why argv[0] shouldn't go - yet it is a bit of an anomaly in how argv[0] is used. If there really is a need for having one executable that comprises multiple commands, is `busybox whoami` instead of `whoami` so much more effort? To me, that would make more sense in terms of what is going on; aliases could be used if one-word commands a…

Well of course it's not only a matter of interactive usage (even because the busybox itself shell could do the conversion). The problem are script, or worse programs that invokes commands as subprocesses (programs that maybe you don't have have access to the source code!).

What you do? Replace every single occurrence of each command by prefixing it `busybox`? Not ideal at all...

Re: Why bother with argv[0]?

#154
> This seems like a questionable design decision. Should a program be allowed to behave differently based on its name? From a 2020s standpoint, this seems highly undesirable, as it makes software less predictable and goes against modern design principles.

No it doesn't make software less predictable nor does it goes against modern design principles. argv has very handy use cases and can be used to provide better user experience.

Unless you have evidence to back up your claims, you're just turning a subjective opinion to an objective one without any merit.

Either way, it's software developer choice and irrelevant to the user as much as it is irrelevant to the user whether the developer prefers for(;;) over while(1).

Re: Why bother with argv[0]?

#155

Earlier quoted context omitted.

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.

> None of the weird arg[0] examples can happen on the shell (without escaping), only when using system calls.

  $ help exec
  [...]
  Options:
    -a name pass NAME as the zeroth argument to COMMAND
Even in shell, you can explicitly specify the argv[0] when running an executable.

Re: Why bother with argv[0]?

#156
post #130
post #53

Earlier quoted context omitted.

For busybox/toybox the argv[0] thing is great, and seems to be the prime example of why argv[0] shouldn't go - yet it is a bit of an anomaly in how argv[0] is used. If there really is a need for having one executable that comprises multiple commands, is `busybox whoami` instead of `whoami` so much more effort? To me, that would make more sense in terms of what is going on; aliases could be used if one-word commands a…

`busybox whoami` is probably fine, but having to write `busybox ls`, `busybox grep`, `busybox cp` etc. would get tedious quickly. Shell aliases don't solve all problems, even if you do: alias rm="busybox rm" alias xargs="busybox xargs" # etc. you still have to write `xargs -exec busybox rm`, because xargs won't use the shell alias. But the main problem with this approach is that POSIX and LSB require certain binaries…

Well /bin/sh is also busybox, so I think you'd need

    #!/bin/busybox sh
    exec /bin/busybox ls

?

Re: Why bother with argv[0]?

#157
post #51

Earlier quoted context omitted.

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…

I think you forget the exec system call’s first argument is a path to an executable, followed by an array of arguments, where arg[0] lives. I can’t find issue with exec(“/proc/self/exe”, [ program , … ).

Well, it could be for example that /proc is not mounted. A lot of software breaks for this, while really there is no need for it to be so. Also that approach only works on Linux, if you want to write a portable software what you do?

Re: Why bother with argv[0]?

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

And that makes a lot of sense, especially for binaries that are statically linked (as usually are Rust binaries), since that could save a lot of disk space!

Re: Why bother with argv[0]?

#159

It’s part of the shambolic world of Unix and C. But “worse is better!” A good language spec is laid out in a way that reads from front to back with minimized circularity. See Common Lisp, Java, Python, etc. As a kid in high school checking out Unix manuals and implementing many Unix tools in https://subethasoftware.com/2022/09/27/exploring-1984-os-9-o... I struggled with K&R because of the circularity of the book, wh…

i may have missed it, but where does the C Standard say anything about access to a symbol table? or even if such a thing exists. and as for IBM i managed to use all sorts of OSs in VMs on IBM hardware back in the 1980s. Which did you have problems with?

The parser in C has to keep track of the symbol table to handle cases like

   typdef int myint;
   myint x;
which is unusual among programming languages. Sure I used VM on IBM hardware in the 1980s and it was great. I also used timesharing systems on the PDP-8 (what atrocious hardware!), the PDP-11 and the PDP-10/20 in the 1970s. Although the 360 was superior in so many respects (except for the slow interrupt handling) it failed to break into the huge market for general-purpose timesharing to support software development and such (learning BASIC) until the time microcomputers came along and crushed the timesharing market. (PDP-10 was famously used to develop microcomputer software such as the original Microsoft BASIC and Infocom's z-machine games)

Fred Brooks' project to develop an OS for the 360 was notoriously troubled and IBM belatedly turned to VM as a dark horse. Today it looks ahead of its time (as virtualization became mainstream on x86 in the 00's) but back then IBM was flailing and they wound up with a good software story by accident. It was not really their fault, people just didn't know how to make an OS and the most advanced thinking back then was monstrosities like MULTICS. It was Unix and VAX/VMS that pointed to what a general purpose OS would look like a few years later and there has been relatively little innovation since then because nobody can afford to rearchitect the user space. (e.g. no way you can take out the "bloat" because you'll have to put it back in to run the software you want)

IBM's z-architecture (the other z) has a great software story today (even runs Linux) but it was not the Plan A or even the Plan B.

Re: Why bother with argv[0]?

#160

Earlier quoted context omitted.

Plus the whole "space is not an issue" thing along with "you can just add more ram" is the reason everything is so bloated and slow even on well provisioned machines.

These days, Windows Calculator takes up more memory than mIRC. Tell me why a simple calculator app needs more memory than a complete multi-server implementation of the IRC protocol (including SSL/TLS), not to mention a full scripting engine.

>These days, Windows Calculator takes up more memory than mIRC.

I'd be somewhat surprised if that's actually true, but I haven't used mirc for years (started using hexchat once I was honest about the fact that I wasn't going to pay for mirc) but I think a lot of that is an inherent part of windows development now, basic c# projects with graphics end up being pretty big.

Interestingly enough, the new windows calculator is mit licensed and on github. But also it has a lot more features than most people think, it's not a 'simple calculator app', it's a full featured graphing calculator even if most people don't use those features.

Post reply on HN