Skip to content

Conversation

nielsdos
Copy link
Member

@nielsdos nielsdos commented Sep 6, 2025

On Linux, these two character devices are exceptions in that they can be seeked. Check their major/minor device number.

On Linux, these two character devices are exceptions in that they can be
seeked. Check their major/minor device number.
@nielsdos nielsdos requested a review from bukka as a code owner September 6, 2025 12:21
@nielsdos nielsdos linked an issue Sep 6, 2025 that may be closed by this pull request
#if defined(S_ISFIFO) && defined(S_ISCHR)
if (self->fd >= 0 && do_fstat(self, 0) == 0) {
#ifdef __linux__
if (S_ISCHR(self->sb.st_mode)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note that not just linux, allows some character devices being seekable, e.g. freebsd and very likely macos. The equivalent for freebsd at least, can t rely on device versions at all but on a "poorer" solution such as if fseek returns -1 and errno is ESPIPE then it is not seekable.

@divinity76
Copy link
Contributor

/dev/mem and /dev/kmem and /dev/port are also seekable.
actually seems there are a lot of seekable character devices.
How about

#ifdef __linux__
    if (S_ISCHR(self->sb.st_mode)) {
        if (major(self->sb.st_rdev) == 1) {
            unsigned m = minor(self->sb.st_rdev);
            self->is_seekable =
                m == 1 ||   /* /dev/mem   */
                m == 2 ||   /* /dev/kmem  */
                m == 3 ||   /* /dev/null  */
                m == 4 ||   /* /dev/port  (seekable, offset = I/O port) */
                m == 5 ||   /* /dev/zero  */
                m == 7;     /* /dev/full  */
        } else {
            self->is_seekable = false;
        }
    } else {
        self->is_seekable = !S_ISFIFO(self->sb.st_mode);
    }
#else

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

unable to fseek in /dev/zero and /dev/null
3 participants