Can anyone tell me what's wrong with this? I'm still a newbie with forking. The computer executes the 1st and 2nd but the 3rd which is wc doesn't work. Need help badly. The terminal returns multiple child process completed but no wc.
pid_t son;
int i;
for (i=0; i<=3; i++){
switch (i){
case 0:
son = fork();
if (son<0){
fprintf(stderr, "Fork failed!");
//exit(-1);
}else if (son == 0){
execlp("/bin/cat", "cat", "wctrial.txt", NULL);
exit(0);
}else{
wait(NULL);
printf("Child process completed!");
}
case 1:
son = fork();
if (son<0){
fprintf(stderr, "Fork failed!");
//exit(-1);
}else if (son == 0){
execlp("/bin/mkdir", "mkdir", "mydirectory", NULL);
exit(0);
}else{
wait(NULL);
printf("Child process completed!");
}
case 2:
son = fork();
if (son<0){
fprintf(stderr, "Fork failed!");
//exit(-1);
}else if (son == 0){
printf("Work!");
execlp("usr/bin/wc","wc","-w","wctrial.txt", NULL);
exit(0);
}else{
wait(NULL);
printf("Work!");
printf("Child process completed!");
exit(0);
}
}
}
}
Since feature requests to mark a comment as an answer remain declined, I copy the above solution here.
You forgot the leading slash in the path. – Joachim Pileborg
"usr/bin/wc" should be "/usr/bin/wc" – Basile Starynkevitch
Related
Process A should start process B and then terminate. Process B should continue as an independent process
please have a little mercy on me - i am trying to educate myself and i like to learn more
int parallel_thread1;
pthread_t thread1;
static void *performer(void) {
pid_t pid;
pid = fork();
if (pid < 0)
exit(EXIT_FAILURE);
if (pid > 0) // if success then let the parent terminate
exit(EXIT_SUCCESS);
if (setsid() < 0)
exit(EXIT_FAILURE);
pid = fork();
if (pid < 0)
exit(EXIT_FAILURE);
if (pid > 0)
exit(EXIT_SUCCESS);
switch(pid)
{
case -1: // Fork() has failed
perror ("fork");
break;
case 0: // This is processed by the child
system("/home/performerprocess/bin/performer");
exit(EXIT_FAILURE);
break;
default: // This is processed by the parrent
break;
}
return(0);
}
int main(int argc, char *argv[])
{
parallel_thread1 = pthread_create(&thread1, NULL, &performer, NULL);
if(parallel_thread1 == 0)
{
pthread_detach(updateThread);
usleep(500000);
}
...
puts("Process should already be terminated :( I don't want to see this msg");
return 0;
}
please suggest a "clean" solution - thank you very much ;)
I am using pipe fork and exec, to implement a generic pipe for any two shell programs. I am specifically using ls | grep to test it. It works, the data gets copied over to grep, grep searches for matches and then outputs them to stdout. However after that the program just hangs.
This is my code that is executed when a pipe is detected. I fork, and then fork again because I wish to have the parent process of the first fork continue to run after the exec calls. I believe due to debug code that after the exec() call that executes grep is made that nothing is happening.
if(pipeFlag == 1){
pipe(fd);
PID = fork();
if (PID == 0){//child process
fPID = fork();
if(fPID == 0){//child of child
printf("in child of child\n");
dup2(fd[1], 1);
execvp(command, argv);//needs error checking
printf("mysh: %s: command not found\n", argv[0]);
exit(EXIT_FAILURE);
}
if(fPID > 0){//parent of 2nd child
printf("in parent of 2nd child\n");
dup2(fd[0], 0);
execvp(command1, argv1);//needs error checking
printf("mysh: %s: command not found\n", argv[0]);
exit(EXIT_FAILURE);
}
if(PID == -1){
printf("ERROR:\n");
switch (errno){
case EAGAIN:
printf("Cannot fork process: System Process Limit Reached\n");
case ENOMEM:
printf("Cannot fork process: Out of memory\n");
}
return 1;
}
}
if(PID > 0){//parent
wait(PID, 0, 0);
printf("in outer parent\n");
}
if(PID == -1){
printf("ERROR:\n");
switch (errno){
case EAGAIN:
printf("Cannot fork process: System Process Limit Reached\n");
case ENOMEM:
printf("Cannot fork process: Out of memory\n");
}
return 1;
}
}
Below is my solution to the problem. I'm not sure if it's a permanent solution. I'm not even 100% sure if my reasoning for why this works and the previous code did not isn't. All I did was switch the command that is waiting for input from the pipe(grep) to the parent process, and the command writing output to the pipe(ls) to the child process.
My reasoning for why this works is thus: I was testing with ls | grep, ls was finished writing to the pipe before grep's child process ever got set up, and therefore never closed the pipe and grep never received EOF. By changing their position grep was ready and waiting for ls to write by the time the process running ls is set up. I believe that this is a very imperfect fix, so for anyone who reads this in the future, I hope you can provide a better answer. There are a number of conditions I can think of where this could still mess up, if my reasoning for why it works is correct.
if(pipeFlag == 1){
pipe(fd);
PID = fork();
if (PID == 0){//child process
fPID = fork();
if(fPID == 0){//child of child
printf("in child of child\n");
dup2(fd[0], 0);
execvp(command1, argv1);//needs error checking
printf("mysh: %s: command not found\n", argv[0]);
exit(EXIT_FAILURE);
}
if(fPID > 0){//parent of 2nd child
printf("in parent of 2nd child\n");
dup2(fd[1], 1);
execvp(command, argv);//needs error checking
printf("mysh: %s: command not found\n", argv[0]);
exit(EXIT_FAILURE);
}
if(PID == -1){
printf("ERROR:\n");
switch (errno){
case EAGAIN:
printf("Cannot fork process: System Process Limit Reached\n");
case ENOMEM:
printf("Cannot fork process: Out of memory\n");
}
return 1;
}
}
if(PID > 0){//parent
wait(PID, 0, 0);
printf("in outer parent\n");
}
if(PID == -1){
printf("ERROR:\n");
switch (errno){
case EAGAIN:
printf("Cannot fork process: System Process Limit Reached\n");
case ENOMEM:
printf("Cannot fork process: Out of memory\n");
}
return 1;
}
}
I'm currently having a problem with the third process because it wont work every time when I run the program. And suggestions with the exit() part because is printing multiple child process! Any suggestions?
I would really APPRECIATE it a lot!
main(){
pid_t son;
int i;
for (i=0; i<3; i++){
switch (i){
case 0:
son = fork();
if (son<0){
fprintf(stderr, "Fork failed!");
//exit(-1);
}else if (son == 0){
execlp("/bin/cat", "cat", "wctrial.txt", NULL);
}else{
wait(NULL);
printf("Child process completed!");
//exit(0);
}
case 1:
son = fork();
if (son<0){
fprintf(stderr, "Fork failed!");
//exit(-1);
}else if (son == 0){
execlp("/bin/mkdir", "mkdir", "mydirectory", NULL);
}else{
wait(NULL);
printf("Child process completed!");
//exit(0);
}
case 2:
son = fork();
if (son<0){
fprintf(stderr, "Fork failed!");
//exit(-1);
}else if (son == 0){
execlp("/bin/wc","wc","wctrial.txt", NULL);
}else{
wait(NULL);
printf("Child process completed!");
//exit(0);
}
}
}
At least I don't see the break at the end of the each case.
In the case of 0 the program will run through all of your cases.
Actually break is the problem that if case 1 execute then 2,3 also will.(but this is not problem that wc not working)
Why wc is not working ?
Because of path of wc command!
In your system path for wc may not is: "/bin/wc"
Search tha path of wc command in your system like:
:~$ whereis wc
wc: /usr/bin/wc
and change
execlp("/bin/wc","wc","wctrial.txt", NULL);
^
as
execlp("/usr/bin/wc","wc","wctrial.txt", NULL);
^
// actually not exactly this but one that appears in your system.
Give it a try!!
Below are my suggestion ,
1st) suggestion would be the clean-up of child process once it is
done, as below,
}else if (son == 0){
execlp("/bin/mkdir", "mkdir", "mydirectory", NULL);
_exit(0);
}
2nd) do break after each switch statement
3rd) and also validate the path of executable by using "whereis"
command before feeding into execlp routine.
I need some help here. I need to execute all three execlp() once I run the program but what happen is that only case 0 is executed.I changed pid to 1 and case1 gets executed and so on. Tried putting it in a for loop but does not work. I changed break to continue but still the same - only one process is executed. Any suggestions?
main(){
pid_t pid;
pid= fork();
int i;
if(pid==0){
for (i=0; i<3; i++){
switch (i){
case 0:
execlp("/bin/cat", "cat", "wctrial.txt", NULL);
break;
case 1:
execlp("/bin/mkdir", "mkdir", "mydirectory", NULL);
break;
case 2:
execlp("/bin/wc", "wctrial.txt", NULL);
break;
}
}
}else{
wait(NULL);
printf("Child process completed!");
exit(0);
}
}
According to man execlp:
The exec() family of functions replaces the current process image with a new process image.
(emphasis is mine)
Therefore, once you called successfully execlp, the process doesn't re-execute the old code.
case 0:
execlp("/bin/cat", "cat", "wctrial.txt", NULL);
/* shouldn't go here */
break;
If you want to execute the three programs, you can create three processes. For instance (loops unrolled):
pid_t son;
son = fork();
if (son == -1) /* report */
else if (son == 0) execlp("/bin/cat", "cat", "wctrial.txt", NULL);
else wait(NULL);
son = fork();
if (son == -1) /* report */
else if (son == 0) execlp("/bin/mkdir", "mkdir", "mydirectory", NULL);
else wait(NULL);
/* ... */
See also Kirilenko's answer. The solution is to use system(..) instead of execlp(..).
Man page here.
How can I have 3 processes running in parallel? Is this solution below correct?
In my solution I put some code to see the time elapsed and I think this is tunning in sequential mode. I need to put pid1, pid2 and pid3 running at the same time.
pid = fork();
if(pid == 0) {
//code...
exit(EXIT_SUCCESS);
} else if(pid > 0) {
pid1 = fork();
if(pid1 == 0) {
//pid1 code...
exit(EXIT_SUCCESS);
} else if(pid1 > 0) {
waitpid(pid1, &status, 0);
} else {
printf("Fork error %d.\n", errno);
}
pid2 = fork();
if(pid2 == 0) {
//pid2 code...
exit(EXIT_SUCCESS);
} else if(pid2 > 0) {
waitpid(pid2, &status, 0);
} else {
printf("Fork error %d.\n", errno);
}
pid3 = fork();
if(pid3 == 0) {
//pid3 code...
exit(EXIT_SUCCESS);
} else if(pid3 > 0) {
waitpid(pid3, &status, 0);
} else {
printf("Fork error %d.\n", errno);
}
waitpid(pid, &status, 0);
}
You keep waiting for one child to complete before you launch the next. Try something like:
for (int i = 0; i < 3; ++i)
{
pid = fork();
if (pid < 0)
error
if (pid == 0)
{
child does thing
exit
}
}
for (int i = 0; i < 3; ++i)
{
wait(&status);
}
EDIT
So just change your code to something like this and wait at the end.
if (pid2 == 0)
{
//pid2 code...
exit(EXIT_SUCCESS);
}
else
if (pid2 < 0)
{
printf("Fork error %d.\n", errno);
}
//....same outline for 3, etc.
Check out my wrap program, specifically the code for wrapc. It forks itself twice, execs one child into wrap, reads, writes to wrap, then reads back in the other child.
Your question is somewhat vague -- are you seeing 3 processes running in parallel or not?
the way your code is written you are exiting the child processes straight away.