Blocked process in c - c

I am working on some code to create a process that goes blocked and then ends, I have to be able to see the blocked state with ps.
I tried with this, but my C knowledge is not good. The code doesn't print anything.
Here it is:
#include <stdio.h>
#include <stdlib.h> //exit();
#include <unistd.h> //sleep();
int main(int argc, char *argv[]) {
createblocked();
}
int pid;
int i;
int estado;
void createblocked() {
pid = fork();
switch( pid ) {
case -1: // pid -1 error ocurred
perror("error\n");
break;
case 0: // pid 0 means its the child process
sleep(); // we put the child to sleep so the parent will be blocked.
printf("child sleeping...");
break;
default: // !=0 parent process
// wait function puts parent to wait for the child
// the child is sleeping so the parent will be blocked
wait( estado );
printf("parent waiting...\n");
printf("Child terminated.\n");
break;
}
exit(0);
}
It should be easy because its only a little program that goes blocked, but I am walking in circles I think. Any advice?

sleep() takes a parameter: the number of seconds to sleep. When you omit it, it tends to return immediately.
Also wait() takes an int *, not an int.
try this:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
createblocked();
}
int pid;
int i;
int estado;
void createblocked() {
pid = fork();
switch(pid)
{
case -1: // pid -1 error ocurred
perror("error\n");
break;
case 0: // pid 0 means its the child process
printf("child sleeping...\n");
sleep(500); // we put the child to sleep so the parent will be blocked.
break;
default: // !=0 parent process
// wait function puts parent to wait for the child
// thechild is sleeping so the parent will be blocked
printf("parent waiting...\n");
wait(&estado);
printf("Child terminated.\n");
break;
}
exit(0);
}
note: I also moved the printf("parent waiting...\n") above the call to wait(), so you should see it before the parent blocks waiting on the child.
edit: Also, include <unistd.h>. While not strictly required in order for the program to work (on most systems), doing so will give you better compile-time error reporting for things like missing and/or incorrectly-typed function arguments.

man sleep
man wait
You should give the number of seconds as an argument in sleep().
For wait and sleep include <unistd.h>

Related

Continue output after parent child termination , i am unable to perform the operation

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
static void sigusr(int iSig) //SIGUSER are the user defined signals
{
if (iSig == SIGUSR1)
{
printf("Received SIGUSR1 signal, going to sleep for 2 seconds\n");
sleep(2);
}
}
int main ()
{
int pid;
signal(SIGUSR1, sigusr);
pid = fork();
if (pid > 0) //Parent process created
{
for(int i=0; i<=1000;i++)
{
printf("%d\n",i);
usleep(70);
}
}
else //Child process created
{
sleep(5);
kill(pid,SIGUSR1);
exit(0);
}
}
Create 2 processes, a parent and a child using fork().
The parent prints the value of ‘i’ from 0 to 1000 and then exits.
Meanwhile the child process sleeps for 5 seconds after it is created,
sends a SIGUSR1 signal to the parent and then exits.
The parent should catch that signal, print on standard output “Received SIGUSR1 signal,
going to sleep for 2 seconds”, sleep for two seconds and then continueprinting the numbers.
But i am unable to continue the process after child process termination.
For me everything works fine if I increase usleep time, without it parent process terminates before child process send signal.
The problem is with kill call, else statement is executed only in child process, so it means that pid value is 0, kill with pid 0 sends signal to whole group, in this case to parent and a child, you should change it to
kill(getppid(), SIGUSR1);
In addition to the #complikator 's answer, you shoudl print and sleep outside the signal handler.
There are remaining questions like "main finishes before the signal is received", but this is really depending on you use case...
would look like this:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
volatile static bool called = false;
static void sigusr(int iSig)
{
called = true;
}
void check_signaled(void) {
if (called) {
called = false;
printf("Received SIGUSR1 signal, going to sleep for 2 seconds\n");
sleep(2);
}
}
int main(void)
{
int pid;
pid = fork();
if (pid > 0) //Parent process created
{
signal(SIGUSR1, sigusr);
for(int i=0; i<=1000;i++)
{
check_signaled(); /* if signal come while iterating */
printf("%d\n",i);
usleep(70);
}
wait(NULL); /* wait child completion */
check_signaled(); /* signal may happen "too late" */
}
else //Child process created
{
sleep(1);
kill(getppid(),SIGUSR1);
}
}

Child processes with fork

I am trying to make a simple C program that will call the fork method three times and display identifiers of child processes (UID, GID, PID, PPID, PGID). And I am struggling with proper understanding what is really happening. There is my code in which I use separate methods for method fork() and for displaying identifiers, and also in for for parent process I am trying to use the waitpid method to wait for all child processes to die. I am really confused now because I cannot get it working in a way that clearly says it works in proper way. Can you give me any suggestions or show a better way for my problem?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
void identifiers();
void forkMethod();
int main(void)
{
forkMethod();
return 0;
}
void forkMethod()
{
int k;
int status;
for (k=0;k<3;k++){
switch (fork()) {
case -1:
perror("fork error");
exit(EXIT_FAILURE);
break;
case 0:
identifiers();
break;
default:
//wait(&status);
waitpid(getpid(), &status, WNOHANG);
sleep(1);
break;
}
}
}
void identifiers()
{
pid_t pid = getpid();
pid_t ppid = getppid();
pid_t pgid = getpgid(pid);
pid_t uid = getuid();
pid_t gid = getgid();
printf("UID:%d GID:%d PID:%d PPID:%d PGID:%d\n", uid, gid, pid, ppid, pgid);
}
// ===========================================================
First thank you all for answers and pointing all of these mistakes I made,
I know the code is horrible and probably still have a few issues but now i think i have what i wanted to.
As #John Bollinger ask what is main functionality that is my list:
1. Write a function that displays identifiers UID, GUID, PID, PPID, PGID for specified process
2. call fork() function 3 times and display these identifiers for child processes
3. Use the sleep function to display processes in order from the oldest
4. display a processes tree based on results.
Thank you #juhist and #Jonathan Leffler for sharp and simple explanation. If there any significant issues in code please post
and know the final code is:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
void identifiers(); // function that display identifiers
void forkMethod(); // function that calls fork() function 3 times
void tree(int); // function displaying processes tree
int main(void)
{
identifiers(); // displaying ID's for parent process
printf("Parent pid: %d\n", getpid());
printf("Child processes: \n");
forkMethod();
return 0;
}
void forkMethod()
{
int k;
int status;
int pid;
for (k=0;k<3;k++){
pid = fork();
switch (pid) {
case -1:
perror("fork error");
exit(EXIT_FAILURE);
break;
case 0:
identifiers();
exit(0);
default:
tree(getpid());
wait(&status);
sleep(1);
break;
}
}
}
void identifiers()
{
pid_t pid = getpid();
pid_t ppid = getppid();
pid_t pgid = getpgid(pid);
pid_t uid = getuid();
pid_t gid = getgid();
printf("\nUID:%d GID:%d PID:%d PPID:%d PGID:%d\n", uid, gid, pid, ppid, pgid);
}
void tree(int pid)
{
char pstree[] = "pstree -np ";
char cmd[12];
sprintf(cmd, "%s%d", pstree, pid);
system(cmd);
}
One of your problems is in this code:
case 0:
identifiers();
break;
Surely you meant to do this instead:
case 0:
identifiers();
exit(0);
Otherwise the child process will continue execution and you will get too many forks.
The other problem is that you're calling waitpid() with the parent pid, not the child pid. The calls does nothing useful as you're using the WNOHANG argument. Either use wait() or store the pid of the child as returned by fork somewhere and use that pid as the argument of waitpid().
Furthermore, you should consider checking the return value of waitpid(). In larger programs, if you have signal handlers it is possible that the call will be interrupted by signal and returns an error code with errno == EINTR. It is good practice to retry system calls interrupted by a signal and check for other possible error returns, too.
On this line:
waitpid(getpid(), &status, WNOHANG);
The getpid() will always get the parent pid, not the pid of the child.
Suggest changing switch(fork()) to
pid= fork(); switch(pid) { ... }
and the waitpid line to
waitpid(pid, &status, 0);

wait() function in c

I have two process. Their names are parent and child process. I want parent process wait child process without wait() function. How can I do this?
My code is here.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
intmain(int argc, char *argv[]) {
printf("hello world (pid:%d)\n", (int) getpid());
int rc = fork(); if (rc < 0) { // fork failed; exit
fprintf(stderr, "fork failed\n");
exit(1);
} else if (rc == 0) { // child (new process)
printf("hello, I am child (pid:%d)\n", (int) getpid());
} else { // parent goes down this path (original process)
printf("hello, I am parent of %d (wc:%d) (pid:%d)\n", rc, wc, (int) getpid());
}
return 0; }
You could write a loop that keeps checking if the child is running. You can use kill function to check if a process is alive. (This won't work, you can send a signal to a zombie process)
You could define a signal handler for SIGCHLD that sets a variable, and check that variable in a loop.
If you don't call some form of wait the child will become a zombie process though.

How to terminate a child process which is running another program by doing exec

I'm doing fork in my main program,and doing exec in the child process which will run another program. Now i want to terminate the child(i.e., the program invoked by exec) and return back to the main program(or parent program). how could i achieve this.. I tried with ctrl+c but its killing parent process and child also.please help me.
/*This is main.c*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
void sig_int(void);
void sig_term(void);
pid_t pid,ppid;
int main(char argc,char **argv){
int n;
char ch;
printf("***********Application to start or stop services**********\n");
do
{
printf("Enter 1 to start service no.1\n");
printf("Enter 2 to start service no.2\n");
printf("Enter 3 to start service no.3\n");
scanf("%d",&n);
if(fork() == 0)
{
switch(n)
{
case 1: printf("starting service no. 1..\n");
printf("checking whether the given service is already running...\n");
// system("./det.sh ./test")
pid = getpid();
printf("child process pid = %d\n",pid);
// signal(SIGINT,(void *)sig_int);
// signal(SIGTERM,(void *)sig_term);
//execl("/var/vR_main","vR_main",argv[1],argv[2],argv[3],argv[4],NULL);
execl("./test","test",0,0);//will run test.c
break;
case 2: printf("starting service no. 2..\n");
break;
case 3: printf("starting service no. 3..\n");
break;
}
}
else
{
int status;
wait(&status);
if (WIFEXITED(status))
printf("CHILD exited with %d\n", WEXITSTATUS(status));
if (WIFSIGNALED(status))
printf("signaled by %d\n", WTERMSIG(status));
if (WIFSTOPPED(status))
printf("stopped by %d\n", WSTOPSIG(status));
// sleep(2);
ppid = getpid();
printf("%d\n",ppid);
// wait();
printf("\nDo you want to continue...y/n:");
scanf(" %c",&ch);
}
}while(ch == 'y');
return 0;
}
void sig_int(void)
{
printf("caught signal\n");
kill(pid,SIGKILL);
// signal(SIGINT,SIG_DFL);
// exit(0);
}
void sig_term(void)
{
printf("killing the process\n");
signal(SIGINT,SIG_DFL);
// exit(0);
}
/*This is test.c*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
void sig_int(void);
void sig_term(void);
pid_t pid;
int main()
{
// int a=10,b=40,c=50,max;
pid = getpid();
printf("exec pid = %d\n",pid);
while (1)
{
signal(SIGINT,(void *)sig_int);
signal(SIGTERM,(void *)sig_term);
}
// max=a>b?a>c?a:c:b>c?b:c;
// printf("%d\n",max);
}
void sig_int(void)
{
printf("caught signal\n");
// signal(SIGINT,SIG_DFL);
kill(pid,SIGKILL);
// exit(0);
}
void sig_term(void)
{
printf("killing the process\n");
signal(SIGINT,SIG_DFL);
// exit(0);
}
Now I want to kill "test application" (invoked by exec),and return to the parent process or the "else block" to continue the program.
You need to do the following:
Do a kill(pid, SIGTERM) first - this gives the child process an opportunity to terminate gracefully
Wait a period of time (use sleep). The period of time depends on the time the child process takes to close down gracefully.
Use waitpid(pid, &status, WNOHANG) checking the return value. If the process has not aborted do step 4
Do a kill(pid, SIGKILL) then harvest the zombie by doing waitpid(pid, &status, 0).
These steps ensure that you give the child process to have a signal handler to close down and also ensures that you have no zombie processes.
Either in or outside your program, it is possible to use kill. By including <signal.h>, you can kill a process with a given PID (use the fork return value to do this).
#include <signal.h>
int pid;
switch (pid = fork())
{
case -1:
/* some stuff */
break;
case 0:
/* some stuff */
break;
default:
/* some stuff */
kill(pid, SIGTERM);
}
It is also possible to use kill command in the shell. To find the PID of your child process, you can run ps command.
man kill
The kill() function shall send a signal to a process or a group of processes specified by pid. The signal to be sent is specified by sig and is either one from the list given in <signal.h> or 0. If sig is 0 (the null signal), error checking is performed but no signal is actually sent. The null signal can be used to check the validity of pid.
POSIX defines the kill(2) system call for this:
kill(pid, SIGKILL);

Parent process doesn't complete after child is terminated in C

I'm having trouble with a process forking exercise. I want to fork a child process and have it hang after announcing it has been forked, and wait for a signal to terminate, after which the parent process must announce it is terminating and then exit.
I can get the processes forked and have the parent wait for the hanging child to be killed by the signal, but it seems to kill the parent as well. I tried killing the child process specifically by its PID, but with no success.
Thanks for any help!
Code:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
void catchInt (int signum)
{
printf("\nMy sincerest apologies, master\n");
/*kill(0, SIGINT);*/
exit(0);
}
void ignoreInt (int signum)
{
wait(NULL);
}
int main () {
pid_t pid;
/* fork process */
pid = fork();
if (pid < 0) /* error handler */
{
fprintf(stderr, "Fork Failed");
exit(-1);
}
else if (pid == 0) /* child */
{
printf("Child reporting in\n");
signal(SIGINT, catchInt);
for ( ;; )
pause();
}
else /* parent */
{
/* parent will wait for the child to complete */
signal(SIGINT, ignoreInt);
wait(NULL);
printf("You're welcome\n");
exit(0);
}
}
Even assuming you fix the code so it compiles (you've not defined tempPID), there are problems:
You set the child to go to sleep until a signal arrives.
You set the parent to wait until the child dies.
So, you have a state where neither process is going to do anything more.
You probably need the parent to send a signal to the child:
kill(pid, SIGINT);
It is not clear that you need the parent to set a signal handler.
You probably want the child to set a signal handler.
You probably don't want the infinite loop in the child.
Oh, and void main() is incorrect - int main() or int main(void) or int main(int argc, char **argv) are the approved declarations for main().
And it is tidier if you return a value (0) from main(). The C99 standard does permit you to drop off the end of main() and will treat that as returning zero, but only if the function is properly declared as returning an int.
The header for wait() and relatives in POSIX is <sys/wait.h>.
And, because I'm a sucker, here's code that compiles and might even do what you want:
#include <stdio.h>
#include <signal.h>
#include <unistd.h> /* getpid() */
#include <stdlib.h>
#include <sys/wait.h>
void catchInt(int signum)
{
printf("Child's PID is %d\n", (int)getpid());
printf("My sincerest apologies, master\n");
exit(1);
}
int main()
{
pid_t pid = fork();
if (pid < 0) /* error handler */
{
fprintf(stderr, "Fork Failed");
exit(-1);
}
else if (pid == 0) /* child */
{
printf("Child reporting in\n");
signal(SIGINT, catchInt);
pause();
}
else /* parent */
{
sleep(1);
kill(pid, SIGINT);
wait(NULL);
printf("You're welcome\n");
}
return(0);
}
Just figured out what I was doing wrong, I should have realized SIGINT is sent to every process, and so the parent was simply being sent an unhandled SIGINT, causing it to exit. Thanks for all the help (my apologies on the sloppy coding, I really shouldn't wait until the program is completed to clean that up), the code's been edited above and works as intended.
Thanks again.

Resources