56

I have spent the last 2 days trying to understand the execlp() system call, but yet here I am. Let me get straight to the issue.

The man page of execlp declares the system call as int execlp(const char *file, const char *arg, ...); with the description: The const char arg and subsequent ellipses in the execl(), execlp(), and execle() functions can be thought of as arg0, arg1, ..., argn.

Yet I see the system call being called like this in our text book: execlp(“/bin/sh”, ..., “ls -l /bin/??”, ...); (the "..." are for us to figure out as students). However this system call doesn´t even resemble anything like the declaration on the man page of the system call.

I am super confused. Any help is appreciated.

Anthony Geoghegan
  • 11,533
  • 5
  • 49
  • 56
Arman Iqbal
  • 725
  • 2
  • 8
  • 14
  • because in the man page it's the definition of the function and I guess in your text book it's an exemple of how to use it – Alexis Feb 04 '14 at 17:17
  • You are right. But what exactly is it trying to do in the above example and how exactly is it being used? Google has very poor info I feel on execlp(). – Arman Iqbal Feb 04 '14 at 17:32
  • 3
    What do you mean it "doesn't even resemble" the declaration? The arguments are `char *`. That very closely resembles a `char *`! – William Pursell Feb 04 '14 at 17:37

2 Answers2

102

this prototype:

  int execlp(const char *file, const char *arg, ...);

Says that execlp ìs a variable argument function. It takes 2 const char *. The rest of the arguments, if any, are the additional arguments to hand over to program we want to run - also char * - all these are C strings (and the last argument must be a NULL pointer)

So, the file argument is the path name of an executable file to be executed. arg is the string we want to appear as argv[0] in the executable. By convention, argv[0] is just the file name of the executable, normally it's set to the same as file.

The ... are now the additional arguments to give to the executable.

Say you run this from a commandline/shell:

$ ls

That'd be execlp("ls", "ls", (char *)NULL); Or if you run

$ ls -l /

That'd be execlp("ls", "ls", "-l", "/", (char *)NULL);

So on to execlp("/bin/sh", ..., "ls -l /bin/??", ...);

Here you are going to the shell, /bin/sh , and you're giving the shell a command to execute. That command is "ls -l /bin/??". You can run that manually from a commandline/shell:

 $ ls -l /bin/??

Now, how do you run a shell and tell it to execute a command ? You open up the documentation/man page for your shell and read it.

What you want to run is:

$ /bin/sh -c "ls -l /bin/??"

This becomes

  execlp("/bin/sh","/bin/sh", "-c", "ls -l /bin/??", (char *)NULL);

Side note: The /bin/?? is doing pattern matching, this pattern matching is done by the shell, and it expands to all files under /bin/ with 2 characters. If you simply did

  execlp("ls","ls", "-l", "/bin/??", (char *)NULL);

Probably nothing would happen (unless there's a file actually named /bin/??) as there's no shell that interprets and expands /bin/??

nos
  • 223,662
  • 58
  • 417
  • 506
  • Are there any special header files you need to run shell commands like this? I tried the above examples and I recieved a bunch of errors like `error: stray ‘\235’ in program` and `error: too few arguments to function ‘execlp’`. Im guessing its because of a header file missing. I used the function like this: `execlp(“/bin/sh”,“/bin/sh”, "-c", mystring, (char *)NULL);` where mystring is a string varible containing an input string of whatever bash command I want `execlp()` to execute. – Arman Iqbal Feb 04 '14 at 20:14
  • @ArmanIqbal The quotes somehow got changed here. But this is C code, so change the strings to be enclosed in double quotes. These: `"` Also read the man page for [execlp](http://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html) to learn which header files you need to include – nos Feb 04 '14 at 20:21
18

The limitation of execl is that when executing a shell command or any other script that is not in the current working directory, then we have to pass the full path of the command or the script. Example:

execl("/bin/ls", "ls", "-la", NULL);

The workaround to passing the full path of the executable is to use the function execlp, that searches for the file (1st argument of execlp) in those directories pointed by PATH:

execlp("ls", "ls", "-la", NULL);
lihudi
  • 860
  • 1
  • 12
  • 21