Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 12 Dec 2025 15:20:55 +0000
From:      bugzilla-noreply@freebsd.org
To:        bugs@FreeBSD.org
Subject:   [Bug 291610] libc stdio breaks when file descriptor greater than 32767
Message-ID:  <bug-291610-227@https.bugs.freebsd.org/bugzilla/>

index | next in thread | raw e-mail

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=291610

            Bug ID: 291610
           Summary: libc stdio breaks when file descriptor greater than
                    32767
           Product: Base System
           Version: 14.3-RELEASE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Many People
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: kris@tranception.com

A long running production application failed with errno EMFILE/24/Too many open
files.

The application did have a large number of open sockets, memory mapped files
and other file handles open but well under one hundred thousand and certainly
far, far less than the resource and kernel limits which were all over twenty
million.

kern.maxfiles: 25154691
kern.maxfilesperproc: 22639221
ulimit -nS: 22639221

Investigation revealed that the errno was not actually returned by a syscall in
the kernel but was due to a hard coded limitation in freebsd's libc that fails
operations where the file descriptor exceeds the range of a sixteen bit signed
integer.

Others have come across this bug in decades past, I found this particular bug
was first reported here as bug #148581 over fifteen years ago in 2010, and then
again as bug #172332 in 2012, and then again as bug #203900 in 2015.

I can see that the logic to fail returning EMFILE when the passed in file
descriptor exceeded SHRT_MAX was added to fopen, fdopen, freopen in libc stdio
in 2008 in commit c55d7e868aeb0 and then to vdprintf in 2009 in commit
ad760e6fc9393 (where the commit hashes are from git.freebsd.org/src.git), and
that the justification at the time was sound, namely that it is better to fail
the operation than to leak a file descriptor given that _file in struct FILE
was both a short int and not as opaque as it should have been.

Now, 17 years later, the freebsd kernel and freebsd libc still do not agree on
the valid range of a file descriptor, the former offering millions and the
latter insisting that just over thirty thousand will do, which is a surprising
state of affairs for an operating system with its kernel and userland developed
jointly as a holistic, coherent whole.

It also means that it is not currently possible to safely run a process on
freebsd that might open more than 32,767 files, sockets, etc. that also uses
libc stdio, which can be difficult to avoid in practice given how often other
libraries and components build on top of stdio.

Having only come fairly recently to freebsd's relative sanity from the land of
flightless, aquatic birds (and mutants thereof), I really do not want to go
back though an issue such as this if left another ten years would be an
unfortunate exception.

-- 
You are receiving this mail because:
You are the assignee for the bug.

home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-291610-227>