Reputation: 89
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
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
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