You are on page 1of 6

GIDForums > C omputer Programming Forums > C Programming Language

User Name User Name Password

Remember Me? Log in

wait() and waitpid() functions


Register FAQ Members List Calendar Search

Today's Posts

Mark Forums Read

Thread Tools 20-Sep-2006, 10:22

Search this Thread

Rate Thread #1

groberts1980
New Member

Join Date: Sep 2006 Posts: 2

wait() and waitpid() functions

This is my first post here, so hello everybody. I have a question about a C program I'm writing for an Operating Systems class. I basically need to write a little shell that will take commands (ls, ls -l, ./program.c, cat prog.c >text.txt, etc). After fork() is called, I have an if and else to determine whether the parent or child is running. In the parent branch, I need it to wait for the child to finish if the user did not specify the & (background) argument. I'm having trouble figuring out the wait() and waitpid() functions. Here is the a snippet of the code in question:
CPP / C++ / C Code:

cpid = fork(); if(cpid) { //parent if(param.Background == 0) { //use wait function here } } else { //child execvp(param.FirstArg, param.ArgVector); return(0); }

When I run the program, the parent does not wait for the child to complete. In the shell, I'm running a program called slow.c, that prints out the process id of itself 10 times, in one second intervals. Hence the name "slow." When it runs, the prompt for the parent comes right back up, when it should wait for slow to finish before coming back. Any help on this would be most humbly appreciated.
Last edited by LuciWiz : 20-Sep-2006 at 15:15. Reason: Please insert your C/C++ code between [cpp] & [/cpp] tags

Guide to Process Rules


Free 20 page Process Rules Guide. Example Business Rules Included!
www.progress.com

20-Sep-2006, 16:37

#2 Join Date: Feb 2004 Location: Left C oast, USA Posts: 5,764

davekw7x
Outstanding Member Re: wait() and waitpid() functions Quote:

Originally Posted by groberts1980 In the parent branch, I need it to wait for the child to finish

functions in the family execvp(), execl(), execv(), etc., never return unless there was an error. When you invoke execvp() it

converted by Web2PDFConvert.com

replaces the current process image with a new process, whose path is given in the first argument. But, and I hate to repeat myself, it never returns. See footnote. For starters, you could consider:
CPP / C++ / C Code:

#include <stdio.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <stdlib.h> int main() { int i; pid_t cpid; pid_t child_pid; cpid = fork(); switch (cpid) { case -1: printf("Fork failed; cpid == -1\n"); break; case 0: child_pid = getpid(); for (i = 0; i < 10; i++) { printf("%d: this is the child, pid = %d\n", i, child_pid); sleep(1); } exit(0); default: printf("This is the parent: waiting for %d to finish\n", cpid); waitpid(cpid, NULL, 0); printf("Ttttthat's all, folks\n"); } Output: return 0; } C ode: 0: this is the child, pid = This is the parent: waiting 1: this is the child, pid = 2: this is the child, pid = 3: this is the child, pid = 4: this is the child, pid = 5: this is the child, pid = 6: this is the child, pid = 7: this is the child, pid = 8: this is the child, pid = 9: this is the child, pid = Ttttthat's all, folks 3562 for 3562 to finish 3562 3562 3562 3562 3562 3562 3562 3562 3562

I'm not sure exactly what you need, but if you want to put see the "sleep" stuff in a process invoked by the child:
CPP / C++ / C Code:

/* * file slow.c */ #include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { pid_t pid; int i; pid = getpid(); for (i = 0; i < 10; i++) { printf("%d: This is slow --- pid = %d\n", i, pid); sleep(1); } return 0; }

You could, maybe, do something like:

converted by Web2PDFConvert.com

CPP / C++ / C Code:

#include <stdio.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <stdlib.h> int main() { int i; pid_t cpid; pid_t child_pid; cpid = fork(); switch (cpid) { case -1: printf("Fork failed; cpid == -1\n"); break; case 0: child_pid = getpid(); printf("This is the child: pid = %d\n", child_pid); system("./slow"); exit(0); default: printf("This is the parent: waiting for %d to finish\n", cpid); waitpid(cpid, NULL, 0); printf("Ttttthat's all, folks\n"); } return 0; } Output:
C ode:

This is the child: pid = 3838 This is the parent: waiting for 3838 to finish 0: This is slow --- pid = 3839 1: This is slow --- pid = 3839 2: This is slow --- pid = 3839 3: This is slow --- pid = 3839 4: This is slow --- pid = 3839 5: This is slow --- pid = 3839 6: This is slow --- pid = 3839 7: This is slow --- pid = 3839 8: This is slow --- pid = 3839 9: This is slow --- pid = 3839 Ttttthat's all, folks

Results are from Linux Fedora Core 5. Regards, Dave Footnote: "Well, did he ever return? No, he never returned and his fate is still unknown. " Charlie on the MTA ---Jacqueline Steiner and Bess Lomax Sung by the Kingston Trio, 1959 "Was it really 1959??? Sometimes it seems like yesterday. Where does the time go?" ---davekw7x
20-Sep-2006, 17:34 #3 Join Date: Sep 2006 Posts: 2

groberts1980
New Member Re: wait() and waitpid() functions

So because it does not return from execvp, I do not need a return statement? We have to use exec, cannot use system() calls. I'm running it like this, and it still is not waiting. When the program first runs, it takes a line of input and passes it into a function, which fills up the param struct. If the input contains <text.txt, it assigns "param->Input = text.txt". If they put a & argument at the end of the line of input, it sets param->Background = 1. If the parent runs, and does not have to wait for the child (& operator in child), it should go back and print the prompt, waiting for more input.
converted by Web2PDFConvert.com

CPP / C++ / C Code:

cpid = fork(); switch (cpid) { case -1: printf("Fork failed; cpid == -1\n"); break; case 0: //child if(param.Input != NULL) //redirect input { fp = freopen(param.Input,"r",stdin); } if(param.Output != NULL) //redirect output { fp = freopen(param.Output,"w",stdout); } execvp(param.FirstArg, param.ArgVector); break; default: //parent if(param.Background) { waitpid(cpid,NULL,0); } break; }
20-Sep-2006, 18:57 #4 Join Date: Feb 2004 Location: Left C oast, USA Posts: 5,764

davekw7x
Outstanding Member Re: wait() and waitpid() functions Quote:

Originally Posted by groberts1980 So because it does not return from execvp, I do not need a return statement? The only time it returns is if there is an error. Therefore, I would usually expect something like:
CPP / C++ / C Code:

execvp(*args, args); perror(*args); exit(1);


Quote:

Originally Posted by groberts1980 We have to use exec, cannot use system() calls. That was just an illustration, where I used system() instead of the execvp that you had indicated. Playing with simple stuff like this might give you a better feel for the whole forking process. (It does for me.)
Quote:

Originally Posted by groberts1980 When the program first runs, it takes a line of input and passes it into a function, which fills up the param struct.

That sounds OK for starters.


Quote:

Originally Posted by groberts1980 If the input contains <text.txt, it assigns "param->Input = text.txt". If they put a & argument at the end of the line of input, it sets param->Background = 1. If the parent runs, and does not have to wait for the child (& operator in child), it should go back and print the prompt, waiting for more input.

But your problem was when it does have to wait, right? I would think of it like this:

converted by Web2PDFConvert.com

C ode:

loop get line parse line into arguments execute the command end loop

I would think that the big loop would be in main(), and I would have a separate function for parsing, and another function to execute the command after the command line had been parsed into arguments. If you are going to call execvp(), you need the args as an array of pointers to char. I assume that is in your struct, somehow. So the execute() function looks something like the main() from my previous example. Here's an execute() function whose arguments are already in the form you need to call execvp. The child calls exevp() and for this one, the parent always waits for the child to finish. You can easily fix it for the background situation where you don't want to wait.
CPP / C++ / C Code:

/* * execute--spawn a child process and execute the program. */ int execute(char **args) { pid_t cpid; cpid = fork(); switch (cpid) { case -1: perror("fork"); break; /* maybe you want to return something indicating error */ case 0: execvp(*args, args); /* this is the child */ perror(*args); exit(1); /* major system error: fuggedaboudit */ default: waitpid(cpid, NULL, 0); /* TODO: parent shouldn't wait if it's background */ } return 0; /* or whatever value your main() program would like to see */ }

Of course, you might have a parameter that determines whether to wait. (Or, better yet, your parameter might be your struct, and inside the execute() function it would figure out what the arguments to execvp are and whether to wait. There might be more error checking and reporting also. I hope this helps. Regards, Dave

Ads by Google

Ads by Google

BPM Process Function DJ Child

MSSQL Function Process Mapping Cell Function

Previous Thread | Next Thread

Recent GIDBlog
Thread Tools Show Printable Version Email this Page

Windows XP ?You may be a victim of software counterfeiting? by LocalTech


Search this Thread Search this Thread : Go Advanced Search

Rate This Thread Rate This Thread : 5 : Excellent Go

converted by Web2PDFConvert.com

Posting Rules You You You You may may may may not not not not post new threads post replies post attachments edit your posts

vB code is On Smilies are On [IMG] code is On HTML code is Off

Forum Jump C Programming Language Go

Network Sites: GIDNetwork GIDWebHosts GIDSearch Learning Journal by J de Silva, The All times are GMT -6. The time now is 12:17. Contact Us - GIDForums - Archive - Top vBulletin, C opyright 2000 - 2011, Jelsoft Enterprises Ltd.

converted by Web2PDFConvert.com

You might also like