Why my fork() does not output anything? - c

As code , why I don't get any outputs , can anybody tell me the issue? like that I have two fork() and each will run in a child process and my parent process will not be exit, seems right, but still don't get anything output.
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv)
{
/***********************************/
printf("--beginning of program\n");
int counter = 0;
pid_t pid1 = 0;
pid_t pid2 = 0;
while(1){
if(pid1 == 0)
pid1 = fork1();
if(pid2 == 0)
pid2 = fork2();
}
printf("--end of program--\n");
return 0;
}
/* Two fork() */
pid_t fork1(){
pid_t pid = fork();
if(pid ==0 )
{
while(1){
sleep(1);
fprintf(stdout," fork1 ");
}
}
return pid;
}
pid_t fork2(){
pid_t pid = fork();
if(pid ==0 )
{
while(1){
sleep(1);
fprintf(stdout," fork1 ");
}
}
return pid;
}

stdout is buffered, it will normally only be flushed on a newline or if you explicitly flush it.
You can get your code to output the lines from the children processes by adding a newline in your statements:
fprintf(stdout, "fork1\n");
Or by explicitly flushing the buffer after the fprintf:
fflush(stdout);

Related

How do I make it so that processes are created parallel to each other rather than one after another?

I need help in modifying this code. Right now, it creates a process, and then waits for its termination. After which, another process is created, and then it waits for its termination. I want to modify it so that it creates both processes at the same time and executes them parallel to each other. The code is:
#include <sys/types.h>
#include <stdio.h>
int main(int argc, char * argv[]) {
pid_t pid;
int status;
pid = fork();
if (pid != 0) {
while (pid != wait( & status));
} else {
sleep(5);
exit(5);
}
pid = fork();
if (pid != 0) {
while (pid != wait( & status));
} else {
sleep(1);
exit(1);
}
}
Here's code that should do the job:
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void)
{
pid_t pid = fork();
if (pid != 0)
printf("Child 1 PID = %d\n", pid);
else
{
sleep(5);
exit(5);
}
pid = fork();
if (pid != 0)
{
printf("Child 2 PID = %d\n", pid);
int corpse;
int status;
while ((corpse = wait(&status)) > 0)
printf("Child %d exited with status 0x%.4X\n", corpse, status);
}
else
{
sleep(1);
exit(1);
}
return 0;
}
One time when I ran it, I got the output:
Child 1 PID = 49582
Child 2 PID = 49583
Child 49583 exited with status 0x0100
Child 49582 exited with status 0x0500
If you preferred, you could move the wait() loop and its variable declarations after the if structures and immediately before the return 0; at the end. That would give you better symmetry. You could even wrap up the child creation phase into a function called twice:
static void procreate(int kidnum, int naptime)
{
int pid = fork();
if (pid != 0)
printf("Child %d PID = %d (nap time = %d)\n", kidnum, pid, naptime);
else
{
sleep(naptime);
exit(naptime);
}
}
and then in main() you'd just have two calls to procreate() and the wait loop:
int main(void)
{
procreate(1, 5);
procreate(2, 1);
int corpse;
int status;
while ((corpse = wait(&status)) > 0)
printf("Child PID %d exited with status 0x%.4X\n", corpse, status);
return 0;
}

How to fix data write or read using pipe in c program is giving wrong output?

I am trying to get an integer input in the child process and send it to the parent process using pipe()
but I receive garbage values every time in the parent process.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include<sys/wait.h>
int main(int argc, char *argv[])
{
pid_t pid;
int fd[2];
char *args[] = {"", NULL};
int cnum,pnum;
pid = fork();
if (pid < 0)
{
perror("fork");
exit(1);
}
if(pipe(fd) == -1)//fd[0] for read fd[1] for write
{
perror("pipe");
exit(1);
}
if(pid == 0)
{
close(fd[0]);
printf("\n**In the child process**\n");
printf("Enter Number : ");
scanf("%d",&cnum);
write(fd[1],&cnum,sizeof(int));
close(fd[1]);
}
else
{
wait(NULL);
close(fd[1]);
printf("\n**In the parent precess**\n");
read(fd[0],&pnum,sizeof(int));
close(fd[0]);
printf("Number recieved = %d\n",pnum);
printf("PID = %d\n", getpid());
execv("./sayHello", args);
printf("Error");
}
}
Output of the above code
**In the child process**
Enter Number : 212
**In the parent precess**
Number recieved = 1036468968
PID = 22528
Hillo Amol
PID = 22528
I give input of 212 but in parent 1036468968 received.
You call fork before you create the pipe FDs. After you call fork, the parent and the child both create their own pair of pipe FDs, and there's no shared pipe between them.
Create the pipe before you fork and it could work.
As drorfromthenegev suggest problem is arising due to I am calling pipe() after fork().
So I call pipe() first and the i call fork() and it works..
Workable solution
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include<sys/wait.h>
int main(int argc, char *argv[])
{
pid_t pid;
int fd[2];
char *args[] = {"", NULL};
int cnum,pnum;
if(pipe(fd) == -1)//fd[0] for read fd[1] for write
{
perror("pipe");
exit(1);
}
pid = fork();
if (pid < 0)
{
perror("fork");
exit(1);
}
if(pid == 0)
{
close(fd[0]);
printf("\n**In the child process**\n");
printf("Enter Number : ");
scanf("%d",&cnum);
write(fd[1],&cnum,sizeof(int));
close(fd[1]);
}
else
{
wait(NULL);
close(fd[1]);
printf("\n**In the parent precess**\n");
read(fd[0],&pnum,sizeof(int));
close(fd[0]);
printf("Number recieved = %d\n",pnum);
printf("PID = %d\n", getpid());
execv("./sayHello", args);
printf("Error");
}
}

Pipe creation through functions

I was wondering if someone can help me modify my current code....
Currently it creates my process using fork() and takes a pointer to a function which executes that childs code block.
I wanted to play around with pipes and attempt to now have Process Y send its pid to Process X and then i want to send it back to the Main...
Heres what i have currently
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h> // exit
#include <fcntl.h>
#include <sys/wait.h>
void processX();
void processY();
pid_t addChild(void (*childPtr) (), int fileDes[2]) {
pid_t cpid;
if((cpid=fork()) == 0) {
pipe(fileDes);
childPtr(fileDes);
wait(NULL);
exit(0);
} else if (cpid < 0) {
printf("failed to fork");
exit(1);
} else {
}
return cpid;
}
void processY(int fileDes[2]) {
printf("Child Y[%d] Created of Parent X[%d]\n", getpid(), getppid());
printf("We are now going to write Y PID to process X\n");
pid_t a = getpid();
char buf[1024]; // child reads from pipe() to buffer
close(fileDes[0]); // close reading end of the pipe
write(fileDes[1], &a, sizeof(buf) / sizeof(int));
}
void processX(int fileDes[2]) {
printf("Child X[%d] Created of parent Main[%d]\n", getpid(), getppid());
int status;
pid_t Y = addChild(processY, fileDes);
wait(&status);
pid_t new_val = 5;
close(fileDes[1]); // closing the writing end of the pipe.
read(fileDes[0], &new_val, sizeof(new_val));
printf("Message read with number %d: \n", new_val);
}
int main() {
int status;
int fd[2];
printf("Main process[%d]\n", getpid());
pid_t root = addChild(processX, fd);
wait(&status);
printf("We are going to read from X to Main and then return the Value we got from Y\n");
return 0;
}
I dont know to create a pipe from Y - X and then X - Main....
Y---->send pid ----> X received Y pid ----- send new info to main --->Main print received data...
My answer i came up with
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h> // exit
#include <fcntl.h>
#include <sys/wait.h>
void processX();
void processY();
pid_t addChild(void (*childPtr) (), int fileDes[2], int backToMainFd[2]) {
pid_t cpid;
if(childPtr != *processX //prevents the the pipe from main to x from recreating
pipe(fileDes);
if((cpid=fork()) == 0) {
if(childPtr == *processX) {
childPtr(fileDes, backToMainFd);
} else {
childPtr(fileDes);
}
wait(NULL);
exit(0);
} else if (cpid < 0) {
printf("failed to fork");
exit(1);
} else {
}
return cpid;
}
void processY(int fileDes[2]) {
printf("[PROCESS Y]: Child Y[%d] Created of Parent X[%d]\n", getpid(), getppid());
pid_t a = getpid();
char buf[1024]; // child reads from pipe() to buffer
close(fileDes[0]); // close reading end of the pipe
write(fileDes[1], &a, sizeof(buf) / sizeof(int));
}
void processX(int fileDes[2], int BackToMainFd[2]) {
printf("[PROCESS X]: Child X[%d] Created of parent Main[%d]\n", getpid(), getppid());
int status;
pid_t Y = addChild(processY, fileDes, NULL);
wait(&status);
pid_t new_val = 5;
close(fileDes[1]); // closing the writing end of the pipe.
read(fileDes[0], &new_val, sizeof(new_val));
printf("[PROCESS X]: We got Ys' PID as:%d from [PROCESS Y]\n", new_val);
close(BackToMainFd[0]); // close reading end of the pipe
char buf[1024]; // child reads from pipe() to buffer
write(BackToMainFd[1], &new_val, sizeof(buf) / sizeof(pid_t));
}
int main() {
int status;
int fd[2];
int backToMainFD[2];
printf("Main process[%d]\n", getpid());
pipe(backToMainFD);
pid_t root = addChild(processX, fd, backToMainFD);
wait(&status);
pid_t new_val = 5;
close(backToMainFD[1]); // closing the writing end of the pipe.
read(backToMainFD[0], &new_val, sizeof(new_val));
printf("[MAIN]: We got Ys' PID as:%d from [PROCESS X]\n", new_val);
printf("Send sig kills too Y and root\n");
kill(new_val, SIGKILL);
kill(root, SIGKILL);
printf("Terminate program.\n");
return 0;
}

Executing wc command on child process using pipeline

I'm writing a program that executes the word count command on the child process. The father process should send a sequence of lines entered by the user trough a pipeline to the child process.
I tried to do this but I ended up with an error.
This is my code:
int main ()
{
int fd[2];
char buff;
int pid;
int pip;
pid = fork();
pip = pipe(fd);
if (pid != 0)
{
pip = pipe(fd);
if (pipe == 0)
{
while (read(fd[0], &buff,1) > 0 )
{
write (fd[1],&buff,1);
}
close(fd[0]);
_exit(0);
}
}
else
{
dup2(fd[1],1);
close(fd[1]);
execlp ("wc","wc",NULL);
_exit(-1);
}
return 0;
}
I've also tried to use dup2 to associate the standard input from the child to the read descriptor of the pipe created by the father process.
But I get this error : wc: standard input: Input/output error.
How can I solve this?
UPDATED (the error is solved but I get an infinite loop)
int main ()
{
int fd[2];
char buff;
int pid;
int pip;
pip = pipe(fd);
if (pip == 0)
{
pid = fork();
if (pid != 0)
{
while (read(fd[0], &buff,1) > 0 )
{
write (fd[1],&buff,1);
}
close(fd[0]);
}
else {
dup2(fd[1],1);
close(fd[1]);
execlp ("wc","wc",NULL);
_exit(-1);
}
}
return 0;
}
#include <unistd.h>
int main ()
{
int fd[2];
char buff;
int pid;
int pip;
int status;
pip = pipe(fd);
if (pip == 0)
{
pid = fork();
if (pid != 0)
{
close(fd[0]);
while (read(0, &buff,1) > 0 )
{
write (fd[1],&buff,1); /* your old loop forwarded internally in the pipe only*/
}
close(fd[1]);
} else {
dup2(fd[0],0); /* you had dup2(fd[1], 1), replacing stdout of wc with the write end from wc */
close(fd[0]);
close(fd[1]);
execlp ("wc","wc",NULL);
_exit(-1);
}
}
wait(&status); /* reap the child process */
return 0;
}

SIGUSR1 - kill sigaction in C

In the C language create a program that creates two processes and connects them via pipe.
The first descendant redirects its' stdout into the pipe and writes (space separated) pairs of random numbers into it (function rand). Delay the output of the numbers by 1 second.
The second descendant redirects the pipe output to it's stdin, redirects it's stdout into a file called out.txt in the current directory.
The parent process waits 5 seconds and then sends SIGUSR1 to the first process (number generator). This should perform a correct termination of both processes. It waits for the sub-processes to terminate (wait function) and terminates itself.
I really need help with:
The first descendant has to treat the SIGUSR1 signal (sigaction function) and in case of receiving such signal it prints a string “TERMINATED” to it's stderr and terminates.
FILE *file;
file = fopen(NAZEV, "a+");
int pipefd[2];
pipe(pipefd);
pid_t pid1;
int retcode;
pid1=fork();
if(pid1 == 0) // child 1
{
close(roura[0]);
printf("child1...\n");
dup2(roura[1], STDOUT_FILENO);
int i = 0;
while(i < 6)
{
i++;
int a = rand();
int b = rand();
sleep(1);
printf("%d %d\n", a, b);
}
close(roura[1]);
exit(45);
}
else if (pid1 < 0)
{
printf("Fork selhal\n");
exit(2);
}
else
{
pid_t pid2;
pid2 = fork();
if (pid2 == 0) //child 2
{
close(roura[1]);
dup2(roura[0], STDIN_FILENO);
printf("child2...\n");
int i = 0;
while(i < 5)
{
i++;
int c;
int d;
scanf("%d %d", &c, &d);
printf("%d %d\n", c, d);
fprintf(file,"%d %d\n", c, d);
}
printf("child2 end\n");
exit(0);
}
else if (pid2 < 0)
{
printf("Fork error\n");
exit(2);
}else
{
sleep(5);
kill(pid1, SIGUSR1);
wait(&pid1); //wait for child 1
wait(&pid2); //wait for child 2
printf("parent end\n");
exit(0);
}
}
exit(0);
}
Adda signal handler to sigusr1 that prints to stderr and exits.
Try this, adapted to compile in cygwin:
#include <stdio.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef STDIN_FILENO
# define STDIN_FILENO 0
#endif
#ifndef STDOUT_FILENO
# define STDOUT_FILENO 1
#endif
void sig_handler(){
fprintf(stderr,"TERMINATED");
exit(0);
}
void main(int argc, char ** argv){
FILE *file;
file = fopen("NAZEV", "a+");
int pipefd[2];
int roura[2] ;
pipe(pipefd);
pid_t pid1;
int retcode;
pid1=fork();
if(pid1 == 0) // child 1
{
close(roura[0]);
printf("child1...\n");
dup2(roura[1], STDOUT_FILENO);
if (signal(SIGUSR1, sig_handler) == SIG_ERR){
printf("\ncan't catch SIGUSR1\n");
exit(13);
}
int i = 0;
while(i < 6)
{
i++;
int a = rand();
int b = rand();
sleep(1);
printf("%d %d\n", a, b);
}
close(roura[1]);
exit(45);
}
else if (pid1 < 0)
{
printf("Fork selhal\n");
exit(2);
}
else
{
pid_t pid2;
pid2 = fork();
if (pid2 == 0) //child 2
{
close(roura[1]);
dup2(roura[0], STDIN_FILENO);
printf("child2...\n");
int i = 0;
while(i < 5)
{
i++;
int c;
int d;
scanf("%d %d", &c, &d);
printf("%d %d\n", c, d);
fprintf(file,"%d %d\n", c, d);
}
printf("child2 end\n");
exit(0);
}
else if (pid2 < 0)
{
printf("Fork error\n");
exit(2);
}else
{
sleep(5);
kill(pid1, SIGUSR1);
wait(&pid1); //wait for child 1
wait(&pid2); //wait for child 2
printf("parent end\n");
exit(0);
}
}
exit(0);
}
You need to register a signal handler using sigaction if you want to override the default action. For SIGUSR1, the default action is to terminate the process.

Resources