This is a recipe for bringing the system into a state where the FILE type is opaque for libc users (unless they -D_EXPOSE__sFILE).
1. Apply the attached diff. 2. cd /usr/src/lib/libc && make && make install 3. Do step 3 of release(8). After that transition, I changed "short _file;" into "int _file;" (src/include/stdio.h), and step 3 of release(8) worked (step 2 too). Changed files: include/stdio.h Implement the _EXPOSE__sFILE toggle and declare the variables std{in,out,err}. Declare a function that will be needed by perl. lib/libc/stdio/findfp.c Define the variables std{in,out,err}. lib/libc/stdio/Makefile.inc Enable _EXPOSE__sFILE for the libc build. lib/libc/stdio/fileno.c Define the function that perl wants. gnu/usr.bin/perl/perlio.c Make perl use the new function. bin/pax/pax.c usr.bin/audioctl/audioctl.c usr.bin/tcopy/tcopy.c usr.sbin/amd/amd/xutil.c usr.sbin/amd/amd/amd.c Move some initializations to main() because std{in,out,err} are not constant anymore. Index: include/stdio.h =================================================================== RCS file: /cvs/src/include/stdio.h,v retrieving revision 1.35 diff -u -r1.35 stdio.h --- include/stdio.h 13 Jan 2006 18:10:09 -0000 1.35 +++ include/stdio.h 8 Jun 2009 14:40:17 -0000 @@ -73,6 +73,7 @@ * by a three-character attempt at a mnemonic. */ +#ifdef _EXPOSE__sFILE /* stdio buffers */ struct __sbuf { unsigned char *_base; @@ -136,9 +137,16 @@ int _blksize; /* stat.st_blksize (may be != _bf._size) */ fpos_t _offset; /* current lseek offset */ } FILE; +#else +typedef struct __sFILE FILE; +#endif /* _EXPOSE__sFILE */ __BEGIN_DECLS +#ifdef _EXPOSE__sFILE extern FILE __sF[]; +#else +extern FILE *stdin, *stdout, *stderr; +#endif __END_DECLS #define __SLBF 0x0001 /* line buffered */ @@ -200,9 +208,11 @@ #define SEEK_END 2 /* set file offset to EOF plus offset */ #endif +#ifdef _EXPOSE__sFILE #define stdin (&__sF[0]) #define stdout (&__sF[1]) #define stderr (&__sF[2]) +#endif /* * Functions defined in ANSI C standard. @@ -347,6 +357,7 @@ int vasprintf(char **, const char *, __va_list) __attribute__((__format__ (printf, 2, 0))) __attribute__((__nonnull__ (2))); +void invalidate_fileno(FILE *); __END_DECLS /* @@ -363,6 +374,7 @@ #define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0) #endif /* __BSD_VISIBLE */ +#ifdef _EXPOSE__sFILE /* * Functions internal to the implementation. */ @@ -429,6 +441,7 @@ #define putc_unlocked(x, fp) __sputc(x, fp) #endif /* __BSD_VISIBLE */ #endif /* lint */ +#endif /* _EXPOSE__sFILE */ #define getchar() getc(stdin) #define putchar(x) putc(x, stdout) Index: lib/libc/stdio/findfp.c =================================================================== RCS file: /cvs/src/lib/libc/stdio/findfp.c,v retrieving revision 1.9 diff -u -r1.9 findfp.c --- lib/libc/stdio/findfp.c 8 Aug 2005 08:05:36 -0000 1.9 +++ lib/libc/stdio/findfp.c 8 Jun 2009 08:06:23 -0000 @@ -63,6 +63,11 @@ }; struct glue __sglue = { &uglue, 3, __sF }; +#undef stdin +#undef stdout +#undef stderr +FILE *stdin = &__sF[0], *stdout = &__sF[1], *stderr = &__sF[2]; + static struct glue * moreglue(int n) { Index: lib/libc/stdio/Makefile.inc =================================================================== RCS file: /cvs/src/lib/libc/stdio/Makefile.inc,v retrieving revision 1.13 diff -u -r1.13 Makefile.inc --- lib/libc/stdio/Makefile.inc 17 Jun 2005 20:40:32 -0000 1.13 +++ lib/libc/stdio/Makefile.inc 8 Jun 2009 08:18:22 -0000 @@ -4,6 +4,7 @@ .PATH: ${LIBCSRCDIR}/stdio CFLAGS+=-DFLOATING_POINT +CFLAGS+=-D_EXPOSE__sFILE SRCS+= asprintf.c clrerr.c fclose.c fdopen.c feof.c ferror.c fflush.c fgetc.c \ fgetln.c fgetpos.c fgets.c fileno.c findfp.c flags.c fopen.c \ Index: lib/libc/stdio/fileno.c =================================================================== RCS file: /cvs/src/lib/libc/stdio/fileno.c,v retrieving revision 1.5 diff -u -r1.5 fileno.c --- lib/libc/stdio/fileno.c 8 Aug 2005 08:05:36 -0000 1.5 +++ lib/libc/stdio/fileno.c 8 Jun 2009 07:58:02 -0000 @@ -43,3 +43,12 @@ { return (__sfileno(fp)); } + +/* + * For perl. + */ +void +invalidate_fileno(FILE *fp) +{ + fp->_file = -1; +} Index: gnu/usr.bin/perl/perlio.c =================================================================== RCS file: /cvs/src/gnu/usr.bin/perl/perlio.c,v retrieving revision 1.12 diff -u -r1.12 perlio.c --- gnu/usr.bin/perl/perlio.c 29 Sep 2008 17:35:58 -0000 1.12 +++ gnu/usr.bin/perl/perlio.c 8 Jun 2009 07:22:39 -0000 @@ -3070,7 +3070,7 @@ - we could insert a dummy func in the _close function entry f->_close = (int (*)(void *)) dummy_close; */ - f->_file = -1; + invalidate_fileno(f); return 1; # elif defined(__EMX__) /* f->_flags &= ~_IOOPEN; */ /* Will leak stream->_buffer */ Index: bin/pax/pax.c =================================================================== RCS file: /cvs/src/bin/pax/pax.c,v retrieving revision 1.28 diff -u -r1.28 pax.c --- bin/pax/pax.c 4 Aug 2005 10:02:44 -0000 1.28 +++ bin/pax/pax.c 8 Jun 2009 10:41:49 -0000 @@ -105,7 +105,7 @@ char *ltmfrmt; /* -v locale time format (if any) */ char *argv0; /* root of argv[0] */ sigset_t s_mask; /* signal mask for cleanup critical sect */ -FILE *listf = stderr; /* file pointer to print file list to */ +FILE *listf; /* file pointer to print file list to */ char *tempfile; /* tempfile to use for mkstemp(3) */ char *tempbase; /* basename of tempfile to use for mkstemp(3) */ @@ -234,6 +234,8 @@ { char *tmpdir; size_t tdlen; + + listf = stderr; /* * Keep a reference to cwd, so we can always come back home. Index: usr.bin/audioctl/audioctl.c =================================================================== RCS file: /cvs/src/usr.bin/audioctl/audioctl.c,v retrieving revision 1.19 diff -u -r1.19 audioctl.c --- usr.bin/audioctl/audioctl.c 26 Jun 2008 05:42:20 -0000 1.19 +++ usr.bin/audioctl/audioctl.c 8 Jun 2009 11:42:59 -0000 @@ -51,7 +51,7 @@ void usage(void); int main(int argc, char **argv); -FILE *out = stdout; +FILE *out; audio_device_t adev; @@ -338,6 +338,8 @@ struct field *p; const char *file; const char *sep = "="; + + out = stdout; if ((file = getenv("AUDIOCTLDEVICE")) == 0 || *file == '\0') file = "/dev/audioctl"; Index: usr.bin/tcopy/tcopy.c =================================================================== RCS file: /cvs/src/usr.bin/tcopy/tcopy.c,v retrieving revision 1.10 diff -u -r1.10 tcopy.c --- usr.bin/tcopy/tcopy.c 25 Jun 2007 16:59:54 -0000 1.10 +++ usr.bin/tcopy/tcopy.c 8 Jun 2009 11:53:44 -0000 @@ -64,7 +64,7 @@ int filen, guesslen, maxblk = MAXREC; long lastrec, record; off_t size, tsize; -FILE *msg = stdout; +FILE *msg; void *getspace(int); void intr(int); @@ -80,6 +80,8 @@ enum {READ, VERIFY, COPY, COPYVERIFY} op = READ; sig_t oldsig; char *buff, *inf; + + msg = stdout; guesslen = 1; while ((ch = getopt(argc, argv, "cs:vx")) != -1) Index: usr.sbin/amd/amd/xutil.c =================================================================== RCS file: /cvs/src/usr.sbin/amd/amd/xutil.c,v retrieving revision 1.11 diff -u -r1.11 xutil.c --- usr.sbin/amd/amd/xutil.c 2 Jun 2003 23:36:51 -0000 1.11 +++ usr.sbin/amd/amd/xutil.c 8 Jun 2009 11:58:30 -0000 @@ -48,7 +48,7 @@ #include <stdlib.h> #include <sys/stat.h> -FILE *logfp = stderr; /* Log errors to stderr initially */ +FILE *logfp; /* Log errors to stderr initially */ #ifdef HAS_SYSLOG int syslogging; #endif /* HAS_SYSLOG */ Index: usr.sbin/amd/amd/amd.c =================================================================== RCS file: /cvs/src/usr.sbin/amd/amd/amd.c,v retrieving revision 1.14 diff -u -r1.14 amd.c --- usr.sbin/amd/amd/amd.c 21 Oct 2004 20:57:08 -0000 1.14 +++ usr.sbin/amd/amd/amd.c 8 Jun 2009 11:59:39 -0000 @@ -195,6 +195,8 @@ pid_t ppid = 0; int error; + logfp = stderr; + /* * Make sure some built-in assumptions are true before we start */