I'm trying to make my own shell in unix.
I want to make child process run in background with adding PID to jobList. And when it ends, I want it to delete PID from jobList. But I don't understand how should I know when the child process in background finishes?
int childPid,endPid;
if(addJob(jobs,childPid = fork(),0,"fork()") >= 0){
if(childPid == 0){
printf("Child Process Running...\n");
execl("/bin/sleep","sleep","5",(char*) 0);
deleteJob(jobs,childPid);
exit(0);
}
else if(childPid > 0){
if(!info->bg){
int count=1;
//waitpid(childPid,NULL,0);
while(endPid!=childPid){
sleep(1);
endPid=waitpid(childPid,NULL,WNOHANG);
//printf("%d:%d\n",endPid,childPid);
printf("%d\n",count++);
}
printf("child process ended.\n");
deleteJob(jobs,childPid);
}
else{
printf("child process runs in background.. \n");
//sleep(1);
}
}
}
Related
I'm actually trying to receive serial line message using the UART0 of a CC1310 with Contiki-ng.
I have implemented a uart callback function with will group all the characters received into a single variable, and stop collecting when it receives a "\n" character.
int uart_handler(unsigned char c)
{
if (c == '\n')
{
end_of_string = 1;
index = 0;
}
else
{
received_message_from_uart[index] = c;
index++;
}
return 0;
}
The uart0 is initialised at the main and only process of the system and then it waits in a infinite while loop until the flag end_of_string
PROCESS_THREAD(udp_client_process, ev, data)
{
PROCESS_BEGIN();
uart0_init();
uart0_set_callback(uart_handler);
while (1)
{
//wait for uart message
if (end_of_string == 1 && received_message_from_uart[0] != 0)
{
LOG_INFO("Received mensaje\n");
index = 0;
end_of_string = 0;
// Delete received message from uart
memset(received_message_from_uart, 0, sizeof received_message_from_uart);
}
etimer_set(&timer, 0.1 * CLOCK_SECOND);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timer));
}
PROCESS_END();
}
As you can see, the while loop stops at each iteration with a minimum time timer event. Although this method works, I think it is a bad way to do it, as I have read that there are uart events that can be used, but I have not been able to find anything for the CC1310.
Is it possible to use the CC1310 (or any other simplelink platform) UART with events and stop doing unnecessary iterations until a message has reached the device?
pit_t pid = fork();
if (pid == -1){
abort();
} else if (pid == 0){
printf("this is child before\n");
ptrace(PTRACE_TRACEME);
raise(SIGSTOP);
printf("this is child after\n");
} else {
//waitpid(pid, NULL, WUNTRACED) for without ptrace
waitpid(pid, NULL, 0);
printf("this is parent\n");
}
without the ptrace line, this code works as expected, the second printf in child never gets printed since parent does not send SIGCONT. But with the ptrace line, the second printf in child does get printed. Why does the child continue to execute without receiving SIGCONT?
Thanks
I need to create "n" child processes and they have to sleep a random number of seconds, and the parent process have to advise when any child process has finished. The problem is that each child process runs one after other and I need them to work in parallel. (In the code I'm just creating 3 children.)
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
int main(void)
{
pid_t pid;
int x,zeit,status,w,n=0;
for(x=1;x<=3;x++)
{
pid=fork();
n++;
srand(time(NULL));
if(pid)
{
w=wait(&status);
printf("Process %d finished in %d seconds (Dad:%d cuenta %d)\n",w,WEXITSTATUS(status),getppid(),n);
}
else
{
int n;
zeit=rand()%3+1;
sleep(zeit);
exit(zeit);
}
}
exit(0);
return 0;
}
You're explicitly waiting for each process to finish before you start the next one
for(x=1;x<=3;x++)
{
pid=fork();
n++;
srand(time(NULL));
if(pid)
{
w=wait(&status);
printf("Process %d finished in %d seconds (Dad:%d cuenta %d)\n",
w, WEXITSTATUS(status), getppid(), n);
...
}
If you want them to run in parallel, you're going to have to make 3 different processes, and start them off before you wait for any one of them to finish.
Can someone please tell me what is this code not working ? it always return a DISPATH_VNODE_WRITE while monitoring application documents directory in iOS 6.0. (iPad) Below is my code. It returns 0x2 always no matter a file is deleted or renamed or added :(. Is this because it is a directory that I am monitoring ? not a file !!! is there any way I can find out what caused the directory to send notification ?
int directoryFileDescripter = open([documentDirectory UTF8String], O_EVTONLY);
if (directoryFileDescripter < 0) {
NSLog(#"Couldn't obtain file descripter from the system.");
return;
}
dispatch_queue_t mainQueue = /*dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);*/dispatch_get_main_queue();
if (mainQueue == NULL) {
NSLog(#"Couldn't obtain mainQueue from the system.");
close(directoryFileDescripter);
return;
}
dispSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, directoryFileDescripter, DISPATCH_VNODE_WRITE | DISPATCH_VNODE_DELETE | DISPATCH_VNODE_RENAME, mainQueue);
if (dispSource == NULL) {
NSLog(#"Couldn't obtain dispatch source for directory from the system.");
close(directoryFileDescripter);
return;
}
dispatch_source_set_event_handler(dispSource, ^{
NSLog(#"directory notification received.");
int fileDes = dispatch_source_get_handle(dispSource);
unsigned long mask = dispatch_source_get_data(dispSource);
char path[PATH_MAX] = {0};
int nRes = fcntl(fileDes, F_GETPATH, &path);
if (nRes < 0) {
return;
}
if (mask & DISPATCH_VNODE_WRITE) {
NSLog(#"A file has been written.");
}
if (mask & DISPATCH_VNODE_DELETE) {
NSLog(#"A file has been deleted.");
}
if (mask & DISPATCH_VNODE_RENAME) {
NSLog(#"A file has been renamed.");
}
});
dispatch_source_set_cancel_handler(dispSource, ^{
close(directoryFileDescripter);
});
dispatch_resume(dispSource);
You are correct about the "why." When files are created, renamed, or deleted, the directory is modified. You are watching the directory, so you get a "WRITE" event.
I would typically deal with this by re-scanning the directory each time it is marked as written, and noting the changes yourself. If you're not worried about the directory itself moving or being deleted, you can just watch for WRITE events.
You can of course also watch each file's VNODE, but I expect this would be much more complicated to implement well for this kind of problem.
I have a program where i ssh into a server and gets data. Here is the code... I fork it and the child executes the query and the parent waits for the child for a predetermined amount of time (in function timeout) and then kills the child. I did that part because sometimes, i am not exactly sure why, but the ssh connection stops and doesnot exit. That is there is a "ssh -oConnectTimeout=60 blah blah" in the processes list for a long and the timeout function doesnt seem to work. What am i doing wrong here? The last time this problem occured, there was an ssh in process list for 5 days and still it didnot timeout and the program had stopped because it was waiting for the child. There are those extra wait() functions because previously i was getting a lot of defunct processes a.k.a zombies. So i took the easy way out..
c = fork();
if(c==0) {
close(fd[READ]);
if (dup2(fd[WRITE],STDOUT_FILENO) != -1)
execlp("ssh", "ssh -oConnectTimeout=60", serverDetails.c_str(), NULL);
_exit(1);
}else{
if(timeout(c) == 1){
kill(c,SIGTERM);
waitpid(c, &exitStatus, WNOHANG);
wait(&exitStatus);
return 0;
}
wait(&exitStatus);
}
This is the timeout function.
int timeout(int childPID)
{
int times = 0, max_times = 10, status, rc;
while (times < max_times){
sleep(5);
rc = waitpid(childPID, &status, WNOHANG);
if(rc < 0){
perror("waitpid");
exit(1);
}
if(WIFEXITED(status) || WIFSIGNALED(status)){
/* child exits */
break;
}
times++;
}
if (times >= max_times){
return 1;
}
else return 0;
}
SIGTERM just asks for a polite termination of the process. If it's got stuck, then it won't respond to that, and you'll need to use SIGKILL to kill it. Probably after trying SIGTERM and waiting a little while.
The other possibility is that it's waiting for the output pipe to the parent process to not be full - maybe there's enough output to fill the buffer, and the child is waiting on that rather than the network.