You are not logged in.

#1 2023-03-10 23:15:38

Iulian
Member
Registered: 2019-08-01
Posts: 24

fopen() fails on symlinks to directories

void TarMaker::writeFileToArchive(const std::string& path)
{
    static const size_t BUFF_SIZE = 1024;
    char buffer[BUFF_SIZE] = {};

    FILE* file = fopen(path.c_str(), "rw");
    if (file == NULL)
    {
        throw archive_exception("Cannot open file " + path + " reason: " + std::to_string(errno));
    }

    while(true)
    {
        size_t read = fread(buffer, sizeof(*buffer), BUFF_SIZE, file);
        
        if(fread > 0)
            archive_write_data(m_pArchiveDescrptor, buffer, read);
        if(feof(file))
            break;
        if(ferror(file))
        {
            fclose(file);
            throw archive_exception("Failed to read from file " + path + " : " + std::to_string(errno));
        }
    }
    fclose(file);
}

i have this snippet that i call to read the contents of a file so i can add it to a tar file that i am making,
the problem is that on symlinks to directories it fails what.

what's different i would assume that a symlink to a file is the same as a symlink to a directory

Offline

#2 2023-03-11 09:03:25

dimich
Member
From: Kharkiv, Ukraine
Registered: 2009-11-03
Posts: 237

Re: fopen() fails on symlinks to directories

I'm not sure i understand the question correctly. Do you want to distinguish symlink to a file from symlink to a directory? You can `stat()` path and `readlink()` if it is a symlink. Probably you need to do it recursively to handle symlink pointing to another symlink. However i'd do it on upper level and call WriteFileToArchive() with regular file path only.

Offline

#3 2023-03-11 20:38:58

rowdog
Member
From: East Texas
Registered: 2009-08-19
Posts: 118

Re: fopen() fails on symlinks to directories

You can use realpath(3) to get the absolute path and then open that.

You can use open(2) to get a file descriptor and then fdopen(3) the fd.

int fd = open(path, O_RDONLY);
if (fd == -1) {
    perror("open");
    exit(-1);
}
FILE *handle = fdopen(fd, "r");
...
fclose(handle);

Offline

Board footer

Powered by FluxBB