Praveen Sundar
Praveen Sundar

Reputation: 89

execl() in child process doesn't end

I wrote a simple program to understand the concept of execl(). Here is my program

#include<stdio.h>
#include<unistd.h>

int main()
{
    pid_t pid;
    pid = fork();
    if(pid == 0)
    {
        execl("/bin/sh","sh","-c","ls -l *.c", NULL);
    }
}

When I execute it, it displays the list of files that have extension ".c". But, it seems that the child process doesn't end and the cursor keeps blinking.

srico@ubuntu:~/Desktop/c$ -rw-rw-r-- 1 srico srico   84 Jun 30 08:30 cmdacc.c
-rw-rw-r-- 1 srico srico  138 Jul  4 11:08 execfun.c
-rw-rw-r-- 1 srico srico  343 Jul  4 10:27 execvp1.c
-rw-rw-r-- 1 srico srico  167 Jun 23 08:20 filechar.c
-rw-rw-r-- 1 srico srico  195 Jun 23 11:20 fileline.c
-rw-rw-r-- 1 srico srico  203 Jun 27 07:17 filestat.c
-rw-rw-r-- 1 srico srico  112 Jun 22 11:11 new.c
-rw-rw-r-- 1 srico srico  304 Jun 27 12:09 parchild1.c
-rw-rw-r-- 1 srico srico 1038 Jun 27 10:56 parchld.c

I have to manually kill the process using ctrl+c.

^C
srico@ubuntu:~/Desktop/c$

please help me correct the mistake.

Upvotes: 3

Views: 4339

Answers (2)

Joni
Joni

Reputation: 111369

What happens is that the parent process exits before the child, and the shell writes the prompt before the child writes its output. When you press control-c the child process has already exited, and the shell rewrites the prompt instead. You could hit enter for the same effect.

To fix this problem you could make the parent process wait until the child exits, using the wait function:

if (pid == 0) {
    execl("/bin/sh", "sh", "-c", "ls -l *.c", NULL);
} else if (pid > 0) {
    wait(NULL); /* wait for child */
} else {
    /* it was not possible to create child process, so print error message */
    perror("fork failed");
}

If you had launched several child processes and you are interested in waiting for the results of a specific one you would use waitpid instead of wait, but in this case I prefer wait for simplicity.

Upvotes: 6

Dayal rai
Dayal rai

Reputation: 6606

The parent process needs to wait for the completion of the child, so you need to call waitpid() as shown below. The rest of the code is for better error handling.

int status;
pid = fork();
if (pid == 0)
{
    /* child process.  shell command execution. */
    execl("/bin/sh", "sh", "-c", "ls -l *.c", NULL);
    _exit(EXIT_FAILURE);
}
else if (pid < 0)
    /* The fork failed.*/
    status = -1;
else
    /* parent process.  Wait for child to complete.  */
    if (waitpid(pid, &status, 0) != pid)
        status = -1;
return status;

Upvotes: 3

Related Questions