bug-gzip
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#75405: gzip --synchronous doesn't work with musl


From: Lasse Collin
Subject: bug#75405: gzip --synchronous doesn't work with musl
Date: Mon, 6 Jan 2025 15:29:22 +0200

On Linux/musl:

    $ echo foo > foo
    $ gzip --synchronous foo

    gzip: foo.gz: Bad file descriptor

From gzip.c:

      dfd = open (dfname, O_SEARCH | O_DIRECTORY);

...

        if ((synchronous
             && ((0 <= dfd && fdatasync (dfd) != 0 && errno != EINVAL)
                 || (fsync (ofd) != 0 && errno != EINVAL)))
            || close (ofd) != 0)
          write_error ();

In musl, O_SEARCH maps to Linux-specific O_PATH which doesn't allow
fsync or fdatasync. Gnulib's fcntl module's docs already warn about a
similar situation with fchmod.

As far as I understand this, O_SEARCH in POSIX is only meant for openat
and such APIs. Then it makes sense that O_SEARCH becomes O_PATH because
O_PATH can open a directory that lacks read permission. This way openat
can be used even for such directories.

Maybe there is no way to sync a directory that only has write and search
permissions. Luckily such a combination is rare.

A short fix is using O_RDONLY when --synchronous has been specified:

      dfd = open (dfname, (synchronous ? O_RDONLY : O_SEARCH)
                          | O_DIRECTORY);

I also tried opening a separate file descriptor for syncing (see the
attachment) but I think the above change is better. However, both have
a weakness that if the directory cannot be opened, --synchronous will
silently skip syncing the directory. It would be safer to show an error
if the directory cannot be opened when --synchronous has been specified.

-- 
Lasse Collin

Attachment: dfd_sync.patch
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]