I am trying to run a program in C for x minutes. I need to make the child process go to sleep for that amount of time. Any help would be appreciated. Basically I am trying to understand how fork() and sleep() work. Here is my code snippet
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int i = fork();
printf("fork return value = %d\n", i);
printf("this is the time before sleep");
system("date +%a%b%d-%H:%M:%S");
printf("\n");
if (i==0){
sleep(120);
}
system("ps");
printf("this is the time after sleep");
system("date +%a%b%d-%H:%M:%S");
printf("\n");
}
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid;
int rv=1;
switch(pid = fork()) {
case -1:
perror("fork"); /* something went wrong */
exit(1); /* parent exits */
case 0:
printf(" CHILD: This is the child process!\n");
printf(" CHILD: My PID is %d\n", getpid());
printf(" CHILD: My parent's PID is %d\n", getppid());
printf(" CHILD: I'm going to wait for 30 seconds \n");
sleep(30);
printf(" CHILD: I'm outta here!\n");
exit(rv);
default:
printf("PARENT: This is the parent process!\n");
printf("PARENT: My PID is %d\n", getpid());
printf("PARENT: My child's PID is %d\n", pid);
printf("PARENT: I'm now waiting for my child to exit()...\n");
wait(&rv);
printf("PARENT: I'm outta here!\n");
}
return 0;
}
Say thanks to Brian "Beej Jorgensen" Hall
Related
I am trying to code a toy process manager and was wondering how do I find the grandchild pids when one of my children pids dies. I.e. how to deal with the "Readiness protocol".
systemd has the "Type=forking" option, which as far as I understand, waits for the forked pid to die and then assumes that one of the forked pid's children is the actual "daemon" to monitor.
My code so far is as following, but I am missing the XXX
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/prctl.h>
int
main (int argc, const char *argv[])
{
printf("sup stared\n");
int pid;
prctl(PR_SET_CHILD_SUBREAPER);
pid = fork();
if (pid == 0) {
setpgid(0, 0);
printf("service started, pid: %d, pgid: %d\n",
getpid(), getpgid(0));
int dpid;
dpid = fork();
if (dpid == 0) {
printf("daemon started, pid: %d, pgid: %d\n",
getpid(), getpgid(0));
while (1);
}
printf("service exiting\n");
return 0;
} else {
printf("service pid: %d\n", pid);
int rc;
rc = waitpid(pid, NULL, 0);
printf("service exited? %d\n", rc);
int dpid;
dpid = XXcX();
printf("daemon, %d\n", dpid);
}
return 0;
}
I want to fork and exec several processes from another.
My parent code is
/*Daddy.c*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(void)
{
int status;
char *nChild;
for (int i=0; i<3;i++){
int pid = fork();
if (pid == 0)
{
sprintf(nChild, "%d", i);
printf("%d\n", i);
char *const arguments[]={nChild, NULL};
fflush(NULL);
execv("child",arguments);
printf("\nNo , you can't print!\n");
}else if (pid == -1){
printf("%d\n", getpid());
exit(0);
}
}
wait(&status);
printf("Dad %d went out!\n", getpid());
exit(0);
}
and my child process is
/*child.c*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int args, char **argv){
if( args !=2){
printf("Child going away!\n");
exit(1);
}
printf("Child %s: %d going away stylishly!\n", argv[1], getpid());
exit(0);
}
When I don´t create three forks, but one, I know how to create the child, do some work and exit from child and parent. But, in this case, with several children it seems like the child never executes.
Because of the line wait(&status) I did hope that when the first child exits, the parent also exits but, any child prints any message.
Some relevant previous questions didn´t help.
You need to make parent wait for all child processes to finish. If not, assume that 1 child waited for is done and then parent exits. What about the other 2 children? They become orphan since their parent doesn't wait for them.
pid_t wpid;
int status = 0;
.
.
while ((wpid = wait(&status)) > 0); // the parent waits for all the child processes
This code did the job
/* daddy.c */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
int main(void)
{
int status=0;
char nChild[16];
pid_t wpid;
for (int i=0; i<3;i++){
sprintf(nChild, "%d", i);
int pid = fork();
if (pid == 0)
{
printf("%s\n", nChild);
char *const arguments[]={"child", nChild, NULL};
fflush(NULL);
execv("child",arguments);
printf("\nNo , you can't print!\n");
}else if (pid == -1){
printf("%d\n", getpid());
exit(0);
}
}
while ((wpid=wait(&status)) >0);
printf("Dad %d went out!\n", getpid());
exit(0);
}
As #OnzOg said in the comments of the question, allocation of nChild was the main problem. Also execv need pass child name twice, one as argument.
And finally, to improve the code, parent process needs to wait all processes to finish.
I have two cods the first one is for the parent which sends a signal (SIGUSER1) to the child and when the child receive it he should print that he received it.
Parent code
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/types.h>
void sighand(int);
int main()
{
int cpid, ppid;
ppid = getpid();
printf("My process ID is %d\n", ppid);
FILE *fp1;
fp1 = fopen("cpid.txt", "w+");
cpid = fork();
if ( cpid == 0 ) {
printf("I am the child => PID = %d\n", getpid());
}
else
printf("I am the parent => PID = %d, child ID = %d\n", getpid(), cpid);
fprintf(fp1, "%d\n", cpid);
// kill(cpid, SIGUSR1);//id, signal, send
sigset(SIGUSR2, sighand);
return 0;
}
void sighand(int the_sig){
if (the_sig == SIGUSR2){
printf("sigusr2 received");
exit(1);
}
}
Child code
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/types.h>
void sighand1(int);
int main()
{
FILE *fp1;
int pid;
fp1 = fopen("cpid.txt", "r");
fscanf(fp1, "%d,", &pid);
sigset(SIGUSR1,sighand1);
while(1) {
printf("Waiting..");
sigpause(SIGUSR1);
}
return 0;
}
void sighand1(int the_sig)
{
if (the_sig == SIGUSR1){
printf("sigusr1 received");
exit(1);
}
}
When I start the code it prints that the process (child) was created then when I send a signal it wont do any thing the child stuck in a loop or the wait and the parent wont do anything can any one tell me where did i go wrong in my code or logic.
Your code has several problems:
You try to pass some pid through a file, but you can use the getppid() function (get parent id)
You have some child code, but it is not called
no signal is launched
So your code can be corrected this way:
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
void parent_handler(int the_sig)
{
if (the_sig == SIGUSR2){
printf("sigusr2 received in parent\n");
}
}
void child_handler(int the_sig)
{
if (the_sig == SIGUSR1){
printf("sigusr1 received in child\n");
kill(getppid(), SIGUSR2);
exit(1);
}
}
int child_function()
{
/* prepare to receive signal */
sigset(SIGUSR1,child_handler);
while(1) {
printf("Waiting..");
fflush(stdout);
/* wait for signal */
sigpause(SIGUSR1);
}
return 0;
}
int main()
{
int cpid, ppid;
ppid = getpid();
printf("My process ID is %d\n", ppid);
cpid = fork();
if ( cpid == 0 ) {
printf("I am the child => PID = %d\n", getpid());
child_function();
return 0;
}
else
printf("I am the parent => PID = %d, child ID = %d\n", getpid(), cpid);
/* child will never reach this point */
sleep(1);
/* prepare parent to received signal */
sigset(SIGUSR2, parent_handler);
/* send signal to child */
kill(cpid, SIGUSR1);
sleep(1);
return 0;
}
My program have to create n childs. When a signal is recieved a child is created. Then the first child wait for the others n-1 childs. The second one wait for the other n-2 childs and so on until the last child run and finish immediately.
I write this code, but it don't work and i get nephews.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
void func(int sign)
{
printf("received signal. I create a child\n");
}
int main(int argc, char*argv[])
{
if(argc!=3)
{
printf("error\n");
return 0;
}
int i,pid,status;
int n=atoi(argv[1]);
unsigned int m=(unsigned int)atoi(argv[2]);
signal(SIGALRM,func);
printf("i'm father: pid %d\n",getpid());
for(i=0; i<n; i++)
{
alarm(m);
pause();
switch(pid=fork())
{
case -1:
printf("error\n");
break;
case 0:
printf("i'm the hild numer %d, my pid is %d\n",i,getpid());
if(i!=n-1)
{
wait(NULL);
break;
}
else
{
printf("%d i have fnished\n",getpid());
exit(0);
}
break;
default:
wait(NULL);
break;
}
}
printf("finish\n");
return 0;
}
The way your code is structured, you are creating 2^N processes.
You need to change the code under:
default:
wait(NULL);
break;
to something that does not fork any more children after that. One way to do that is using a goto statement. Here's an updated version.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
void func(int sign)
{
printf("received signal. I create a child\n");
}
int main(int argc, char*argv[])
{
if(argc!=3)
{
printf("error\n");
return 0;
}
int i,pid,status;
int n=atoi(argv[1]);
unsigned int m=(unsigned int)atoi(argv[2]);
signal(SIGALRM,func);
printf("i'm father: pid %d\n",getpid());
for(i=0; i<n; i++)
{
alarm(m);
pause();
switch(pid=fork())
{
case -1:
printf("error\n");
break;
case 0:
printf("i'm the child numer %d, my pid is %d\n",i,getpid());
if(i!=n-1)
{
wait(NULL);
break;
}
else
{
printf("%d i have fnished\n",getpid());
exit(0);
}
break;
default:
wait(NULL);
goto done;
}
}
done:
printf("%d i have fnished\n",getpid());
return 0;
}
I need your help in an exercise i have about signal handling between processes. I think that it's a trivial question but i can't find the answer anywhere. I want to print something from the parent in a file, send a signal from the parent to the child, the child has to print in a file and then send a signal from the child to the parent.
The code i am using is this:
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#define WRITEF 123451 //Random number
FILE *infile;
void writef() {
fprintf(infile, "Child Starting (%d)\n", getpid());
printf("Child Starting (%d)\n", getpid());
}
int main() {
pid_t pid;
infile = fopen("pid_log.txt","w");
pid = fork();
signal(WRITEF, writef);
if ( pid == 0 ) {
pause();
printf("enter child\n");
}
else {
fprintf(infile, "Parent (%d)\n", getpid());
printf("Parent (%d)\n", getpid());
kill(pid, WRITEF);
pause();
wait((int*)1);
}
fclose(infile);
return 1;
}
PROBLEM SOLVED!!!
The key is that you have to register the signal (use the singal function) before every pause(). Also you cannot use a "user-made" signal and in my case i used SIGCONT.
Here is the final (almost) version of my program:
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
FILE *infile;
void noth() {
}
void writec() {
infile = fopen("pid_log.txt","a+");
fprintf(infile, "Child (%d)\n", getpid());
printf("Child (%d)\n", getpid());
fclose(infile);
}
void writep() {
infile = fopen("pid_log.txt","a+");
fprintf(infile, "Parent (%d)\n", getpid());
printf("Parent (%d)\n", getpid());
fclose(infile);
}
main() {
pid_t pid = fork();
if ( pid == 0 ) { //child process
signal(SIGCONT,noth); //registering signal before pause()
pause();
infile = fopen("pid_log.txt","a+");
printf("Child Starting (%d)\n",getpid());
fprintf(infile,"Child Starting (%d)\n",getpid());
fclose(infile);
while (1) {
sleep(2);
kill(getppid(), SIGCONT); //sending singal to parent
signal(SIGCONT, writec);
pause();
}
}
else { //parent process
infile = fopen("pid_log.txt","a+");
printf("Parent Starting (%d)\n",getpid());
fprintf(infile,"Parent Starting (%d)\n",getpid());
fclose(infile);
kill(pid, SIGCONT);
signal(SIGCONT, writep);
pause();
while (1) {
sleep(2);
kill(pid, SIGCONT);
signal(SIGCONT, writep);
pause();
}
}
return 1;
}