6

In my code I need to execute /bin/bash, but I wan't to do it without passing any arguments to it. I wrote this:

execl("/bin/bash", NULL);

Then, through some research, I realized that I also need to add type cast:

execl("bin/bash", (char*) NULL);

but GCC is still giving me warnings:

main.c:18:5: warning: null argument where non-null required (argument 2) [-Wnonnull]
     if(execl("/bin/bash", (char*) NULL) == -1) {
     ^
main.c:18:5: warning: not enough variable arguments to fit a sentinel [-Wformat=]

What is the proper way of doing this, am I misunderstanding something, or am I using a completely wrong function call?

Błażej Michalik
  • 4,474
  • 40
  • 55
  • 3
    You've got a couple of substantially identical answers so far. I'll observe that the classic way of getting a login shell was `execl("/bin/sh", "-sh", (char *)0)`, where the `-` indicated that it was a login shell. Bash (and some other shells) have regularized it so that `execl("/bin/bash", "bash", "-l", (char *)0)` is a login shell. – Jonathan Leffler Dec 21 '15 at 16:57

4 Answers4

11

You are getting the warning because the convention is that the first argument is always the same as the path of the program being run, like this:

execl("/bin/bash", "/bin/bash", (char*) NULL);

This is essentially what happens when you run a program without arguments in the shell.

This argument will go into the executed program's argv[0], which it can use to check how it was run.

interjay
  • 107,303
  • 21
  • 270
  • 254
  • 3
    The convention is that the first arg is the full path as it was run, not just the filename. You got it right in your example however. – John Zwinck Dec 21 '15 at 17:01
3

Per the man page, execl() has the following defintion:

   int execl(const char *path, const char *arg, ...
                   /* (char  *) NULL */);

GCC is telling you the execl() function is expecting a non-NULL argument.

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
1

Just had a similar problem. I found out that if I specified the full path to my exe (starting with /) neither execlp nor execv passed any argument. And also that I could not output anything to stderr.

Since I only want to replace my current process with a clone version of itself, I save and use the argv[0] of the parent as the 2 first arguments of execlp/v and everything is fine.

piotrpo
  • 12,398
  • 7
  • 42
  • 58
pbouchaud
  • 11
  • 1
-1

The first two parameters of execl() should be the full path and then the process name.

At least that's how I interpreted it here:

Community
  • 1
  • 1
JonCav
  • 1,667
  • 2
  • 11
  • 9
  • 1
    Why don't you use an official documentation link, like [this one `exec(3)`](http://man7.org/linux/man-pages/man3/exec.3.html)? – Iharob Al Asimi Dec 21 '15 at 17:03