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