3

I am new to C programming language on Unix and trying to build a shell-like C program. However the program gives error if I try to change the function according to my own choices. For example as it seems /bin/ls -l is working but pwd is not. It may be simple but I couldn't understand the problem.

if (fork() == 0)
{
    char* argv[3];
    argv[0] = "/bin/ls";
    argv[1] = "-l";
    argv[2] = NULL;

    if(execv(argv[0], argv)==-1)
        printf("Error in calling exec!!");

    printf("I will not be printed!\n"); 
}

This function is working. I can clearly see the results on shell. However if I want to change like this, it prints error.

if(fork() == 0){
   char * argv[2];

   argv[0] = "pwd";
   argv[1] = NULL;

   if(execv(argv[0], argv) == -1)
       printf("Error in calling exec!");
    }
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
Cemil Çakmak
  • 149
  • 1
  • 12
  • Also, you need to figure out what to do in your child process if any call to `execv*()` fails. From the posted code, your child process will just continue to run, which probably isn't good since it's likely trying to run code intended for the parent process. Usually, an immediate call to `_exit()` is made. The leading underscore is important - calling `exit()` will do things like flush buffers, which are copied from the parent process when the parent process calls `fork()`. `_exit()` doesn't do that. – Andrew Henle Nov 15 '18 at 19:17

1 Answers1

4

The execv function doesn't search the path for the command to run, so it's not able to find pwd. It can find ls because you specified the full path to the executable. Use execvp instead, which does a path search.

Also, use perror to print error messages for library/system function. It will tell you why the function failed.

if(execvp(argv[0], argv) == -1)
    perror("Error in calling exec!");
dbush
  • 205,898
  • 23
  • 218
  • 273
  • +1, meanwhile a general caution to OP that [`execvp`](https://linux.die.net/man/3/execvp) can lead to trojan travesties: best to consider using a known path or a fixed set of known paths when executing programs (eg verify/sanitize `PATH` prior to `execvp`). For more: https://wiki.sei.cmu.edu/confluence/display/c/ENV03-C.+Sanitize+the+environment+when+invoking+external+programs – bishop Nov 15 '18 at 19:03
  • @bishop, whether that's good advice is very contingent on the software's invocation mode / intended execution environment / threat model / etc; appropriately-privileged users who *expect* to be able to install their own shims (or updated tools, or replace OS-vendor-provided tools with GNU ones) via PATH can be legitimately annoyed when software deliberately circumvents their efforts. – Charles Duffy Nov 15 '18 at 19:05
  • @CharlesDuffy A good point. I've rephrased from "best to use" to "give consideration". Thanks! – bishop Nov 15 '18 at 19:06