Help debugging c fifos code - stack smashing detected - open call not functioning - removing pipes

Posted by nunos on Stack Overflow See other posts from Stack Overflow or by nunos
Published on 2010-05-20T17:18:38Z Indexed on 2010/05/20 17:20 UTC
Read the original article Hit count: 594

Filed under:
|
|
|
|

I have three bugs/questions regarding the source code pasted below:

  1. stack smashing deteced: In order to compile and not have that error I have addedd the gcc compile flag -fno-stack-protector. However, this should be just a temporary solution, since I would like to find where the cause for this is and correct it. However, I haven't been able to do so. Any clues?

  2. For some reason, the last open function call doesn't work and the programs just stops there, without an error, even though the fifo already exists.

  3. I want to delete the pipes from the filesystem after before terminating the processes. I have added close and unlink statements at the end, but the fifos are not removed. What am I doing wrong?

Thanks very much in advance.

P.S.: I am pasting here the whole source file for additional clarity. Just ignore the comments, since they are in my own native language.

server.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#define MAX_INPUT_LENGTH 100
#define FIFO_NAME_MAX_LEN 20
#define FIFO_DIR "/tmp/"
#define FIFO_NAME_CMD_CLI_TO_SRV "lrc_cmd_cli_to_srv"

typedef enum { false, true } bool;

bool background = false;
char* logfile = NULL;

void read_from_fifo(int fd, char** var)
{
    int n_bytes;
    read(fd, &n_bytes, sizeof(int));
    *var = (char *) malloc (n_bytes);
    read(fd, *var, n_bytes);
    printf("read %d bytes '%s'\n", n_bytes, *var);
}

void write_to_fifo(int fd, char* data)
{
    int n_bytes = (strlen(data)+1) * sizeof(char);
    write(fd, &n_bytes, sizeof(int)); //primeiro envia o numero de bytes que a proxima instrucao write ira enviar
    write(fd, data, n_bytes);
    printf("writing %d bytes '%s'\n", n_bytes, data);
}


int main(int argc, char* argv[])
{   
    //CRIA FIFO CMD_CLI_TO_SRV, se ainda nao existir

    char* fifo_name_cmd_cli_to_srv;
    fifo_name_cmd_cli_to_srv = (char*) malloc ( (strlen(FIFO_NAME_CMD_CLI_TO_SRV) + strlen(FIFO_DIR) + 1) * sizeof(char) );
    strcpy(fifo_name_cmd_cli_to_srv, FIFO_DIR);
    strcat(fifo_name_cmd_cli_to_srv, FIFO_NAME_CMD_CLI_TO_SRV);
    int n = mkfifo(fifo_name_cmd_cli_to_srv, 0660); //TODO ver permissoes
    if (n < 0 && errno != EEXIST) //se houver erro, e nao for por causa de ja haver um com o mesmo nome, termina o programa
    {
        fprintf(stderr, "erro ao criar o fifo\n");
        fprintf(stderr, "errno: %d\n", errno);
        exit(4);
    }

    //se por acaso já existir, nao cria o fifo e continua o programa normalmente


    //le informacao enviada pelo cliente, nesta ordem:
    //1. pid (em formato char*) do processo cliente
    //2. comando /CONNECT
    //3. nome de fifo INFO_SRV_TO_CLIXXX
    //4. nome de fifo MSG_SRV_TO_CLIXXX

    char* command;
    char* fifo_name_info_srv_to_cli;
    char* fifo_name_msg_srv_to_cli;
    char* client_pid_string;
    int client_pid;

    int fd_cmd_cli_to_srv, fd_info_srv_to_cli;

    fd_cmd_cli_to_srv = open(fifo_name_cmd_cli_to_srv, O_RDONLY);

    read_from_fifo(fd_cmd_cli_to_srv, &client_pid_string);
    client_pid = atoi(client_pid_string);
    read_from_fifo(fd_cmd_cli_to_srv, &command); //recebe commando /CONNECT
    read_from_fifo(fd_cmd_cli_to_srv, &fifo_name_info_srv_to_cli); //recebe nome de fifo INFO_SRV_TO_CLIXXX
    read_from_fifo(fd_cmd_cli_to_srv, &fifo_name_msg_srv_to_cli); //recebe nome de fifo MSG_TO_SRV_TO_CLIXXX


    //CIRA FIFO MSG_CLIXXX_TO_SRV

    char fifo_name_msg_cli_to_srv[FIFO_NAME_MAX_LEN];
    strcpy(fifo_name_msg_cli_to_srv, FIFO_DIR);
    strcat(fifo_name_msg_cli_to_srv, "lrc_msg_cli");
    strcat(fifo_name_msg_cli_to_srv, client_pid_string);
    strcat(fifo_name_msg_cli_to_srv, "_to_srv");

    n = mkfifo(fifo_name_msg_cli_to_srv, 0660);
    if (n < 0)
    {
        fprintf(stderr, "error creating %s\n", fifo_name_msg_cli_to_srv);
        fprintf(stderr, "errno: %d\n", errno);
        exit(5);
    }
    //envia ao cliente a resposta ao commando /CONNECT
    fd_info_srv_to_cli = open(fifo_name_info_srv_to_cli, O_WRONLY);
    write_to_fifo(fd_info_srv_to_cli, fifo_name_msg_cli_to_srv);

    free(logfile);
    free(fifo_name_cmd_cli_to_srv);

    close(fd_cmd_cli_to_srv);

    unlink(fifo_name_cmd_cli_to_srv);
    unlink(fifo_name_msg_cli_to_srv);
    unlink(fifo_name_msg_srv_to_cli);
    unlink(fifo_name_info_srv_to_cli);

    printf("fim\n");

    return 0;
}

client.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#define MAX_INPUT_LENGTH 100
#define PID_BUFFER_LEN 10
#define FIFO_NAME_CMD_CLI_TO_SRV "lrc_cmd_cli_to_srv"
#define FIFO_NAME_INFO_SRV_TO_CLI "lrc_info_srv_to_cli"
#define FIFO_NAME_MSG_SRV_TO_CLI "lrc_msg_srv_to_cli"
#define COMMAND_MAX_LEN 100
#define FIFO_DIR "/tmp/"

typedef enum { false, true } bool;

char* nickname;
char* name;
char* email;

void write_to_fifo(int fd, char* data)
{
    int n_bytes = (strlen(data)+1) * sizeof(char);
    write(fd, &n_bytes, sizeof(int)); //primeiro envia o numero de bytes que a proxima instrucao write ira enviar
    write(fd, data, n_bytes);
    printf("writing %d bytes '%s'\n", n_bytes, data);
}

void read_from_fifo(int fd, char** var)
{
    int n_bytes;
    read(fd, &n_bytes, sizeof(int));
    *var = (char *) malloc (n_bytes);
    printf("read '%s'\n", *var);
    read(fd, *var, n_bytes);
}    

int main(int argc, char* argv[])
{
    pid_t pid = getpid();

    //CRIA FIFO INFO_SRV_TO_CLIXXX

    char pid_string[PID_BUFFER_LEN];
    sprintf(pid_string, "%d", pid);
    char* fifo_name_info_srv_to_cli;
    fifo_name_info_srv_to_cli = (char *) malloc ( (strlen(FIFO_DIR) + strlen(FIFO_NAME_INFO_SRV_TO_CLI) + strlen(pid_string) + 1 ) * sizeof(char) );
    strcpy(fifo_name_info_srv_to_cli, FIFO_DIR);
    strcat(fifo_name_info_srv_to_cli, FIFO_NAME_INFO_SRV_TO_CLI);
    strcat(fifo_name_info_srv_to_cli, pid_string);

    int n = mkfifo(fifo_name_info_srv_to_cli, 0660);
    if (n < 0)
    {
        fprintf(stderr, "error creating %s\n", fifo_name_info_srv_to_cli);
        fprintf(stderr, "errno: %d\n", errno);
        exit(6);
    }

    int fd_cmd_cli_to_srv, fd_info_srv_to_cli;

    fd_cmd_cli_to_srv = open("/tmp/lrc_cmd_cli_to_srv", O_WRONLY);

    char command[COMMAND_MAX_LEN];

    printf("> ");
    scanf("%s", command);

    while (strcmp(command, "/CONNECT"))
    {
        printf("O primeiro comando deverá ser \"/CONNECT\"\n");
        printf("> ");
        scanf("%s", command);
    }

    //CRIA FIFO MSG_SRV_TO_CLIXXX

    char* fifo_name_msg_srv_to_cli;
    fifo_name_msg_srv_to_cli = (char *) malloc ( (strlen(FIFO_DIR) + strlen(FIFO_NAME_MSG_SRV_TO_CLI) + strlen(pid_string) + 1) * sizeof(char) );
    strcpy(fifo_name_msg_srv_to_cli, FIFO_DIR);
    strcat(fifo_name_msg_srv_to_cli, FIFO_NAME_MSG_SRV_TO_CLI);
    strcat(fifo_name_msg_srv_to_cli, pid_string);

    n = mkfifo(fifo_name_msg_srv_to_cli, 0660);
    if (n < 0)
    {
        fprintf(stderr, "error creating %s\n", fifo_name_info_srv_to_cli);
        fprintf(stderr, "errno: %d\n", errno);
        exit(7);
    }

    // ENVIA COMANDO /CONNECT

    write_to_fifo(fd_cmd_cli_to_srv, pid_string); //envia pid do processo cliente
    write_to_fifo(fd_cmd_cli_to_srv, command); //envia commando /CONNECT
    write_to_fifo(fd_cmd_cli_to_srv, fifo_name_info_srv_to_cli); //envia nome de fifo INFO_SRV_TO_CLIXXX
    write_to_fifo(fd_cmd_cli_to_srv, fifo_name_msg_srv_to_cli); //envia nome de fifo MSG_TO_SRV_TO_CLIXXX

    // recebe do servidor a resposta ao comanddo /CONNECT
    printf("msg1\n");
    printf("vamos tentar abrir %s\n", fifo_name_info_srv_to_cli);
    fd_info_srv_to_cli = open(fifo_name_info_srv_to_cli, O_RDONLY);
    printf("%s aberto", fifo_name_info_srv_to_cli);
    if (fd_info_srv_to_cli < 0) {
        fprintf(stderr, "erro ao criar %s\n", fifo_name_info_srv_to_cli);
        fprintf(stderr, "errno: %d\n", errno);
    }
    printf("msg2\n");
    char* fifo_name_msg_cli_to_srv;
    printf("msg3\n");
    read_from_fifo(fd_info_srv_to_cli, &fifo_name_msg_cli_to_srv);
    printf("msg4\n");

    free(nickname);
    free(name);
    free(email);
    free(fifo_name_info_srv_to_cli);
    free(fifo_name_msg_srv_to_cli);

    unlink(fifo_name_msg_srv_to_cli);
    unlink(fifo_name_info_srv_to_cli);

    printf("fim\n");

    return 0;
}

makefile:

CC = gcc
CFLAGS = -Wall -lpthread -fno-stack-protector

all: client server

client: client.c
    $(CC) $(CFLAGS) client.c -o client

server: server.c
    $(CC) $(CFLAGS) server.c -o server

clean:
    rm -f client server *~

© Stack Overflow or respective owner

Related posts about c

    Related posts about fifo