c++cbashexecve

execve not giving outputting with "which" command


I've been working on understanding the execve command, and I've encountered an issue that I've narrowed down. I'm puzzled as to why execve doesn't work with the "which" command but works perfectly fine with other commands like "ls". I obtained the paths for these executables directly from the Bash shell.

Here's the code that doesn't work with "which":

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(void)
{
    char    *cmd_args_joined[] = {"which", "ls", NULL};
    char    cmd_plus_path[] = "/usr/bin/which";

    if (execve(cmd_plus_path, cmd_args_joined, NULL) < 0)
    {
        perror("failed at execve\n");
        exit(1);
    }
    return (0);
}

And here's the code that works with "ls":

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(void)
{
    char    *cmd_args_joined[] = {"ls", NULL};
    char    cmd_plus_path[] = "/bin/ls";

    if (execve(cmd_plus_path, cmd_args_joined, NULL) < 0)
    {
        perror("failed at execve\n");
        exit(1);
    }
    return (0);
}

I would greatly appreciate any insights or suggestions to help me understand and resolve this issue. Thank you!

I initially suspected that I might have inadvertently redirected the standard output to another file. However, given that the code above doesn't employ dup2() for redirection, I must conclude that my initial assumption was incorrect.


Solution

  • The problem isn't your call to execve. The problem is with no environment, which won't find ls and produce no output. Had you checked the return code you would find it to be nonzero.

    Stupid fix:

    if (execve(cmd_plus_path, cmd_args_joined, environ) < 0)
    

    The exported variable environ is the process environment. You can also capture it as the third argument to main, but that's deprecated.