Tuesday, February 14, 2006

We're all familiar with the arguments passed to the main function by the OS:

int argc

char *argv[]

char *envp[]

But programs started on Mac OS X (i.e. Darwin) actually have access to another argument - the apple vector. The apple vector is defined as char *apple[] and it's passed as the 4th argument to the main() function (it's actually stored right after envp on the stack).

But what is it used for? Well, Apple can use the apple vector to pass whatever "hidden" parameters they want to any program. And they do actually use it, too. Currently, apple[0] contains the path where the executing binary was found on disk. What's that you say? How is apple[0] different from argv[0]? The difference is that argv[0] can be set to any arbitrary value when execve(2) is called. For example, shells often differentiate a login shell from a regular shell by starting login shells with the first character in argv[0] being a -. For example:

So, we can see that the bash login shell on my Mac was started with a dash in its name. In this example, bash's argv[0] would equal -bash, but its apple[0] would contain the path to where the bash binary was actually found (likely apple[0] would be /bin/bash).