-1

New to C. So I have a program called test.c (doesnt need any arguments to start, compiled like this " gcc test.c -o test") I want to make my other program execute test I know I have to use execl but I just cant understand the arguments in the execl function

execl( code here )

Ventura
  • 97
  • 12
  • 2
    The args are explained in the [Docs](https://linux.die.net/man/3/execl). If this doesn't help please be __specific__ which part you don't understand. – tkausl Nov 11 '18 at 01:55
  • its the syntaxe in writing the arguments – Ventura Nov 11 '18 at 01:58

1 Answers1

1

All the arguments to execle() except the last two are strings — the penultimate one is a null char * marking the end of the command line arguments, and the last is a char ** specifying the environment. The first is the pathname of the executable, relative to the current directory if the name does not start with a / slash. The second argument is the name of the program. Subsequent arguments are the extra arguments for the program (the list is terminated by a (char *)0 argument) and then there's a final argument that is the environment for the program (the trailing e indicates that the environment is passed). Hence, for example:

extern char **environ;    // No header declares this!

execle("teste", "pink elephants", (char *)0, environ);

You could use "teste" or "/bin/bash" in place of "pink elephants", depending on your tastes. Only two of the three program name options suggested are outright fibs. If you replace the environ argument with (char **)0 or equivalent, then the program is invoked with no environment variables, which is usually regarded as an abuse of the program that's run (rather like telling it that it's name is "pink elephants" rather than "teste" is an abuse of it).

You could use variables too:

const char *progname = "teste";

execle(progname, progname, (char *)0, environ);

Ended up using execlp and just writing execlp("./teste",NULL,NULL); only solution that worked.

It's impressive how many (small) problems there can be in a single simple line of code. Using execlp("./teste", NULL, NULL); is dubious on at least these counts:

  1. You've not provided the executed program with its name, which is discourteous at best and leads to unhelpful error reports, etc.
  2. The first NULL is sufficient if you're not going to provide a name; the second is never processed.
  3. Using "./teste" means that the p (path search) part of execlp() is never exercised; you might as well have used execle("./teste", (char *)NULL, environ);.
  4. It's not impossible for NULL not to translate to (char *)0 in a variable argument list like with execle(). It's not a very likely problem, but #define NULL 0 is legitimate, and if sizeof(int) == 4 but sizeof(char *) == 8, then you could have difficulties.

Aside: you'll probably find the execv*() functions more useful in general than the execl*() functions. At least, my experience is that the variable length argument list is more often needed by the programs I run than a fixed length list.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Ended up using execlp and just writting execlp './teste",NULL,NULL' only solution that worked – Ventura Nov 11 '18 at 02:17
  • Using `execlp("./teste", NULL, NULL);` is dubious on at least three counts: (1) You've not provided the executed program with its name, which is discourteous at best and leads to unhelpful error reports, etc, and (2) the first NULL is sufficient if you're not going to provide a name; the second is never processed, and (3) using `"./teste"` means that the `p` (path search) part of `execlp()` is never exercised; you might as well have use `execle("./teste", (char *)NULL);` — and (4) it's not impossible for NULL not to translate to `(char *)0` in a variable argument list like with `execle()`. – Jonathan Leffler Nov 11 '18 at 02:22
  • `execle("./teste", (char *) NULL);` actually didnt work – Ventura Nov 11 '18 at 02:30
  • 1
    @Ventura: Yes, it wouldn't; I forgot that the `e` in `execle()` means 'environment is passed' and `execle("./teste", (char *)NULL);` doesn't provide the environment. **My bad — I'm sorry**. I've fixed the answer. However, using `execlp()` is pointless when there's a slash in the string in the first argument — the program name. The PATH is never searched then. POSIX gives the synopsis: `int execle(const char *path, const char *arg0, ... /*, (char *)0, char *const envp[]*/);` for the function. Note the use of `(char *)0` explicitly. – Jonathan Leffler Nov 11 '18 at 02:33
  • So what would you say its the best approach to solve this problem knowing that this teste.c is in only one directory The path should be something like `/directory/test.c` – Ventura Nov 11 '18 at 02:42
  • Are you running the command from the same directory? If so, then you can use: `execl("teste", "teste", (char *)0);` or `execle("teste", "teste", (char *)0, environ);` with no problems, and `execle("teste", "teste", (char *)0, (char **)0);` with limited problems. In each case, you could replace the first (or second) argument with `"./teste"` with a clear conscience. While you can use `execlp("./teste", "teste", (char *)0);`, it isn't very clean. If the current directory isn't on your path, the `./` is needed, but the `/` means that the path is ignored. You could use an absolute pathname too. – Jonathan Leffler Nov 11 '18 at 02:46
  • If you're not (necessarily) running from the same directory as where `teste` is found, then you either need to install `teste` in a directory that is in your PATH (`$HOME/bin` is a good candidate), or you need to generate and use the absolute pathname for `teste` — perhaps `execl("/home/you/tmp/teste", "teste", (char *)0);` or some suitable variant. The options are legion! (Also, note that it doesn't matter where the source file `test.c` is; all that matters is where the executable, `teste` is. And it is easier to work if a single-file C program named `xyz` has `xyz.c` as the source file.) – Jonathan Leffler Nov 11 '18 at 02:48
  • Took the first suggestion since the files are all in the same directory Thank you again, and about the executable having the same name as the source file, it was a miss click, already edited the post – Ventura Nov 11 '18 at 02:54
  • Ah — and now we go into the other disquisition about how `test` is a built-in to the shell, so your `test` program won't be executed unless you use `./test` or `/path/to/test` to execute it because if you write `test a = c` in the shell, it will execute the built-in silently, returning a non-zero (false) status — yes, shell exit statuses use zero for success and non-zero for failure; experiment with the `true`, `false` commands and `echo $?` to see the return value (exit status) or the prior command. The `test` built-in is also known as `[`; you can often find both executables on disk too. – Jonathan Leffler Nov 11 '18 at 02:58
  • In short, **don't call your test programs `test`** — you _will_ get confused, sooner or later. – Jonathan Leffler Nov 11 '18 at 02:59