Junius L
Junius L

Reputation: 16142

Reading and writing pdf or binary data in C

I'm implementing ftp and I want to upload and download files, when I download or upload pdf files they are corrupted. How can handle reading any file, using read() and write() or mmap? below is my simplified code of what I have tried.

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

int     is_regular_file(const char *path)
{
    struct stat path_stat;

    stat(path, &path_stat);
    return (S_ISREG(path_stat.st_mode));
}

int     ft_get_file_size(const char *filename)
{
    struct stat file;
    int         fd;

    if (!is_regular_file(filename))
        return (-1);
    fd = open(filename, O_RDONLY);
    memset(&file, 0, sizeof(struct stat));
    fstat(fd, &file);
    close(fd);
    return (file.st_size);
}

char    *read_file(const char *filename)
{
    char    *content;
    int     file_size;
    int     fd;
    ssize_t retval;

    if ((file_size = ft_get_file_size(filename)) <= 0)
        return (NULL);
    content = (char *)malloc(sizeof(char) * file_size + 1);
    fd = open(filename, O_RDONLY);
    retval = read(fd, content, file_size);
    content[retval + 1] = '\0';
    close(fd);
    return (content);
}

void    write_file(char *file, char *content)
{
    int fd;

    fd = open(file, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR);
    if (fd)
        write(fd, content, strlen(content));
    close(fd);
}

int main() {
    char *test = read_file("ftp.en.pdf");
    write_file("copy.pdf", test);
    return EXIT_SUCCESS;
}

The process of downloading and uploading the file, is reading all the data from the file and then send that data to the socket. I have tried using mmap and I still get corrupted file.

Document is damaged error message

Corrupted file

Upvotes: 0

Views: 100

Answers (1)

Paul Ogilvie
Paul Ogilvie

Reputation: 25286

As binary data can have \0 characters, you cannot treat your content as a string, so strlen(content) is wrong. You must return the size of the content from your read_file function.

For example, define your function as char *read_file(const char *filename, int *size) and return the size in *size. Likewise define your write function as void write_file(char *file, char *content, int size)

(and forget the +1 in malloc)

Upvotes: 4

Related Questions