Reputation: 423
I'm writing this program, that creates a parent and a child, and I have to verify a username. But it seems it doesn't work as I have a global variable set so that I can jump over some block of code directly to the part I want to evaluate the username. But it seems that the variable I have, logEval, doesn't maintain the value i give it in the first child, so it returns 0 inside the parent.
this is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
//sys variables
char Input[100], commandLogin[100], Output[100], Username[50], possibleUsername[50];
int readDescriptor, logEval;
pid_t childPid;
//
int commandCatcher(){
//define socket
int socketOne[2], socketTwo[2];
if(socketpair(AF_UNIX, SOCK_STREAM, 0, socketOne) < 0){
perror("socket - err");
exit(0);
}
if(logEval == 0)
switch(fork()){//first child
case -1:
perror("fork - err");
exit(1);
case 0:
childPid=getpid();
readDescriptor = read(socketOne[0], commandLogin, sizeof(commandLogin));
if (strcmp(commandLogin, "login") == 0 ){
logEval = logEval + 1;
printf("Log eval from first:%d\n", logEval);
write(socketOne[0], "ok", strlen("ok") + 1);
//something to do here so that the child knows it was given the username
exit(1);
}
else {
printf("Try again.\n");
write(socketOne[0], "none", strlen("none")+1);
exit(1);
}
}
if(logEval == 1){
switch(fork()){//verify username
case -1:
perror("fork - err");
exit(2);
case 0:
readDescriptor = read(socketTwo[0], possibleUsername, sizeof(possibleUsername));
printf("Username from second child:%s\n", possibleUsername);
printf("logEval is : %d", logEval);
}
exit(2);
}
//parent
//getting initial value
scanf("%s", Input);
//writing initial value
write(socketOne[1], Input, strlen(Input)+1);
readDescriptor = read(socketOne[1], Output, sizeof(Output));
//printf("output %s\n", Output);
//verify if the command was correctly given
if(strcmp(Output, "ok") == 0) {
printf("Command was accepted. Insert your username: %d\n", logEval);
if(socketpair(AF_UNIX, SOCK_STREAM, 0, socketTwo) < 0){//second socket
perror("sockettwo - err");
exit(2);
}
scanf("%s", Username);
write(socketTwo[1], Username, strlen(Username)+1);
printf("%s\n", Username);
printf("%d\n", logEval);
commandCatcher();
}
else if(strcmp(Output, "none") == 0) {
printf("Command was denied. Please try again:\n");
commandCatcher();//recursive call
}
wait(&childPid);
printf("execution finished");
}
int main(){
printf("Welcome to Sys v1.0. To start off, please insert your command. \n");
commandCatcher();
return 0;
}
SECOND EDIT:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
//sys variables
char Input[100], commandLogin[100], Output[100], Username[50], possibleUsername[50];
int readDescriptor, logEval;
int readDescriptor2;
pid_t childPid;
//
int commandCatcher(){
//define socket
int socketOne[2], socketTwo[2];
if(socketpair(AF_UNIX, SOCK_STREAM, 0, socketOne) < 0){
perror("socket - err");
exit(0);
}
if(logEval == 0)
switch(fork()){//first child
case -1:
perror("fork - err");
exit(1);
case 0:
childPid=getpid();
readDescriptor = read(socketOne[0], commandLogin, sizeof(commandLogin));
if (strcmp(commandLogin, "login") == 0 ){
printf("Log eval from first:%d\n", logEval);
write(socketOne[0], "ok", strlen("ok") + 1);
//something to do here so that the child knows it was given the username
exit(logEval);
}
else {
printf("Try again.\n");
write(socketOne[0], "none", strlen("none")+1);
exit(1);
}
}
if(logEval == 1){
switch(fork()){//verify username
case -1:
perror("fork - err");
exit(2);
case 0:
readDescriptor2 = read(socketTwo[0], possibleUsername, sizeof(possibleUsername));
printf("Username from second child:%s ---\n", possibleUsername);
printf("logEval is : %d\n", logEval);
}
exit(2);
}
//parent
//getting initial value
scanf("%s", Input);
//writing initial value
write(socketOne[1], Input, strlen(Input)+1);
readDescriptor = read(socketOne[1], Output, sizeof(Output));
//printf("output %s\n", Output);
//verify if the command was correctly given
if(strcmp(Output, "ok") == 0) {
printf("Command was accepted. Insert your username: %d\n", logEval);
if(socketpair(AF_UNIX, SOCK_STREAM, 0, socketTwo) < 0){//second socket
perror("sockettwo - err");
exit(2);
}
scanf("%s", Username);
write(socketTwo[1], Username, strlen(Username)+1);
logEval = 1;
commandCatcher();
}
else if(strcmp(Output, "none") == 0) {
printf("Command was denied. Please try again:\n");
commandCatcher();//recursive call
}
wait(&logEval);
printf("execution finished");
}
int main(){
printf("Welcome to Sys v1.0. To start off, please insert your command. \n");
commandCatcher();
return 0;
}
Upvotes: 0
Views: 26
Reputation: 3158
When you fork()
a process, it's children do not have access to the parent's address space. It will have a full copy of it, so anything that was set before the fork()
will be the same in the child, but if you update anything inside the child process the parent will not see it. You will need to use some form of inter-process communication (IPC) for this, such as shared memory or a pipe.
Upvotes: 1