my program was to be a terminal communicator between clients. So the first terminal should be a server, second and third should be clients. The servers starts with ./program --start, and the clients should log in with ./program --login [name]. Then they should write to each other with the TO [name] [message], but it doesnt work. Something is wrong with writing the message from terminal to FIFO, kind of the program dont want to respond on what i wrote in terminal. Do you know where is the problem? Im confused
//program.h
#ifndef SERVER_H
#define SERVER_H
#define MSG_SIZE 256
#define MAX_USERS 10
typedef struct user {
int pid;
char name[20];
char fifo[50];
int fd;
} user;
void handle_sigquit(int sig);
#endif
//program.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include "server.h"
int num_users = 0;
user users[MAX_USERS];
void handle_sigquit(int sig)
{
printf("Server is shuting down\n");
exit(0);
}
void server()
{
signal(SIGQUIT, handle_sigquit);
mkfifo("server_fifo", 0666);
int server_fifo = open("server_fifo", O_RDONLY | O_NONBLOCK);
printf("Server has started.\n");
while (1)
{
char buffer[1024];
int num_read = read(server_fifo, buffer, sizeof(buffer));
if (num_read > 0)
{
buffer[num_read] = '\0';
printf("You received the message from: %s\n", buffer);
char *name = strtok(buffer, " ");
char *message = strtok(NULL, "\n");
int i;
for (i = 0; i < num_users; i++)
{
if (strcmp(name, users[i].name) == 0)
{
write(users[i].fd, message, strlen(message));
printf("The message has been written to: %s.\n", name);
break;
}
}
if (i == num_users)
{
printf("User doesn't exists.\n");
}
}
}
}
void client(int fd, int sender_pid, char *name)
{
if (num_users == MAX_USERS)
{
printf("Max users.\n");
}
char fifo_name[50];
sprintf(fifo_name, "%s_fifo", name);
mkfifo(fifo_name, 0666);
int user_fifo = open(fifo_name, O_RDONLY | O_NONBLOCK);
if (user_fifo == -1)
{
perror("open user fifo");
exit(1);
}
char msg[MSG_SIZE];
memset(msg, 0, sizeof(msg));
while (1)
{
int bytes_read = read(user_fifo, msg, MSG_SIZE);
if (bytes_read == -1)
{
perror("read user fifo");
exit(1);
}
if (bytes_read == 0)
{
usleep(1000);
continue;
}
char *tok = strtok(msg, " ");
if (tok == NULL)
{
continue;
}
if (strcmp(tok, "TO") == 0)
{
tok = strtok(NULL, " ");
if (tok == NULL)
{
continue;
}
int to_user = -1;
for (int i = 0; i < num_users; i++)
{
if (strcmp(users[i].name, tok) == 0)
{
to_user = i;
break;
}
}
if (to_user == -1)
{
continue;
}
tok = strtok(NULL, "");
if (tok == NULL)
{
continue;
}
int to_user_fifo = open(users[to_user].name, O_WRONLY | O_NONBLOCK);
if (to_user_fifo == -1)
{
continue;
}
char reply[MSG_SIZE + 32];
snprintf(reply, MSG_SIZE + 32, "FROM %s %s", fifo_name, tok);
if (write(to_user_fifo, reply, strlen(reply) + 1) == -1)
{
perror("write to user fifo");
}
close(to_user_fifo);
}
else if (strcmp(tok, "REGISTER") == 0)
{
if (num_users >= MAX_USERS)
{
continue;
}
tok = strtok(NULL, "");
if (tok == NULL)
{
continue;
}
/* Dodaj użytkownika */
struct user u;
u.pid = getpid();
strncpy(u.name, tok, 31);
u.name[31] = '\0';
users[num_users++] = u;
}
else if (strcmp(tok, "UNREGISTER") == 0)
{
tok = strtok(NULL, "");
if (tok == NULL)
{
continue;
}
int index = -1;
for (int i = 0; i < MAX_USERS; i++)
{
if (users[i].pid == sender_pid)
{
index = i;
break;
}
}
if (index == -1)
{
char *error_msg = "ERROR: User not registered.\n";
write(fd, error_msg, strlen(error_msg));
exit(1);
}
char message[MSG_SIZE];
volatile int msg_size = sizeof(message);
snprintf(message, msg_size, "[%s] %s", users[index].name, msg);
for (int i = 0; i < MAX_USERS; i++)
{
if (users[i].pid != 0 && users[i].pid != sender_pid)
{
int user_fifo = open(users[i].fifo, O_WRONLY | O_NONBLOCK);
if (user_fifo != -1)
{
write(user_fifo, message, strlen(message));
close(user_fifo);
}
}
}
}
}
}
int main(int argc, char *argv[])
{
int fd;
int sender_pid = -1;
char *name = argv[2];
if (argc == 2 && strcmp(argv[1], "--start") == 0)
{
server();
}
else if (argc == 3 && strcmp(argv[1], "--login") == 0)
{
client(fd, sender_pid, name);
}
}
I tried a lot, most of changing something with fifo's code.