Rob, you can use the MSG_PEEK flag on recv(2) instead of relying on stdio FILE* handles.
发件人: Rob Landley via austin-group-l at The Open Group <austin-group-l@opengroup.org> 日期: 星期二, 2022-04-12 05:59:31 收件人: Rich Felker <dal...@libc.org> 抄送: austin-group-l@opengroup.org <austin-group-l@opengroup.org> 主题: Re: How do I get the buffered bytes in a FILE *? On 4/11/22 15:41, Rich Felker wrote: >> But I can't find a portable way to do this? > > To give some context to this question, the __freadahead function > present in musl libc was created in 2012 to resolve a conflict between > gnulib, which has traditionally used an #ifdef jungle to provide > "freadahead" and other functionality by poking at FILE internals for > each known target they support, and musl, which explicitly makes FILE > an opaque non-ABI type. The idea was to let them implement the > function in a way that keeps the private member accesses on the stdio > implementation side. > > While I don't like this interface, gnulib is longstanding historical > precedent for its existence ~somewhere~ (just not as part of the > implementation), and it's historical precedent for major software > wanting this kind of access to stdio. I just emailed the chair of the C standard group and 90% of his reply was about text vs binary mode with FILE * (which is not present in Linux, MacOS, Android, iOS, Solaris, any embedded OS I've encountered...) I'm personally fine with fileno() returning -1 when the FILE * is in text mode, let alone freadahead(). Even the coreutils developers are noping out of support for things like cygwin now that Windows Subsystem for Linux exists: https://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.gnu.org%2Farchive%2Fhtml%2Fcoreutils%2F2022-04%2Fmsg00038.html&data=04%7C01%7C%7Cd6b866684e314bcdb99f08da1c068c38%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637853111716104245%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=qW6cnH8rwWc%2Bwv%2BQrfB4Di10WhaBgNBPdVLsjMvKnCM%3D&reserved=0 The C committee chair then said: > File descriptors are outside the scope of the C standard, so any > support for switching back and forth between streams and file > descriptors belongs elsewhere. I.E. ANSI C doesn't have read(), write(), or open(). They don't do ANYTHING with file descriptors. That's why fileno() and fdopen() are only in posix, not in ANSI C. And the issues I'm currently trying to solve are a result of getline() showing up in posix-2008, which also does not exist in ANSI C. Thus an freadahead() function to encapsulate the horrible #ifdef staircase people are already repeatedly reinventing belongs in Posix, not ANSI. The function is needed to make Posix's existing fileno() reliable, and in the absence of a standard this has already been reimplemented multiple times. GNU has attempted to centralize its workaround collection in gnulib: https://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdigitalocean%2Fgnulib%2Fblob%2Fmaster%2Flib%2Ffreadahead.c&data=04%7C01%7C%7Cd6b866684e314bcdb99f08da1c068c38%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637853111716104245%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=y4vMMkD3zqnD7QCbH5i3Q6jUGEIl2UAY1znerzOg%2FNc%3D&reserved=0 (Leading to a bunch of patches for m4 and glib coming up when you google for freadahead because said staircase breaks a lot.) But even IBM Z/OS implemented __freadahead(): https://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.ibm.com%2Fdocs%2Fen%2Fzos%2F2.4.0%3Ftopic%3Dlf-freadahead-retrieve-number-bytes-remaining-in-input-buffer%23freadahead&data=04%7C01%7C%7Cd6b866684e314bcdb99f08da1c068c38%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637853111716104245%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=i7WGhxZ9VW21u1Az3Yc6lcl3DZLTQcswfc8wLb6SK3M%3D&reserved=0 The lack of this function derailed a port to VMS a few years back: https://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsourceforge.net%2Fp%2Fvms-ports%2Ftickets%2F61%2F&data=04%7C01%7C%7Cd6b866684e314bcdb99f08da1c068c38%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637853111716104245%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=H30KHDv8zLCzMUYrWmEDe1VVR7ZPmwSu7i1eRdd4FNc%3D&reserved=0 Here's somebody trying to update i386 support in buildroot and guess what they needed to patch: https://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.zephray.me%2Fpost%2Fcreate_coremark_boot_disk_for_386%2F%23%3A~%3Atext%3Dfreadahead&data=04%7C01%7C%7Cd6b866684e314bcdb99f08da1c068c38%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637853111716104245%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=fT0ive9CHUOpphQqo0ePRbtWTnYK1XlHhY7EGmTuChs%3D&reserved=0 *shrug* This is a thing people are reimplementing a lot. Rob