-1

I have a C program. I noticed that you can't put 2 execl's in it.

The code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

int main()

{
      pid_t fork(void);

      int system(const char *command);

      execl("/bin/sh", "sh", "-c", "kdialog --warningcontinuecancel 
      \"Make sure to include: \n \n 1. py_lcd folder \n 2. 4x20 
      Raspberry Pi LCD Display \n 3. Python 2.7.12 to be installed \n 
      \n If you are missing something, kill the program process and 
      get them.\"", (char *) 0);

      sleep(1);

      execl("/bin/sh", "sh", "-c", "kdialog --msgbox \"Setting up files...\" --title \"Installing...\"", (char *) 0);
      return(0);
}

Can someone help me if there is a way to bypass this or if i am making a mistake???

Ivan
  • 3
  • 2
  • If execl succeeds, it does not return. Ever. – Antti Haapala -- Слава Україні Nov 09 '18 at 05:03
  • The code shown doesn't compile. Avoid using backslash to paste lines in a string together. Use string concatenation: adjacent string literals are combined by the compiler into one, so `"abc" "-" "def"` creates a single string `"abc-def"`, even if the three component strings are on different lines, with blank lines or comments in between, and without any need for any backslashes. You can create three lines with `"abc\n" "def\n" "ghi\n"`, for example. – Jonathan Leffler Nov 09 '18 at 05:52
  • 1
    Why do you put the declaration of fork locally? – Lundin Nov 09 '18 at 13:01
  • @Jonathan Leffler What do you mean by "Doesn't compile"? – Ivan Nov 15 '18 at 03:58
  • @Antti Haapala Thanks for the information! I will look into that and see what I can improve! :) – Ivan Nov 15 '18 at 03:59
  • I mean that the string that starts with `"kdialog --warningcontinuecancel` is not correctly continued. You either need a backslash before the newline, or you need a close double quote on the first line and a new open double quote on the second line so that the compiler does 'string concatenation'. The second is by far the better choice. – Jonathan Leffler Nov 15 '18 at 04:00
  • Incidentally, the declaration of `system()` is doubly pointless — it isn't used, and it is declared by ``. And you haven't invoked `fork()` either; you've declared it (and there was no point in that, either, since it is declared in ``). – Jonathan Leffler Nov 15 '18 at 05:06
  • @JonathanLeffler Oh I see! BTW somehow I managed to squeeze in some code after an execl and it ran! – Ivan Dec 11 '18 at 05:25
  • If `execl()` is successful, any code after is is not executed. If `execl()` fails, it returns and the code after it will be executed as normal. I don't completely agree with the accepted answer which says "Anything written after `execl` is dead code". – Jonathan Leffler Dec 11 '18 at 06:07
  • It executed for me, with a correct response. (On a different program though) P.S. about the kdialog thing, it worked perfectly though... don't exactly see a problem – Ivan Dec 12 '18 at 02:45

3 Answers3

4

The exec family of functions don't return when they succeed. They replace the running process with the one being execed. If you want to run a program in a child process (with full control, unlike system), you need to use fork + exec + wait (or perhaps posix_spawn).

hobbs
  • 223,387
  • 19
  • 210
  • 288
  • Ok thanks! I just started C programming and my dad has been showing me around... I have been making a lot of mistakes, but I couldn't solve this one... – Ivan Nov 15 '18 at 04:00
1

Anything written after execl is a deadcode. The main purpose of execl is to re-use the current process information for a new process to improve performance. You will be using sharing the same structures of process information(pid, stack, heap etc.) of the current process where execl is executed.

  • 1
    That's not entirely true. Testing the return value from `execl()` is pointless; it failed if it returned. But if the code does fail to execute the program, you should have code to print an appropriate error (probably) and definitely have code to ensure that the child process terminates on failure. (OK: there might be occasions where you do some other error recovery, but you need to think carefully and you normally do have an exit after the `execl()`.) – Jonathan Leffler Nov 15 '18 at 04:02
  • Which part exactly is not true? I assume it's about deadcode. If it's a single process, execl succeeds and if there is no code to handle error returned by execl then there is no use of putting code after that. – Ishwar Chandra Nov 15 '18 at 05:01
  • 1
    You said "Anything written after `execl()` is dead code"; I'm disagreeing with that observation — and I gave the reasons why (`execl()` can return if it fails (but only if it fails), and then you need code to deal with that error). – Jonathan Leffler Nov 15 '18 at 05:04
0

I found an answer myself. There is a system() command which works the exact same but you are able to insert it anywhere in the code without problems

Ivan
  • 3
  • 2