0

In an exercise problem, I am required to build a client program (write first) that opens a .txt file, put each line and the total bytes of each line into a struct variable and then send it out to the server program (read first). Right after this is done, the client program will also receive a struct file (similarly only has char * and int attributes) from the server program.

// Below are global variables in both programs
#define BUFSIZE 1024

struct info_pack
{
    char line[BUFSIZE]; // the line to receive messages
    int bytes; // the bytes of data transferred
};

char fifo_path[] = "./my_fifo";
struct info_pack info_w; // the info_pack for writing each line in text.txt
struct info_pack info_r; // the info_pack for reading feedback info_pack sent from the server program

First is the client program:

// the main() in the client program
int main()
{
    int fd;
    int i = 0, index = 1, bytes = 0, line_length, fifo_read;
    char *file_path = "/home/text.txt";
    FILE *fd2;
    
    mkfifo(fifo_path, 0666);
    if ((fd2 = fopen(file_path, "r")) < 0)
    {
        perror("Opening file");
        return -1;
    }
    else
    {
        printf("Successfully open the target file\n");
        while (fgets(info.line, BUFSIZE, fd2) != NULL)
        // the "segmentation fault" error appears right after this line

        {
            info_w.bytes = strlen(line);
            
            fd = open(fifo_path, O_WRONLY);
            printf("The %d th line sent out is: %s\n%d bytes are sent\n\n", 
                    index, info_w.line, info_w.bytes);
            write(fd, &info_w, sizeof(info_w) + 1);
            close(fd);
            
            fd = open(fifo_path, O_RDONLY);
            fifo_read = read(fd, &info_r, sizeof(info_r));
            close(fd);
           
            if (fifo_read > 0)
            {
                printf("Feedback: %s\nand %d bytes are returned\n", info_r.line, info_r.bytes);
            }
        }
        printf("All data is successfully transfered\n");
    }
    return 0;
}

Then is the server program

// the main() in the server program
int main()
{
    int fd, fifo_read;
    int line_length;
    char *feedback = "SUCCESS";
    
    strcpy(info_w.line, feedback);
    info_w.bytes = strlen(feedback);
    // define a constant info_pack variable to send to the client program

    if (mkfifo(fifo_path, 0666) < 0)
    {
        perror("client end: ");
        exit(-1);
    }
    while (1)
    // This server program will wait for any one single client's message
    // This server program can only be terminated by manually input signals (like ^\)
    {
        fd = open(fifo_path, O_RDONLY);
        printf("waiting for client's message\n");
        fifo_read = read(fd, &info_r, sizeof(info_r));
        close(fd);
        
        if (fifo_read > 0)
        // if receive the struct variable, print all of its attributes
        {
            if (info_r == NULL)
                printf("Found no lines sent from the client\n");
            else
                printf("Read from fifo:\n %s\n(in info)%d bytes read  (actually)%d bytes read\n", info_r.line, info_r.bytes, fifo_read);
        }
        else
        {
            sleep(1);
            printf("Fail to read data from the client\n");
        }
        // Because of the error in client program this server program
        // always pause here        

        fd = open(fifo_path, O_WRONLY);
        printf("Now writing feedback to the client\n");
        write(fd, info_w, sizeof(info_w));
        close(fd);
    }
}

Could anyone explain why the segmentation fault error appears in the client program? Then I can test if the both the client and the server can co-op properly.By the way, I read this post already but, in this post, it is a one-time data stream and I cannot find any hints in it.

  • 'line' is used uninitialized - UB. – Martin James Apr 05 '21 at 10:03
  • Do you mean the ```char *line``` in the client program? I assume if it needs be initialized I will be prompted an error but it seems fine – Sanae Kochiya Apr 05 '21 at 15:26
  • Oh, it absolutely does need to be initialized to point at a valid address. I would expect a warning at least for passing it as an argument before initialization. Turn your compiler warning/error levels up to 11. – Martin James Apr 06 '21 at 17:59
  • Thank you for your comments. I change definition of those global struct variables and now my code is working – Sanae Kochiya Apr 06 '21 at 18:48

0 Answers0