Index: head/include/stdio.h =================================================================== --- head/include/stdio.h (revision 75577) +++ head/include/stdio.h (revision 75578) @@ -1,403 +1,405 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)stdio.h 8.5 (Berkeley) 4/29/95 * $FreeBSD$ */ #ifndef _STDIO_H_ #define _STDIO_H_ #include #include #ifdef _BSD_SIZE_T_ typedef _BSD_SIZE_T_ size_t; #undef _BSD_SIZE_T_ #endif #ifndef NULL #define NULL 0 #endif typedef _BSD_OFF_T_ fpos_t; #define _FSTDIO /* Define for new stdio with functions. */ /* * NB: to fit things in six character monocase externals, the stdio * code uses the prefix `__s' for stdio objects, typically followed * by a three-character attempt at a mnemonic. */ /* stdio buffers */ struct __sbuf { unsigned char *_base; int _size; }; /* hold a buncha junk that would grow the ABI */ struct __sFILEX; /* * stdio state variables. * * The following always hold: * * if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR), * _lbfsize is -_bf._size, else _lbfsize is 0 * if _flags&__SRD, _w is 0 * if _flags&__SWR, _r is 0 * * This ensures that the getc and putc macros (or inline functions) never * try to write or read from a file that is in `read' or `write' mode. * (Moreover, they can, and do, automatically switch from read mode to * write mode, and back, on "r+" and "w+" files.) * * _lbfsize is used only to make the inline line-buffered output stream * code as compact as possible. * * _ub, _up, and _ur are used when ungetc() pushes back more characters * than fit in the current _bf, or when ungetc() pushes back a character * that does not match the previous one in _bf. When this happens, * _ub._base becomes non-nil (i.e., a stream has ungetc() data iff * _ub._base!=NULL) and _up and _ur save the current values of _p and _r. * * NB: see WARNING above before changing the layout of this structure! */ typedef struct __sFILE { unsigned char *_p; /* current position in (some) buffer */ int _r; /* read space left for getc() */ int _w; /* write space left for putc() */ short _flags; /* flags, below; this FILE is free if 0 */ short _file; /* fileno, if Unix descriptor, else -1 */ struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */ int _lbfsize; /* 0 or -_bf._size, for inline putc */ /* operations */ void *_cookie; /* cookie passed to io functions */ int (*_close) __P((void *)); int (*_read) __P((void *, char *, int)); fpos_t (*_seek) __P((void *, fpos_t, int)); int (*_write) __P((void *, const char *, int)); /* separate buffer for long sequences of ungetc() */ struct __sbuf _ub; /* ungetc buffer */ struct __sFILEX *_extra; /* additions to FILE to not break ABI */ int _ur; /* saved _r when _r is counting ungetc data */ /* tricks to meet minimum requirements even when malloc() fails */ unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */ unsigned char _nbuf[1]; /* guarantee a getc() buffer */ /* separate buffer for fgetln() when line crosses buffer boundary */ struct __sbuf _lb; /* buffer for fgetln() */ /* Unix stdio files get aligned to block boundaries on fseek() */ int _blksize; /* stat.st_blksize (may be != _bf._size) */ fpos_t _offset; /* current lseek offset (see WARNING) */ } FILE; __BEGIN_DECLS extern FILE __sF[]; __END_DECLS #define __SLBF 0x0001 /* line buffered */ #define __SNBF 0x0002 /* unbuffered */ #define __SRD 0x0004 /* OK to read */ #define __SWR 0x0008 /* OK to write */ /* RD and WR are never simultaneously asserted */ #define __SRW 0x0010 /* open for reading & writing */ #define __SEOF 0x0020 /* found EOF */ #define __SERR 0x0040 /* found error */ #define __SMBF 0x0080 /* _buf is from malloc */ #define __SAPP 0x0100 /* fdopen()ed in append mode */ #define __SSTR 0x0200 /* this is an sprintf/snprintf string */ #define __SOPT 0x0400 /* do fseek() optimization */ #define __SNPT 0x0800 /* do not do fseek() optimization */ #define __SOFF 0x1000 /* set iff _offset is in fact correct */ #define __SMOD 0x2000 /* true => fgetln modified _p text */ #define __SALC 0x4000 /* allocate string space dynamically */ #define __SIGN 0x8000 /* ignore this file in _fwalk */ /* * The following three definitions are for ANSI C, which took them * from System V, which brilliantly took internal interface macros and * made them official arguments to setvbuf(), without renaming them. * Hence, these ugly _IOxxx names are *supposed* to appear in user code. * * Although numbered as their counterparts above, the implementation * does not rely on this. */ #define _IOFBF 0 /* setvbuf should set fully buffered */ #define _IOLBF 1 /* setvbuf should set line buffered */ #define _IONBF 2 /* setvbuf should set unbuffered */ #define BUFSIZ 1024 /* size of buffer used by setbuf */ #define EOF (-1) /* * FOPEN_MAX is a minimum maximum, and is the number of streams that * stdio can provide without attempting to allocate further resources * (which could fail). Do not use this for anything. */ /* must be == _POSIX_STREAM_MAX */ #define FOPEN_MAX 20 /* must be <= OPEN_MAX */ #define FILENAME_MAX 1024 /* must be <= PATH_MAX */ /* System V/ANSI C; this is the wrong way to do this, do *not* use these. */ #ifndef _ANSI_SOURCE #define P_tmpdir "/var/tmp/" #endif #define L_tmpnam 1024 /* XXX must be == PATH_MAX */ #define TMP_MAX 308915776 #ifndef SEEK_SET #define SEEK_SET 0 /* set file offset to offset */ #endif #ifndef SEEK_CUR #define SEEK_CUR 1 /* set file offset to current plus offset */ #endif #ifndef SEEK_END #define SEEK_END 2 /* set file offset to EOF plus offset */ #endif #define stdin (&__sF[0]) #define stdout (&__sF[1]) #define stderr (&__sF[2]) /* * Functions defined in ANSI C standard. */ __BEGIN_DECLS void clearerr __P((FILE *)); int fclose __P((FILE *)); int feof __P((FILE *)); int ferror __P((FILE *)); int fflush __P((FILE *)); int fgetc __P((FILE *)); int fgetpos __P((FILE *, fpos_t *)); char *fgets __P((char *, int, FILE *)); FILE *fopen __P((const char *, const char *)); int fprintf __P((FILE *, const char *, ...)); int fputc __P((int, FILE *)); int fputs __P((const char *, FILE *)); size_t fread __P((void *, size_t, size_t, FILE *)); FILE *freopen __P((const char *, const char *, FILE *)); int fscanf __P((FILE *, const char *, ...)); int fseek __P((FILE *, long, int)); int fsetpos __P((FILE *, const fpos_t *)); long ftell __P((FILE *)); size_t fwrite __P((const void *, size_t, size_t, FILE *)); int getc __P((FILE *)); int getchar __P((void)); char *gets __P((char *)); #if !defined(_ANSI_SOURCE) && !defined(_POSIX_SOURCE) extern __const int sys_nerr; /* perror(3) external variables */ extern __const char *__const sys_errlist[]; #endif void perror __P((const char *)); int printf __P((const char *, ...)); int putc __P((int, FILE *)); int putchar __P((int)); int puts __P((const char *)); int remove __P((const char *)); int rename __P((const char *, const char *)); void rewind __P((FILE *)); int scanf __P((const char *, ...)); void setbuf __P((FILE *, char *)); int setvbuf __P((FILE *, char *, int, size_t)); int sprintf __P((char *, const char *, ...)); int sscanf __P((const char *, const char *, ...)); FILE *tmpfile __P((void)); char *tmpnam __P((char *)); int ungetc __P((int, FILE *)); int vfprintf __P((FILE *, const char *, _BSD_VA_LIST_)); int vprintf __P((const char *, _BSD_VA_LIST_)); int vsprintf __P((char *, const char *, _BSD_VA_LIST_)); __END_DECLS /* * Functions defined in POSIX 1003.1. */ #ifndef _ANSI_SOURCE /* size for cuserid(3); UT_NAMESIZE + 1, see */ #define L_cuserid 17 #define L_ctermid 1024 /* size for ctermid(3); PATH_MAX */ __BEGIN_DECLS char *ctermid __P((char *)); FILE *fdopen __P((int, const char *)); int fileno __P((FILE *)); int ftrylockfile __P((FILE *)); void flockfile __P((FILE *)); void funlockfile __P((FILE *)); __END_DECLS #endif /* not ANSI */ /* * Portability hacks. See . */ #if !defined (_ANSI_SOURCE) && !defined(_POSIX_SOURCE) __BEGIN_DECLS #ifndef _FTRUNCATE_DECLARED #define _FTRUNCATE_DECLARED int ftruncate __P((int, _BSD_OFF_T_)); #endif #ifndef _LSEEK_DECLARED #define _LSEEK_DECLARED _BSD_OFF_T_ lseek __P((int, _BSD_OFF_T_, int)); #endif #ifndef _MMAP_DECLARED #define _MMAP_DECLARED void *mmap __P((void *, size_t, int, int, int, _BSD_OFF_T_)); #endif #ifndef _TRUNCATE_DECLARED #define _TRUNCATE_DECLARED int truncate __P((const char *, _BSD_OFF_T_)); #endif __END_DECLS #endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */ /* * Routines that are purely local. */ #if !defined (_ANSI_SOURCE) && !defined(_POSIX_SOURCE) __BEGIN_DECLS int asprintf __P((char **, const char *, ...)) __printflike(2, 3); char *ctermid_r __P((char *)); +const char *fmtcheck __P((const char *, const char *)) + __attribute__((__format_arg__(2))); char *fgetln __P((FILE *, size_t *)); int fpurge __P((FILE *)); int fseeko __P((FILE *, _BSD_OFF_T_, int)); _BSD_OFF_T_ ftello __P((FILE *)); int getw __P((FILE *)); int pclose __P((FILE *)); FILE *popen __P((const char *, const char *)); int putw __P((int, FILE *)); void setbuffer __P((FILE *, char *, int)); int setlinebuf __P((FILE *)); char *tempnam __P((const char *, const char *)); int snprintf __P((char *, size_t, const char *, ...)) __printflike(3, 4); int vasprintf __P((char **, const char *, _BSD_VA_LIST_)) __printflike(2, 0); int vsnprintf __P((char *, size_t, const char *, _BSD_VA_LIST_)) __printflike(3, 0); int vscanf __P((const char *, _BSD_VA_LIST_)) __scanflike(1, 0); int vsscanf __P((const char *, const char *, _BSD_VA_LIST_)) __scanflike(2, 0); __END_DECLS /* * This is a #define because the function is used internally and * (unlike vfscanf) the name __vfscanf is guaranteed not to collide * with a user function when _ANSI_SOURCE or _POSIX_SOURCE is defined. */ #define vfscanf __vfscanf /* * Stdio function-access interface. */ __BEGIN_DECLS FILE *funopen __P((const void *, int (*)(void *, char *, int), int (*)(void *, const char *, int), fpos_t (*)(void *, fpos_t, int), int (*)(void *))); __END_DECLS #define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0) #define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0) #endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */ /* * Functions internal to the implementation. */ __BEGIN_DECLS int __srget __P((FILE *)); int __vfscanf __P((FILE *, const char *, _BSD_VA_LIST_)); int __svfscanf __P((FILE *, const char *, _BSD_VA_LIST_)); int __swbuf __P((int, FILE *)); __END_DECLS /* * The __sfoo macros are here so that we can * define function versions in the C library. */ #define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++)) #if defined(__GNUC__) && defined(__STDC__) static __inline int __sputc(int _c, FILE *_p) { if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n')) return (*_p->_p++ = _c); else return (__swbuf(_c, _p)); } #else /* * This has been tuned to generate reasonable code on the vax using pcc. */ #define __sputc(c, p) \ (--(p)->_w < 0 ? \ (p)->_w >= (p)->_lbfsize ? \ (*(p)->_p = (c)), *(p)->_p != '\n' ? \ (int)*(p)->_p++ : \ __swbuf('\n', p) : \ __swbuf((int)(c), p) : \ (*(p)->_p = (c), (int)*(p)->_p++)) #endif #define __sfeof(p) (((p)->_flags & __SEOF) != 0) #define __sferror(p) (((p)->_flags & __SERR) != 0) #define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF))) #define __sfileno(p) ((p)->_file) /* * See ISO/IEC 9945-1 ANSI/IEEE Std 1003.1 Second Edition 1996-07-12 * B.8.2.7 for the rationale behind the *_unlocked() macros. */ #define feof_unlocked(p) __sfeof(p) #define ferror_unlocked(p) __sferror(p) #define clearerr_unlocked(p) __sclearerr(p) #ifndef _ANSI_SOURCE #define fileno_unlocked(p) __sfileno(p) #endif #define getc_unlocked(fp) __sgetc(fp) #define putc_unlocked(x, fp) __sputc(x, fp) #define getchar_unlocked() getc_unlocked(stdin) #define putchar_unlocked(x) putc_unlocked(x, stdout) #endif /* !_STDIO_H_ */ Index: head/lib/libc/gen/Makefile.inc =================================================================== --- head/lib/libc/gen/Makefile.inc (revision 75577) +++ head/lib/libc/gen/Makefile.inc (revision 75578) @@ -1,128 +1,128 @@ # @(#)Makefile.inc 8.6 (Berkeley) 5/4/95 # $FreeBSD$ # machine-independent gen sources .PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/gen ${.CURDIR}/../libc/gen SRCS+= __xuname.c _pthread_stubs.c _rand48.c _spinlock_stub.c _thread_init.c \ alarm.c arc4random.c assert.c basename.c \ clock.c closedir.c confstr.c \ crypt.c ctermid.c daemon.c devname.c dirname.c disklabel.c \ dlfcn.c drand48.c erand48.c err.c errlst.c \ - exec.c fnmatch.c fstab.c ftok.c fts.c getbootfile.c getbsize.c \ + exec.c fmtcheck.c fnmatch.c fstab.c ftok.c fts.c getbootfile.c getbsize.c \ getcap.c getcwd.c getdomainname.c getgrent.c getgrouplist.c \ gethostname.c getloadavg.c getlogin.c getmntinfo.c getnetgrent.c \ getobjformat.c getosreldate.c getpagesize.c \ getpass.c getpwent.c getttyent.c \ getusershell.c getvfsbyname.c getvfsent.c glob.c \ initgroups.c isatty.c jrand48.c lcong48.c \ lockf.c lrand48.c mrand48.c msgctl.c \ msgget.c msgrcv.c msgsnd.c nice.c \ nlist.c nrand48.c ntp_gettime.c opendir.c \ pause.c popen.c psignal.c pw_scan.c pwcache.c raise.c readdir.c rewinddir.c \ posixshm.c \ scandir.c seed48.c seekdir.c semconfig.c semctl.c semget.c semop.c \ setdomainname.c sethostname.c setjmperr.c setmode.c setproctitle.c \ shmat.c shmctl.c shmdt.c shmget.c siginterrupt.c siglist.c signal.c \ sigsetops.c sleep.c srand48.c stringlist.c strtofflags.c \ sysconf.c sysctl.c sysctlbyname.c sysctlnametomib.c \ syslog.c telldir.c termios.c time.c times.c timezone.c ttyname.c \ ttyslot.c ualarm.c uname.c unvis.c usleep.c utime.c valloc.c vis.c \ wait.c wait3.c waitpid.c # machine-dependent gen sources .include "${.CURDIR}/../libc/${MACHINE_ARCH}/gen/Makefile.inc" .if ${LIB} == "c" MAN+= alarm.3 arc4random.3 clock.3 \ basename.3 \ confstr.3 ctermid.3 daemon.3 \ devname.3 directory.3 dirname.3 dladdr.3 dllockinit.3 dlopen.3 \ - err.3 exec.3 fnmatch.3 frexp.3 ftok.3 fts.3 \ + err.3 exec.3 fmtcheck.3 fnmatch.3 frexp.3 ftok.3 fts.3 \ getbootfile.3 getbsize.3 getcap.3 getcwd.3 \ getdiskbyname.3 getdomainname.3 getfsent.3 \ getgrent.3 getgrouplist.3 gethostname.3 getloadavg.3 \ getmntinfo.3 getnetgrent.3 getobjformat.3 \ getpagesize.3 getpass.3 getpwent.3 \ getttyent.3 getusershell.3 getvfsbyname.3 getvfsent.3 \ glob.3 initgroups.3 isinf.3 \ ldexp.3 lockf.3 modf.3 msgctl.3 msgget.3 msgrcv.3 msgsnd.3 \ nice.3 nlist.3 pause.3 popen.3 psignal.3 pwcache.3 \ raise.3 rand48.3 rfork_thread.3 \ scandir.3 setjmp.3 setmode.3 setproctitle.3 shm_open.3 \ siginterrupt.3 signal.3 sigsetops.3 sleep.3 stringlist.3 \ strtofflags.3 sysconf.3 sysctl.3 syslog.3 tcgetpgrp.3 \ tcsendbreak.3 tcsetattr.3 tcsetpgrp.3 time.3 times.3 timezone.3 \ ttyname.3 tzset.3 ualarm.3 uname.3 unvis.3 usleep.3 utime.3 \ valloc.3 vis.3 MLINKS+=arc4random.3 arc4random_addrandom.3 arc4random.3 arc4random_stir.3 MLINKS+=ctermid.3 ctermid_r.3 MLINKS+=directory.3 closedir.3 directory.3 dirfd.3 directory.3 opendir.3 \ directory.3 readdir.3 directory.3 rewinddir.3 directory.3 seekdir.3 \ directory.3 telldir.3 MLINKS+=dlopen.3 dlclose.3 dlopen.3 dlerror.3 dlopen.3 dlsym.3 MLINKS+=err.3 err_set_exit.3 err.3 err_set_file.3 err.3 errc.3 err.3 errx.3 \ err.3 verr.3 err.3 verrc.3 err.3 verrx.3 err.3 vwarn.3 err.3 vwarnc.3 \ err.3 vwarnx.3 err.3 warnc.3 err.3 warn.3 err.3 warnx.3 MLINKS+=exec.3 execl.3 exec.3 execle.3 exec.3 execlp.3 exec.3 exect.3 \ exec.3 execv.3 exec.3 execvp.3 MLINKS+=fts.3 fts_children.3 fts.3 fts_close.3 fts.3 fts_open.3 \ fts.3 fts_read.3 fts.3 fts_set.3 MLINKS+=getcap.3 cgetcap.3 getcap.3 cgetclose.3 getcap.3 cgetent.3 \ getcap.3 cgetfirst.3 getcap.3 cgetmatch.3 getcap.3 cgetnext.3 \ getcap.3 cgetnum.3 getcap.3 cgetset.3 getcap.3 cgetstr.3 \ getcap.3 cgetustr.3 MLINKS+=getcwd.3 getwd.3 MLINKS+=getdomainname.3 setdomainname.3 MLINKS+=getfsent.3 endfsent.3 getfsent.3 getfsfile.3 getfsent.3 getfsspec.3 \ getfsent.3 getfstype.3 getfsent.3 setfsent.3 MLINKS+=getgrent.3 endgrent.3 getgrent.3 getgrgid.3 getgrent.3 getgrnam.3 \ getgrent.3 setgrent.3 getgrent.3 setgroupent.3 MLINKS+=gethostname.3 sethostname.3 MLINKS+=getnetgrent.3 endnetgrent.3 getnetgrent.3 innetgr.3 \ getnetgrent.3 setnetgrent.3 MLINKS+=getpwent.3 endpwent.3 getpwent.3 getpwnam.3 getpwent.3 getpwuid.3 \ getpwent.3 setpassent.3 getpwent.3 setpwent.3 getpwent.3 setpwfile.3 MLINKS+=getttyent.3 endttyent.3 getttyent.3 getttynam.3 \ getttyent.3 isdialuptty.3 getttyent.3 isnettty.3 \ getttyent.3 setttyent.3 MLINKS+=getusershell.3 endusershell.3 getusershell.3 setusershell.3 MLINKS+=getvfsent.3 endvfsent.3 getvfsent.3 getvfsbytype.3 \ getvfsent.3 setvfsent.3 getvfsent.3 vfsisloadable.3 \ getvfsent.3 vfsload.3 MLINKS+=glob.3 globfree.3 MLINKS+=isinf.3 isnan.3 isinf.3 isnanf.3 MLINKS+=popen.3 pclose.3 MLINKS+=psignal.3 sys_siglist.3 psignal.3 sys_signame.3 MLINKS+=psignal.3 strsignal.3 psignal.3 sys_siglist.3 psignal.3 sys_signame.3 MLINKS+=pwcache.3 group_from_gid.3 pwcache.3 user_from_uid.3 MLINKS+=rand48.3 _rand48.3 rand48.3 drand48.3 rand48.3 erand48.3 \ rand48.3 jrand48.3 rand48.3 lcong48.3 rand48.3 lrand48.3 \ rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 seed48.3 \ rand48.3 srand48.3 MLINKS+=scandir.3 alphasort.3 MLINKS+=strtofflags.3 fflagstostr.3 MLINKS+=setjmp.3 _longjmp.3 setjmp.3 _setjmp.3 setjmp.3 longjmp.3 \ setjmp.3 longjmperr.3 setjmp.3 longjmperror.3 \ setjmp.3 siglongjmp.3 setjmp.3 sigsetjmp.3 MLINKS+=setmode.3 getmode.3 MLINKS+=shm_open.3 shm_unlink.3 MLINKS+=sigsetops.3 sigaddset.3 sigsetops.3 sigdelset.3 \ sigsetops.3 sigemptyset.3 sigsetops.3 sigfillset.3 \ sigsetops.3 sigismember.3 MLINKS+=stringlist.3 sl_add.3 stringlist.3 sl_find.3 \ stringlist.3 sl_free.3 stringlist.3 sl_init.3 MLINKS+=sysctl.3 sysctlbyname.3 sysctl.3 sysctlnametomib.3 MLINKS+=syslog.3 closelog.3 syslog.3 openlog.3 syslog.3 setlogmask.3 \ syslog.3 vsyslog.3 MLINKS+=tcsendbreak.3 tcdrain.3 tcsendbreak.3 tcflow.3 tcsendbreak.3 tcflush.3 MLINKS+=tcsetattr.3 cfgetispeed.3 tcsetattr.3 cfgetospeed.3 \ tcsetattr.3 cfmakeraw.3 tcsetattr.3 cfsetispeed.3 \ tcsetattr.3 cfsetospeed.3 tcsetattr.3 cfsetspeed.3 \ tcsetattr.3 tcgetattr.3 MLINKS+=ttyname.3 isatty.3 ttyname.3 ttyslot.3 MLINKS+=tzset.3 tzsetwall.3 MLINKS+=unvis.3 strunvis.3 unvis.3 strunvisx.3 MLINKS+=vis.3 strvis.3 vis.3 strvisx.3 .endif Index: head/lib/libc/gen/fmtcheck.3 =================================================================== --- head/lib/libc/gen/fmtcheck.3 (nonexistent) +++ head/lib/libc/gen/fmtcheck.3 (revision 75578) @@ -0,0 +1,100 @@ +.\" Copyright (c) 2000 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This file was contributed to The NetBSD Foundation by Allen Briggs. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the NetBSD +.\" Foundation, Inc. and its contributors. +.\" 4. Neither the name of The NetBSD Foundation nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.Dd October 17, 2000 +.Os +.Dt FMTCHECK 3 +.Sh NAME +.Nm fmtcheck +.Nd sanitizes user-supplied printf(3)-style format string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.Fd #include +.Ft const char * +.Fn fmtcheck "const char *fmt_suspect" "const char *fmt_default" +.Sh DESCRIPTION +The +.Nm +function scans +.Fa fmt_suspect +and +.Fa fmt_default +to determine if +.Fa fmt_suspect +will consume the same argument types as +.Fa fmt_default +and to ensure that +.Fa fmt_suspect +is a valid format string. +.Pp +The +.Xr printf 3 +family of functions can not verify the types of arguments that they are +passed at run-time. In some cases, like +.Xr catgets 3 , +it is useful or necessary to use a user-supplied format string with no +guarantee that the format string matches the specified parameters. +.Pp +The +.Nm +function was designed to be used in these cases, as in: +.Bd -literal -offset indent +printf(fmtcheck(user_format, standard_format), arg1, arg2); +.Ed +.Pp +In the check, field widths, fillers, precisions, etc. are ignored (unless +the field width or precision is an asterisk +.Ql * +instead of a digit string). Also, any text other than the format specifiers +is completely ignored. +.Pp +Note that the formats may be quite different as long as they accept the +same parameters. For example, ".Dq %p %o %30s %#llx %-10.*e %n" is +compatible with "This number %lu %d%% and string %s has %qd numbers +and %.*g floats (%n)." However, "%o" is not equivalent to "%lx" because +the first requires an integer and the second requires a long. +.Sh RETURN VALUES +If +.Fa fmt_suspect +is a valid format and consumes the same argument types as +.Fa fmt_default , +then the +.Nm +function will return +.Fa fmt_suspect . +Otherwise, it will return +.Fa fmt_default . +.Sh SEE ALSO +.Xr printf 3 Property changes on: head/lib/libc/gen/fmtcheck.3 ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: head/lib/libc/gen/fmtcheck.c =================================================================== --- head/lib/libc/gen/fmtcheck.c (nonexistent) +++ head/lib/libc/gen/fmtcheck.c (revision 75578) @@ -0,0 +1,253 @@ +/* $FreeBSD$ */ +/* $NetBSD: fmtcheck.c,v 1.2 2000/11/01 01:17:20 briggs Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Allen Briggs. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#ifndef lint +static const char rcsid[] = + "$FreeBSD$"; +#endif /* not lint */ + +#include "namespace.h" + +#include +#include +#include +#include + +#ifdef __weak_alias +__weak_alias(fmtcheck,__fmtcheck) +#endif + +enum __e_fmtcheck_types { + FMTCHECK_START, + FMTCHECK_SHORT, + FMTCHECK_INT, + FMTCHECK_LONG, + FMTCHECK_QUAD, + FMTCHECK_SHORTPOINTER, + FMTCHECK_INTPOINTER, + FMTCHECK_LONGPOINTER, + FMTCHECK_QUADPOINTER, + FMTCHECK_DOUBLE, + FMTCHECK_LONGDOUBLE, + FMTCHECK_STRING, + FMTCHECK_WIDTH, + FMTCHECK_PRECISION, + FMTCHECK_DONE, + FMTCHECK_UNKNOWN +}; +typedef enum __e_fmtcheck_types EFT; + +#define RETURN(pf,f,r) do { \ + *(pf) = (f); \ + return r; \ + } /*NOTREACHED*/ /*CONSTCOND*/ while (0) + +static EFT +get_next_format_from_precision(const char **pf) +{ + int sh, lg, quad, longdouble; + const char *f; + + sh = lg = quad = longdouble = 0; + + f = *pf; + switch (*f) { + case 'h': + f++; + sh = 1; + break; + case 'l': + f++; + if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN); + if (*f == 'l') { + f++; + quad = 1; + } else { + lg = 1; + } + break; + case 'q': + f++; + quad = 1; + break; + case 'L': + f++; + longdouble = 1; + break; + default: + break; + } + if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN); + if (strchr("diouxX", *f)) { + if (longdouble) + RETURN(pf,f,FMTCHECK_UNKNOWN); + if (lg) + RETURN(pf,f,FMTCHECK_LONG); + if (quad) + RETURN(pf,f,FMTCHECK_QUAD); + RETURN(pf,f,FMTCHECK_INT); + } + if (*f == 'n') { + if (longdouble) + RETURN(pf,f,FMTCHECK_UNKNOWN); + if (sh) + RETURN(pf,f,FMTCHECK_SHORTPOINTER); + if (lg) + RETURN(pf,f,FMTCHECK_LONGPOINTER); + if (quad) + RETURN(pf,f,FMTCHECK_QUADPOINTER); + RETURN(pf,f,FMTCHECK_INTPOINTER); + } + if (strchr("DOU", *f)) { + if (sh + lg + quad + longdouble) + RETURN(pf,f,FMTCHECK_UNKNOWN); + RETURN(pf,f,FMTCHECK_LONG); + } + if (strchr("eEfg", *f)) { + if (longdouble) + RETURN(pf,f,FMTCHECK_LONGDOUBLE); + if (sh + lg + quad) + RETURN(pf,f,FMTCHECK_UNKNOWN); + RETURN(pf,f,FMTCHECK_DOUBLE); + } + if (*f == 'c') { + if (sh + lg + quad + longdouble) + RETURN(pf,f,FMTCHECK_UNKNOWN); + RETURN(pf,f,FMTCHECK_INT); + } + if (*f == 's') { + if (sh + lg + quad + longdouble) + RETURN(pf,f,FMTCHECK_UNKNOWN); + RETURN(pf,f,FMTCHECK_STRING); + } + if (*f == 'p') { + if (sh + lg + quad + longdouble) + RETURN(pf,f,FMTCHECK_UNKNOWN); + RETURN(pf,f,FMTCHECK_LONG); + } + RETURN(pf,f,FMTCHECK_UNKNOWN); + /*NOTREACHED*/ +} + +static EFT +get_next_format_from_width(const char **pf) +{ + const char *f; + + f = *pf; + if (*f == '.') { + f++; + if (*f == '*') { + RETURN(pf,f,FMTCHECK_PRECISION); + } + /* eat any precision (empty is allowed) */ + while (isdigit(*f)) f++; + if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN); + } + RETURN(pf,f,get_next_format_from_precision(pf)); + /*NOTREACHED*/ +} + +static EFT +get_next_format(const char **pf, EFT eft) +{ + int infmt; + const char *f; + + if (eft == FMTCHECK_WIDTH) { + (*pf)++; + return get_next_format_from_width(pf); + } else if (eft == FMTCHECK_PRECISION) { + (*pf)++; + return get_next_format_from_precision(pf); + } + + f = *pf; + infmt = 0; + while (!infmt) { + f = strchr(f, '%'); + if (f == NULL) + RETURN(pf,f,FMTCHECK_DONE); + f++; + if (!*f) + RETURN(pf,f,FMTCHECK_UNKNOWN); + if (*f != '%') + infmt = 1; + else + f++; + } + + /* Eat any of the flags */ + while (*f && (strchr("#0- +", *f))) + f++; + + if (*f == '*') { + RETURN(pf,f,FMTCHECK_WIDTH); + } + /* eat any width */ + while (isdigit(*f)) f++; + if (!*f) { + RETURN(pf,f,FMTCHECK_UNKNOWN); + } + + RETURN(pf,f,get_next_format_from_width(pf)); + /*NOTREACHED*/ +} + +__const char * +fmtcheck(const char *f1, const char *f2) +{ + const char *f1p, *f2p; + EFT f1t, f2t; + + if (!f1) return f2; + + f1p = f1; + f1t = FMTCHECK_START; + f2p = f2; + f2t = FMTCHECK_START; + while ((f1t = get_next_format(&f1p, f1t)) != FMTCHECK_DONE) { + if (f1t == FMTCHECK_UNKNOWN) + return f2; + f2t = get_next_format(&f2p, f2t); + if (f1t != f2t) + return f2; + } + return f1; +} Property changes on: head/lib/libc/gen/fmtcheck.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property