For some reason im getting wrong result using fork - c

The program creates a child proccess and the child does the proper work in order to see if its pid is even or odd
And for some reason even if the pid is even i get that it is odd , also the parent waits for child
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main() {
pid_t pid, mypid, cpid;
int flag;
pid = getpid();
printf("Process %d creates new process\n\n", pid);
cpid = fork();
if (cpid == 0) {
cpid=getpid();
printf("\n----[%d] child\n", cpid);
if (cpid % 2 == 0) {
flag = 1;
} else {
flag = 0;
}
exit(0);
} else if (cpid != 0) {
wait(NULL);
mypid = getpid();
printf("\n[%d] parent of [%d]\n", mypid, cpid);
if (flag == 1) {
printf("\nThe child pid is even");
} else if(flag ==0) {
printf("\nThe child pid is odd");
} else {
printf("\nSomething went wrong");
}
} else {
perror("Fork failed");
}
return 0;
}

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;
}

Message sending and recieving not working using messagequeue

I am trying to send a message from child to parent (it has 2 children). But it returns error "Invalid Argument" when I run it in Xcode and when I run it in vim it is just pending and doing nothing. I want to send a message from 2nd child to Parent.
I have checked these, they are working finely :
Parent and child id matching
Arguments of msgrcv and msgsnd
fork and message queue creation
(I have added appropriate headers)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
void signalHandler(int signumber,siginfo_t* info,void* nonused){
printf("Signal with number %i has arrived\n",signumber);
switch (info->si_code){
case SI_USER:
printf("Process (PID number %i) sent the signal \n",info->si_pid); break;
case SI_QUEUE:
printf("It was sent by a sigqueue, sending process (PID %i)\n",info->si_pid);
default: printf("");
}
}
struct messg {
long mtype;
char mtext[1024];
};
int sendMsg (int mqueue){
const struct messg m = {5,"Test message"};
int status;
status = msgsnd(mqueue, &mqueue, strlen(m.mtext) + 1, IPC_NOWAIT);
if (status < 0){
perror("Message send error!");
}
return 0;
}
int receiveMsg(int mqueue){
struct messg m;
int status;
status = msgrcv(mqueue, &m, 1024 - sizeof(long), 5, 0);
if (status < 0){
printf("Errno : %d\n",status);
perror("Message recieve error!");
} else {
printf("Received msg : %s",m.mtext);
}
return 0;
}
int main(int argc, const char * argv[]) {
struct sigaction sigact;
sigact.sa_sigaction=signalHandler;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags=SA_SIGINFO;
sigaction(SIGTERM,&sigact,NULL);
key_t key = ftok(argv[0],1);
int messg = msgget(key, 0600 | IPC_CREAT);
pid_t parent_co;
int pid_co_parent[2];
if (messg < 0){
perror("Message creation error!");
return 1;
}
pid_t child_nhp;
int pid_child_nhp[2];
char sz[250];
if(pipe(pid_co_parent) == -1){
perror("Pipe");
exit(0);
}
if(pipe(pid_co_parent) == -1){
perror("Pipe");
exit(0);
}
parent_co = fork();
if (parent_co == 0) {
sleep(3);
printf("(Police Lieutenant-colon) Child process : child_id : %d, parent_id : %d\n",getpid(),getppid());
kill(getppid(), SIGTERM);
read(pid_co_parent[0], sz, sizeof(sz));
printf("(Communication Officer) : %s\n" ,sz);
char answer[250];
strcpy(answer, "Yes, it is compulsory to wear the mask when you leave your flat!");
write(pid_co_parent[1], answer, strlen(answer) + 1);
close(pid_co_parent[0]);
return 0;
} else {
printf("(Communication Officer) Parent process_id : %d\n",getpid());
pause();
char ques[250];
strcpy(ques, "Is it compulsory to wear a mask in the shops?");
write(pid_co_parent[1], ques, strlen(ques) + 1);
close(pid_co_parent[1]);
read(pid_co_parent[0], sz, sizeof(sz));
printf("(Police Lieutenant-colon) : %s\n",sz);
close(pid_co_parent[0]);
child_nhp = fork();
if (child_nhp < 0){
perror("fork error for child nhp!");
exit(0);
}
if (child_nhp == 0) {
printf("(National Head Physician) child_id : %d, parent_id : %d\n",getpid(),getppid());
receiveMsg(messg);
return 0;
} else {
sendMsg(messg);
wait(NULL);
// parent process
}
fflush(NULL);
wait(NULL);
}
return 0;
}

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;
}

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?

wait(&status) always return 0

I'm try to get exit status of child process but always gets 0.
what I'm doing wrong, is this not the way?
here is my code, tokens = an commands array.
thanks
int execute(char** tokens)
{
pid_t pid;
int status;
pid = fork();
if (pid == -1)
{
fprintf(stderr,"ERROR: forking child process failed\n");
return -1;
}
// Child process
if (pid == 0)
{
// Command was failed
if (execvp(*tokens, tokens) == -1)
{
fprintf(stderr, "%s:command not found\n", *tokens);
return 255;
}
}
else
{
pid = wait(&status);
status = WEXITSTATUS(status);
}
return status;
}
always:
status = 0.
what I need to change?
You'd probably want to exit(255) right away to ensure that the correct status is returned. Also wait is very probable to get EINTR. Also, the return status is meaningful only if WIFEXITED(status), otherwise you shouldn't rely on it:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <errno.h>
int execute(char** tokens)
{
pid_t pid;
int status;
pid = fork();
if (pid == -1)
{
fprintf(stderr,"ERROR: forking child process failed\n");
return -1;
}
// Child process
if (pid == 0)
{
// Command was failed
if (execvp(*tokens, tokens) == -1)
{
fprintf(stderr, "%s: command not found\n", *tokens);
exit(255);
}
}
else {
while (1) {
pid = wait(&status);
if (pid == -1) {
if (errno == EINTR) {
continue;
}
perror("wait");
exit(1);
}
break;
}
if (WIFEXITED(status)) {
int exitcode = WEXITSTATUS(status);
printf("%d\n", exitcode);
}
else {
printf("Abnormal program termination");
}
}
return status;
}
int main() {
char *args[] = {
"/bin/cmd_not_found",
"Hello",
"World!",
0
};
execute(args);
}

Resources