Skip to main content
3 of 7
added 176 characters in body

Code dealing with files and separate lines in them

I have been using similar piece of code since a while.
I have read some issues regarding treating mapped memory as a string. I am not sure about that though.
So I just use strndup(3) to avoid it anyway. Wanted some reviews on this code:

#include <sys/mman.h>
#include <sys/stat.h>

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct MyFile {
    const char *filename;
    int fd;
    size_t size;
    char *contents;
};

int setup_myfile(const char *filename, struct MyFile *file);
void clean_myfile(struct MyFile file);

int
main(int argc, char *argv[])
{
    if (argc != 2) {
        fprintf(stderr, "usage: %s filename\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    
    struct MyFile my_file;
    char *contents, *line, *to_free;

    int err = setup_myfile(argv[1], &my_file);

    if (err == -1) {
        fprintf(stderr, "setup_myfile() failed\n");
        exit(EXIT_FAILURE);
    }

    to_free = contents = strndup(my_file.contents, my_file.size);

    if (to_free == NULL) {
        perror("strndup(3)");
        exit(EXIT_FAILURE);
    }

    while ((line = strsep(&contents, "\n")) != NULL) {

        // Print line by line or do anything with line
        printf("%s", line);
    }

    free(to_free);
    clean_myfile(my_file);
    
    return 0;
}

int
setup_myfile(const char *filename, struct MyFile *file)
{
    struct stat st;
    
    file->filename = filename;
    file->fd = open(file->filename, O_RDONLY);

    if (file->fd == -1) {
        perror("open(2)");
        return -1;
    }

    if (fstat(file->fd, &st) == -1) {
       perror("fstat(2)");
       return -1;
    }

    file->size = st.st_size;    

    file->contents = mmap(NULL, file->size, PROT_READ | PROT_WRITE, MAP_PRIVATE, file->fd, 0);

    if (file->contents == MAP_FAILED) {
        perror("mmap(2)");
        return -1;
    }

    return 0;
}

void
clean_myfile(struct MyFile file)
{
    munmap(file.contents, file.size);
    close(file.fd);
}