Checking if a number is prime using fork and pipe - c

So I have to do the next program:
create a child process,
the parent reads numbers from the keyboard (until 0) and sends them to the child,
the child receives numbers from the parent and prints those that are prime,
when the child receives 0 from the parent, it will terminate.
And I did it the next way:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
int a=1;
int isprime=0;
int p[2];
pipe(p);
int pid = fork();
if(pid < 0)
exit(1);
if(pid == 0)
{
close(p[1]);
read(p[0],&a,sizeof(int));
isprime = 1;
for(int i=2;i*i<=a;i++)
if(a%i==0)
isprime = 0;
if(isprime == 1)
printf("%d is prime",a);
close(p[0]);
}
else
{
close(p[0]);
while(a!=0){
printf("a=");
scanf("%d",&a);
write(p[1],&a,sizeof(int));
}
wait(0);
close(p[1]);
}
return 0;
}
But it doesn't work properly, it stops after the first reading of a. Can somebody help me, please?

Related

fork() in a For Loop

#include <stdio.h>
#include <sys/type.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
int main(void)
{
pid_t pid;
int i;
for(i=0; i<3; i++) {
pid = fork();
if(pid == -1) {
printf("Fork Error.\n");
} else if(pid == 0) {
printf("I am child");
}
}
if(pid != 0) {
while((pid = waitpid(-1, NULL, 0)) > 0)
if(errno == ECHILD)
break;
printf("I am parent and all children have exited.\n");
}
exit(0);
return 0;
}
The result is that,
'I am child' is printed 7 times,
'I am parent and all children have exited.' is printed 4 times
and the print sequence is not fixed.
Here's my question!
Why 'I am child' is printed 7 times,
and 'I am parent and all children have exited.' is printed 4 times ?
I don't understand the number of times those sentences are printed.
Could you explain it in detail?
You can try the code below. You need to add the wait header. At the same time, after providing the 0 condition of the child processes, you should definitely sign out, otherwise each processes will fork again and again each time in the code. Shortly you have to kill every process after their task end.
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/wait.h>
int main(void){
pid_t pid;
int i;
for (i = 0; i < 3; i++)
{
pid = fork();
if (pid == -1) {
printf("Fork Error.\n");
} else if (pid == 0) {
printf("I am child\n");
exit(0); // !
}
}
if (pid != 0) {
while ((pid = waitpid(-1, NULL, 0)) > 0)
if (errno == ECHILD)
break;
printf("I am parent and all children have exited.\n");
}
return 0;
}

When using fork, scanf in parent reads input twice

When program is reading input from file like this ./a.out < inputFile after fork all input is printed twice to output like there would be no exit(0) in child of fork. My expectation was that everything would be printed only once, since program is only printing in parent, not child. Why does that happen?
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <wait.h>
int main() {
char currentChar;
int counter = 0;
while (scanf("%c", &currentChar) != EOF) {
printf("%c", currentChar);
fflush(stdout);
counter++;
if (counter == 10) {
// all characters after 10 characters are printed twice
int pid = fork();
if (pid == 0) {
// child;
exit(0);
} else {
// parent;
int status;
waitpid(pid, &status, 0);
}
}
}
return 0;
}

why does creating a fork in the middle of my program change my pid variable's value before the program runs?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
useconds_t BEAUTY_SLEEP = 500;
int main() {
int remains = 0;
char whoami[50];
pid_t pid;
pid_t ppid;
printf("%d\n", pid); //debug
printf("%d\n", getppid()); //debug
fflush(stdout); //debug
while (1) {
if ((ppid = getppid()) == 2704 && (pid == 0)) {
pid = fork();
if (pid == -1) {
perror("fork()");
exit(1);
}
printf("%ld\n", (long)ppid);
puts("beep");
} else {
usleep(BEAUTY_SLEEP);
}
}
return 0;
}
When I comment out "pid = fork()" in the while loop above, printf("%d\n", pid) prints the proper default value, 0. However, when I restore the pid = fork() line, the print statement outputs a non-zero process ID. Any clue as to why the retroactive assignment is happening?

creating a second process in C

Im new in C programming and i have to do this:
Write a program that creates a second process, and then in both processes outputs the process ID and the owners user ID.
I don't know if thats right and how to continue from here. Here is what i have:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(void) {
int ChildPID;
printf("This is the parent process number %d\n",getpid());
if ((ChildPID = fork()) == -1) {
perror("Could not fork");
exit(EXIT_FAILURE);
}
if (ChildPID == 0) {
//----In the child process
printf("This is the child process, number %d parent number %d\n", getpid(), getppid());
}
return(EXIT_SUCCESS);
}
The piece of code given below gives your solution. Here you can clearly identify parent code and child process code. Both are printing their corresponding pids.
void ExecuteChild(void);
void ExecuteParent(void);
int main(void)
{
pid_t pid;
pid = fork();
if (pid == 0)
ExecuteChild();
else
ExecuteParent();
}
void ExecuteChild(void)
{
int i;
for (i = 1; i <= 200; i++)
printf("CHILD[%d]: UserID[%d] printing - %d\n", getpid(),getuid(),i);
printf(" ------------- Child Exiting -------------\n");
}
void ExecuteParent(void)
{
int i;
for (i = 1; i <= 200; i++)
printf("PARENT[%d]: UserID[%d] printing - %d\n", getpid(),getuid(),i);
printf(" ------------- Parent Exiting -------------\n");
}

parent send command line arguments to child

I am writing a program that creates a pipe, forks, then the parent sends the command line arguments to the child one char at a time. The child is supposed to count them, and then the parent reaps the child and prints out how many arguments there were. Here is what I have so far:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
int main(int argc, char **argv)
{
pid_t pid;
int status;
int comm[2];
char buffer[BUFSIZ];
// set up pipe
if (pipe(comm)) {
printf("pipe error\n");
return -1;
}
// call fork()
pid = fork();
// fork failed
if (pid < 0) {
printf("fork error %d\n", pid);
return -1;
}
else if (pid == 0) {
// -- running in child process --
int nChars = 0;
close(comm[1]);
// Receive characters from parent process via pipe
// one at a time, and count them.
while(read(comm[0], buffer, sizeof(buffer)) != '\n')
nChars++;
// Return number of characters counted to parent process.
return nChars;
}
else {
// -- running in parent process --
int nChars = 0;
close(comm[0]);
// Send characters from command line arguments starting with
// argv[1] one at a time through pipe to child process.
char endl='\n';
for (int a = 1; a < argc; a++) {
for (int c = 0; c < strlen(argv[a]); c++) {
write(comm[1], &argv[a][c], 1);
}
}
write(comm[1], &endl, 1);
// Wait for child process to return. Reap child process.
// Receive number of characters counted via the value
// returned when the child process is reaped.
waitpid(pid, &status, 0);
printf("child counted %d chars\n", nChars);
return 0;
}
}
It seems to run endlessly. It must be stuck in one of the loops. What is going wrong?
Code:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
int main(int argc, char *argv[])
{
pid_t pid;
int status;
int comm[2];
char buffer[BUFSIZ];
// set up pipe
if (pipe(comm) < 0) {
printf("pipe error\n");
return -1;
}
// call fork()
if((pid = fork()) <0)
{
printf("fork error %d\n", pid);
return -1;
}
else if (pid == 0) {
// -- running in child process --
int nChars = 0;
close(comm[1]);
//printf("%d \n",BUFSIZ);
// Receive characters from parent process via pipe
// one at a time, and count them.
int n;
while( (n =read(comm[0], buffer, BUFSIZ)) >0)
{
buffer[n] = 0;
int oneChar, i = 0,endflag = 0;
while((oneChar = buffer[i])!=0)
{
// printf("%d\n",oneChar);
if(oneChar!=EOF)
nChars++;
else
{
endflag = 1;
break;
}
i++;
}
//printf("%s\n",buffer);
if(endflag)
break;
}
printf("nChar : %d",nChars);
// Return number of characters counted to parent process.
return nChars;
}
else {
// -- running in parent process --
//int nChars = 0;
close(comm[0]);
// Send characters from command line arguments starting with
// argv[1] one at a time through pipe to child process.
int a,c;
char endl='\n';
for ( a = 1; a < argc; a++) {
for ( c = 0; c < strlen(argv[a]); c++) {
write(comm[1], &argv[a][c], 1);
}
}
printf("write end\n");
int end = EOF;
write(comm[1],&end,4);
waitpid(pid, &status, 0);
printf("child counted %d chars\n", WEXITSTATUS(status));
return 0;
}
}

Resources