Reputation: 81
As an assignment I got at my university to send arguments to Server, then server needs to calculate and send the result back to the Client. I need to make 2 .c files(client and server). Then, compile them using gcc command(gcc client.c -o client.out) and run the server first, let it run in the background(CTRL+Z), get it's PID('ps' command) and then run the client with those arguments:
The code is written in C, and my workspace is Linux terminal using Putty. The problem is that when I use the "kill" command in my client file(I called it "c.c") in order to send a signal to a specific process that I have it's PID(which is the server) , The handler of the server doesn't wake up and start working and of course because of that, it won't send a "kill" command back to the client with result. Jokes aside, I literally sat 24 hours(I'm mean.. for real lol), and since it's 5am I really need to get some rest I'm starting to get delusional and I have less then 24 hours to submit the assignment :( . Below I shared my code, I hope it's understandable, I tried to do my best guys.
Client.c:
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#define GODEL 100
char* reqArgs[5];
void sigterm_handler(int dummy)
{
char msg[150];
int clientPID, toClientFD, res, signalCharsR;
pid_t pid;
clientPID = getpid();
char* toClientFileName = (char*)malloc(strlen("to_client_") + strlen(reqArgs[4]) + strlen(".txt") + 1);
strcat(toClientFileName, "to_client_");
strcat(toClientFileName, reqArgs[4]);
strcat(toClientFileName, ".txt");
// Open the result file(to_client_XXXXX) from Server
toClientFD = open(toClientFileName, O_RDONLY, 0777);
if(toClientFD == -1)
{
sprintf(msg, "Could not Open file: to_client_%d.txt\n", clientPID);
write(2, msg, strlen(msg));
exit(-1);
}
// Read the result from the results file(to_client_XXXXX)
signalCharsR = read(toClientFD, msg, strlen(toClientFileName));
if(signalCharsR == -1)
{
sprintf(msg, "Could not Read result from file: to_client_%d.txt\n", clientPID);
write(2, msg, strlen(msg));
exit(-1);
}
write(1, msg, sizeof(msg));
signal(SIGTERM, sigterm_handler);
exit(0);
}
int main(int argc, char* argv[])
{
char msg[150];
int logFD, reqFD, charsR = 0;
pid_t pid;
if(argc != 5)
{
strcpy(msg, "Wrong number of arguments\n");
write(2, msg, strlen(msg));
exit(-1);
}
signal(SIGTERM, sigterm_handler);
for(int i = 0; i<argc; i++)
reqArgs[i] = argv[i];
// Open request.txt, Creates it if doesn't exist
reqFD = open("request.txt", O_CREAT | O_RDONLY | O_WRONLY | O_APPEND, 0777);
if(reqFD == -1)
{
strcpy(msg, "Could not Create and Open file: request.txt\n");
write(2, msg, strlen(msg));
exit(-1);
}
// Open cLog.txt file
logFD = open("cLog.txt", O_CREAT | O_RDONLY | O_WRONLY | O_APPEND, 0777);
if(logFD == -1)
{
strcpy(msg, "Could not Create and Open file: request.txt\n");
write(2, msg, strlen(msg));
exit(-1);
}
close(1);
dup(logFD);
close(logFD);
// Writing into request.txt
for(int i = 2; i<argc; i++)
{
charsR = write(reqFD, argv[i], strlen(argv[i]));
if(charsR == -1)
{
strcpy(msg, "Could not write to file: request.txt\n");
write(2, msg, strlen(msg));
exit(-1);
}
write(reqFD, "\n", 1);
}
char mypid[5];
sprintf(mypid, "%d", pid);
write(reqFD, mypid, sizeof(mypid));
close(reqFD);
signal(SIGTERM, sigterm_handler);
// Sending KILL to the Server
if(kill(atoi(argv[1]), SIGTERM) == -1){
write(2, "Could not send signal\n", strlen("Could not send
signal\n"));
}
// Sleeping until Server sends back a result
while(1){
sleep(1);
}
exit(1);
}
Server:
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
int calculator(int x, int y, int op)
{
switch(op)
{
case 1:
return x+y;
break;
case 2:
return x-y;
break;
case 3:
return x*y;
break;
case 4:
if(y == 0)
return -1;
return x/y;
break;
default:
return -1;
}
return -1;
}
void sigterm_handler(int dummy)
{
char msg[150];
pid_t pid;
// Forking
pid = fork();
if(pid < 0)
{
//printf("EX2_FROM_ERROR\n");
strcpy(msg, "Could not Fork\n");
write(2, msg, strlen(msg));
printf("Could not Fork\n");
exit(-1);
}
else
{
// Son
if(pid == 0)
{
int logFD, fd, bytesRead, x, y, op, res;
char ch;
char* reqArgs[4];
// Open request.txt file
fd = open("request.txt", O_RDONLY, 0777);
if(fd == -1)
{
strcpy(msg, "Could not open file: request.txt\n");
write(2, msg, strlen(msg));
exit(-1);
}
// Reading lines from request.txt file;
for(int i = 0; i < 4; i++) {
int j = 0;
bytesRead = read(fd, &ch, 1);
while(ch != '\n' && bytesRead != 0) {
reqArgs[i][j] = ch;
bytesRead = read(fd, &ch, 1);
j++;
}
reqArgs[i][j] = '\0'; // put null at the end
}
close(fd); // Close request.txt File
// Initialize the data into variables
x = atoi(reqArgs[0]);
op = atoi(reqArgs[1]);
y = atoi(reqArgs[2]);
printf("%d+%d+%d=", x, op, y);
// Creating result file to send to the client
char* toClientFileName = (char*)malloc(strlen("to_client_") + strlen(reqArgs[3]) + strlen(".txt") + 1);
strcat(toClientFileName, "to_client_");
strcat(toClientFileName, reqArgs[3]);
strcat(toClientFileName, ".txt");
fd = open(toClientFileName, O_CREAT | O_RDWR | O_APPEND, 0777);
if(fd == -1)
{
sprintf(msg, "Could not Create and Open file: %s\n", toClientFileName);
write(2, msg, strlen(msg));
//printf("Could not Create and Open file: %s\n", toClientFileName);
exit(-1);
}
// Calling the calc() function
res = calculator(x, y, op);
if(res =! -1)
write(fd, &res, sizeof(res));
else
write(fd, "Calculate went wrong\n", strlen("Calculate went wrong")+1);
close(fd);
signal(SIGTERM, sigterm_handler);
char test[5];
sprintf(test, "%d", atoi(reqArgs[3]));
// Sending KILL back to the Client
if(kill(atoi(test), SIGTERM) == -1){
write(2, "Could not send signal\n", strlen("Could not send
signal\n"));
}
}
// Father
else
{
}
}
signal(SIGTERM, sigterm_handler);
}
int main(int argc, char* argv[])
{
signal(SIGTERM, sigterm_handler);
while(1){
sleep(10);
}
exit(1);
}
Upvotes: 1
Views: 1176
Reputation: 2735
ctrl-z
merely stops the forground process. It does not send it to the background. You need to resume the process as background process using bg $n
where n
is the job number shown in brackets after you stopped the server, [1]
as seen in your terminal screenshot:
bg $1
Upvotes: 1