diff options
Diffstat (limited to 'lib/libc/stdio')
39 files changed, 489 insertions, 86 deletions
diff --git a/lib/libc/stdio/Makefile.inc b/lib/libc/stdio/Makefile.inc index b9c02a41f40c..a549be2c1050 100644 --- a/lib/libc/stdio/Makefile.inc +++ b/lib/libc/stdio/Makefile.inc @@ -1,4 +1,5 @@ # @(#)Makefile.inc 8.3 (Berkeley) 4/17/94 +# $Id$ # stdio sources .PATH: ${.CURDIR}/stdio @@ -32,7 +33,7 @@ MLINKS+=getc.3 fgetc.3 getc.3 getchar.3 getc.3 getw.3 MLINKS+=mktemp.3 mkstemp.3 MLINKS+=printf.3 fprintf.3 printf.3 snprintf.3 printf.3 sprintf.3 \ printf.3 vfprintf.3 printf.3 vprintf.3 printf.3 vsnprintf.3 \ - printf.3 vsprintf.3 + printf.3 vsprintf.3 printf.3 asprintf.3 printf.3 vasprintf.3 MLINKS+=putc.3 fputc.3 putc.3 putchar.3 putc.3 putw.3 MLINKS+=scanf.3 fscanf.3 scanf.3 sscanf.3 scanf.3 vfscanf.3 scanf.3 vscanf.3 \ scanf.3 vsscanf.3 diff --git a/lib/libc/stdio/clrerr.c b/lib/libc/stdio/clrerr.c index de4526e0a7dc..a597b7b0baf3 100644 --- a/lib/libc/stdio/clrerr.c +++ b/lib/libc/stdio/clrerr.c @@ -40,10 +40,20 @@ static char sccsid[] = "@(#)clrerr.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #undef clearerr +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif void clearerr(fp) FILE *fp; { +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif __sclearerr(fp); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif } diff --git a/lib/libc/stdio/fclose.c b/lib/libc/stdio/fclose.c index 8315c3cf41ea..be9210801b50 100644 --- a/lib/libc/stdio/fclose.c +++ b/lib/libc/stdio/fclose.c @@ -42,7 +42,12 @@ static char sccsid[] = "@(#)fclose.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #include <stdlib.h> #include "local.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif +int fclose(fp) register FILE *fp; { @@ -52,6 +57,9 @@ fclose(fp) errno = EBADF; return (EOF); } +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif r = fp->_flags & __SWR ? __sflush(fp) : 0; if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0) r = EOF; @@ -61,7 +69,11 @@ fclose(fp) FREEUB(fp); if (HASLB(fp)) FREELB(fp); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif fp->_flags = 0; /* Release this FILE for reuse. */ + fp->_file = -1; fp->_r = fp->_w = 0; /* Mess up if reaccessed. */ return (r); } diff --git a/lib/libc/stdio/fflush.c b/lib/libc/stdio/fflush.c index 4a5cf0f43084..fce893292e60 100644 --- a/lib/libc/stdio/fflush.c +++ b/lib/libc/stdio/fflush.c @@ -41,21 +41,36 @@ static char sccsid[] = "@(#)fflush.c 8.1 (Berkeley) 6/4/93"; #include <errno.h> #include <stdio.h> #include "local.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* Flush a single file, or (if fp is NULL) all files. */ +int fflush(fp) register FILE *fp; { + int retval; if (fp == NULL) return (_fwalk(__sflush)); +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif if ((fp->_flags & (__SWR | __SRW)) == 0) { errno = EBADF; - return (EOF); + retval = EOF; + } else { + retval = __sflush(fp); } - return (__sflush(fp)); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (retval); } +int __sflush(fp) register FILE *fp; { diff --git a/lib/libc/stdio/fgetc.c b/lib/libc/stdio/fgetc.c index 800846cda974..7e2738f6c48f 100644 --- a/lib/libc/stdio/fgetc.c +++ b/lib/libc/stdio/fgetc.c @@ -39,9 +39,22 @@ static char sccsid[] = "@(#)fgetc.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include <stdio.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif +int fgetc(fp) FILE *fp; { - return (__sgetc(fp)); + int retval; +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif + retval = __sgetc(fp); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (retval); } diff --git a/lib/libc/stdio/fgetpos.c b/lib/libc/stdio/fgetpos.c index 1f4ec1de23d6..4ac0be4ed3e2 100644 --- a/lib/libc/stdio/fgetpos.c +++ b/lib/libc/stdio/fgetpos.c @@ -39,10 +39,23 @@ static char sccsid[] = "@(#)fgetpos.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include <stdio.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif +int fgetpos(fp, pos) FILE *fp; fpos_t *pos; { - return((*pos = ftell(fp)) == (fpos_t)-1); + int retval; +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif + retval = (*pos = ftell(fp)) == (fpos_t)-1; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return(retval); } diff --git a/lib/libc/stdio/fgets.c b/lib/libc/stdio/fgets.c index 09f68772818d..186a1a1136ad 100644 --- a/lib/libc/stdio/fgets.c +++ b/lib/libc/stdio/fgets.c @@ -40,6 +40,11 @@ static char sccsid[] = "@(#)fgets.c 8.2 (Berkeley) 12/22/93"; #include <stdio.h> #include <string.h> +#include "local.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * Read at most n-1 characters from the given file. @@ -49,16 +54,19 @@ static char sccsid[] = "@(#)fgets.c 8.2 (Berkeley) 12/22/93"; char * fgets(buf, n, fp) char *buf; - register size_t n; + register int n; register FILE *fp; { register size_t len; register char *s; register unsigned char *p, *t; - if (n == 0) /* sanity check */ + if (n <= 0) /* sanity check */ return (NULL); +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif s = buf; n--; /* leave space for NUL */ while (n != 0) { @@ -68,8 +76,12 @@ fgets(buf, n, fp) if ((len = fp->_r) <= 0) { if (__srefill(fp)) { /* EOF/error: stop with partial or no line */ - if (s == buf) + if (s == buf) { +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (NULL); + } break; } len = fp->_r; @@ -91,6 +103,9 @@ fgets(buf, n, fp) fp->_p = t; (void)memcpy((void *)s, (void *)p, len); s[len] = 0; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (buf); } fp->_r -= len; @@ -100,5 +115,8 @@ fgets(buf, n, fp) n -= len; } *s = 0; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (buf); } diff --git a/lib/libc/stdio/findfp.c b/lib/libc/stdio/findfp.c index 64548db20b3f..2986a2ccbbd8 100644 --- a/lib/libc/stdio/findfp.c +++ b/lib/libc/stdio/findfp.c @@ -127,6 +127,10 @@ found: * XXX. Force immediate allocation of internal memory. Not used by stdio, * but documented historically for certain applications. Bad applications. */ +__warn_references(f_prealloc, + "warning: this program uses f_prealloc(), which is stupid."); + +void f_prealloc() { register struct glue *g; diff --git a/lib/libc/stdio/fpurge.c b/lib/libc/stdio/fpurge.c index 3bee5132aa57..7cf54ffb2e38 100644 --- a/lib/libc/stdio/fpurge.c +++ b/lib/libc/stdio/fpurge.c @@ -42,6 +42,10 @@ static char sccsid[] = "@(#)fpurge.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #include <stdlib.h> #include "local.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * fpurge: like fflush, but without writing anything: leave the @@ -51,15 +55,23 @@ int fpurge(fp) register FILE *fp; { + int retval; +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif if (!fp->_flags) { errno = EBADF; - return(EOF); + retval = EOF; + } else { + if (HASUB(fp)) + FREEUB(fp); + fp->_p = fp->_bf._base; + fp->_r = 0; + fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size; + retval = 0; } - - if (HASUB(fp)) - FREEUB(fp); - fp->_p = fp->_bf._base; - fp->_r = 0; - fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size; - return (0); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (retval); } diff --git a/lib/libc/stdio/fputc.c b/lib/libc/stdio/fputc.c index c86f71161fc4..09b55d59a58e 100644 --- a/lib/libc/stdio/fputc.c +++ b/lib/libc/stdio/fputc.c @@ -39,10 +39,23 @@ static char sccsid[] = "@(#)fputc.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include <stdio.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif +int fputc(c, fp) int c; register FILE *fp; { - return (putc(c, fp)); + int retval; +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif + retval = putc(c, fp); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (retval); } diff --git a/lib/libc/stdio/fputs.c b/lib/libc/stdio/fputs.c index 9f9be2e2feee..92fcc303a690 100644 --- a/lib/libc/stdio/fputs.c +++ b/lib/libc/stdio/fputs.c @@ -41,14 +41,20 @@ static char sccsid[] = "@(#)fputs.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #include <string.h> #include "fvwrite.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * Write the given string to the given file. */ +int fputs(s, fp) const char *s; FILE *fp; { + int retval; struct __suio uio; struct __siov iov; @@ -56,5 +62,12 @@ fputs(s, fp) iov.iov_len = uio.uio_resid = strlen(s); uio.uio_iov = &iov; uio.uio_iovcnt = 1; - return (__sfvwrite(fp, &uio)); +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif + retval = __sfvwrite(fp, &uio); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (retval); } diff --git a/lib/libc/stdio/fread.3 b/lib/libc/stdio/fread.3 index 03a91412bc88..c3e591af9ddd 100644 --- a/lib/libc/stdio/fread.3 +++ b/lib/libc/stdio/fread.3 @@ -44,9 +44,9 @@ .Nd binary stream input/output .Sh SYNOPSIS .Fd #include <stdio.h> -.Ft int +.Ft size_t .Fn fread "void *ptr" "size_t size" "size_t nmemb" "FILE *stream" -.Ft int +.Ft size_t .Fn fwrite "const void *ptr" "size_t size" "size_t nmemb" "FILE *stream" .Sh DESCRIPTION The function diff --git a/lib/libc/stdio/fread.c b/lib/libc/stdio/fread.c index 22436ec8dcc1..7132e8544c01 100644 --- a/lib/libc/stdio/fread.c +++ b/lib/libc/stdio/fread.c @@ -40,6 +40,11 @@ static char sccsid[] = "@(#)fread.c 8.2 (Berkeley) 12/11/93"; #include <stdio.h> #include <string.h> +#include "local.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif size_t fread(buf, size, count, fp) @@ -59,6 +64,9 @@ fread(buf, size, count, fp) */ if ((resid = count * size) == 0) return (0); +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif if (fp->_r < 0) fp->_r = 0; total = resid; @@ -77,5 +85,8 @@ fread(buf, size, count, fp) (void)memcpy((void *)p, (void *)fp->_p, resid); fp->_r -= resid; fp->_p += resid; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (count); } diff --git a/lib/libc/stdio/fscanf.c b/lib/libc/stdio/fscanf.c index f0e726af8490..bbb3155f94ad 100644 --- a/lib/libc/stdio/fscanf.c +++ b/lib/libc/stdio/fscanf.c @@ -44,14 +44,20 @@ static char sccsid[] = "@(#)fscanf.c 8.1 (Berkeley) 6/4/93"; #else #include <varargs.h> #endif +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif #if __STDC__ +int fscanf(FILE *fp, char const *fmt, ...) { int ret; va_list ap; va_start(ap, fmt); #else +int fscanf(fp, fmt, va_alist) FILE *fp; char *fmt; @@ -62,7 +68,13 @@ fscanf(fp, fmt, va_alist) va_start(ap); #endif +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif ret = __svfscanf(fp, fmt, ap); va_end(ap); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (ret); } diff --git a/lib/libc/stdio/fseek.c b/lib/libc/stdio/fseek.c index 9cb04ad03787..1e99de9db2cc 100644 --- a/lib/libc/stdio/fseek.c +++ b/lib/libc/stdio/fseek.c @@ -45,6 +45,10 @@ static char sccsid[] = "@(#)fseek.c 8.3 (Berkeley) 1/2/94"; #include <stdlib.h> #include <errno.h> #include "local.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif #define POS_ERR (-(fpos_t)1) @@ -68,6 +72,9 @@ fseek(fp, offset, whence) if (!__sdidinit) __sinit(); +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif /* * Have to be able to seek. */ @@ -92,8 +99,12 @@ fseek(fp, offset, whence) curoff = fp->_offset; else { curoff = (*seekfn)(fp->_cookie, (fpos_t)0, SEEK_CUR); - if (curoff == -1L) + if (curoff == -1L) { +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (EOF); + } } if (fp->_flags & __SRD) { curoff -= fp->_r; @@ -115,6 +126,9 @@ fseek(fp, offset, whence) default: errno = EINVAL; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (EOF); } @@ -198,6 +212,9 @@ fseek(fp, offset, whence) if (HASUB(fp)) FREEUB(fp); fp->_flags &= ~__SEOF; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (0); } @@ -224,6 +241,9 @@ fseek(fp, offset, whence) fp->_p += n; fp->_r -= n; } +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (0); /* @@ -233,6 +253,9 @@ fseek(fp, offset, whence) dumb: if (__sflush(fp) || (*seekfn)(fp->_cookie, (fpos_t)offset, whence) == POS_ERR) { +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (EOF); } /* success: clear EOF indicator and discard ungetc() data */ @@ -242,5 +265,8 @@ dumb: fp->_r = 0; /* fp->_w = 0; */ /* unnecessary (I think...) */ fp->_flags &= ~__SEOF; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (0); } diff --git a/lib/libc/stdio/ftell.c b/lib/libc/stdio/ftell.c index 724e5437812b..abffc3e8daa1 100644 --- a/lib/libc/stdio/ftell.c +++ b/lib/libc/stdio/ftell.c @@ -41,13 +41,17 @@ static char sccsid[] = "@(#)ftell.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #include <errno.h> #include "local.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * ftell: return current offset. */ long ftell(fp) - register const FILE *fp; + register FILE *fp; { register fpos_t pos; @@ -56,6 +60,9 @@ ftell(fp) return (-1L); } +#ifdef _THREAD_SAFE + _thread_flockfile(fp, __FILE__, __LINE__); +#endif /* * Find offset of underlying I/O object, then * adjust for buffered bytes. @@ -64,8 +71,12 @@ ftell(fp) pos = fp->_offset; else { pos = (*fp->_seek)(fp->_cookie, (fpos_t)0, SEEK_CUR); - if (pos == -1L) + if (pos == -1) { +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (pos); + } } if (fp->_flags & __SRD) { /* @@ -84,5 +95,8 @@ ftell(fp) */ pos += fp->_p - fp->_bf._base; } +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (pos); } diff --git a/lib/libc/stdio/fwrite.c b/lib/libc/stdio/fwrite.c index dbc2e978d7d0..7efb0ac4e277 100644 --- a/lib/libc/stdio/fwrite.c +++ b/lib/libc/stdio/fwrite.c @@ -41,6 +41,10 @@ static char sccsid[] = "@(#)fwrite.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #include "local.h" #include "fvwrite.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * Write `count' objects (each size `size') from memory to the given file. @@ -61,12 +65,18 @@ fwrite(buf, size, count, fp) uio.uio_iov = &iov; uio.uio_iovcnt = 1; +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif /* * The usual case is success (__sfvwrite returns 0); * skip the divide if this happens, since divides are * generally slow and since this occurs whenever size==0. */ - if (__sfvwrite(fp, &uio) == 0) - return (count); - return ((n - uio.uio_resid) / size); + if (__sfvwrite(fp, &uio) != 0) + count = (n - uio.uio_resid) / size; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (count); } diff --git a/lib/libc/stdio/getc.c b/lib/libc/stdio/getc.c index 1e900cd6e64a..c0726ee2db64 100644 --- a/lib/libc/stdio/getc.c +++ b/lib/libc/stdio/getc.c @@ -39,14 +39,27 @@ static char sccsid[] = "@(#)getc.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include <stdio.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * A subroutine version of the macro getc. */ #undef getc +int getc(fp) register FILE *fp; { - return (__sgetc(fp)); + int retval; +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif + retval = __sgetc(fp); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (retval); } diff --git a/lib/libc/stdio/getchar.c b/lib/libc/stdio/getchar.c index 20e52b79193e..7aeef8af645f 100644 --- a/lib/libc/stdio/getchar.c +++ b/lib/libc/stdio/getchar.c @@ -42,10 +42,23 @@ static char sccsid[] = "@(#)getchar.c 8.1 (Berkeley) 6/4/93"; * A subroutine version of the macro getchar. */ #include <stdio.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif #undef getchar +int getchar() { - return (getc(stdin)); + int retval; +#ifdef _THREAD_SAFE + _thread_flockfile(stdin,__FILE__,__LINE__); +#endif + retval = getc(stdin); +#ifdef _THREAD_SAFE + _thread_funlockfile(stdin); +#endif + return (retval); } diff --git a/lib/libc/stdio/gets.c b/lib/libc/stdio/gets.c index 0517930bbcb1..d31aeeef9148 100644 --- a/lib/libc/stdio/gets.c +++ b/lib/libc/stdio/gets.c @@ -40,6 +40,9 @@ static char sccsid[] = "@(#)gets.c 8.1 (Berkeley) 6/4/93"; #include <unistd.h> #include <stdio.h> +#include <sys/cdefs.h> + +__warn_references(gets, "warning: this program uses gets(), which is unsafe."); char * gets(buf) @@ -49,7 +52,7 @@ gets(buf) register char *s; static int warned; static char w[] = - "warning: this program uses gets(), which is unsafe.\r\n"; + "warning: this program uses gets(), which is unsafe.\n"; if (!warned) { (void) write(STDERR_FILENO, w, sizeof(w) - 1); diff --git a/lib/libc/stdio/mktemp.c b/lib/libc/stdio/mktemp.c index 6cedd6a6be43..3f5966e1f424 100644 --- a/lib/libc/stdio/mktemp.c +++ b/lib/libc/stdio/mktemp.c @@ -40,6 +40,7 @@ static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93"; #include <fcntl.h> #include <errno.h> #include <stdio.h> +#include <unistd.h> #include <ctype.h> static int _gettemp(); diff --git a/lib/libc/stdio/printf.3 b/lib/libc/stdio/printf.3 index 4238a90a889e..e675b3eda99b 100644 --- a/lib/libc/stdio/printf.3 +++ b/lib/libc/stdio/printf.3 @@ -43,10 +43,12 @@ .Nm fprintf , .Nm sprintf , .Nm snprintf , +.Nm asprintf , .Nm vprintf , .Nm vfprintf, .Nm vsprintf , -.Nm vsnprintf +.Nm vsnprintf , +.Nm vasprintf .Nd formatted output conversion .Sh SYNOPSIS .Fd #include <stdio.h> @@ -58,8 +60,8 @@ .Fn sprintf "char *str" "const char *format" ... .Ft int .Fn snprintf "char *str" "size_t size" "const char *format" ... -.\" .Ft int -.\" .Fn smprintf "const char *format" ... +.Ft int +.Fn asprintf "char **ret" "const char *format" ... .Fd #include <stdarg.h> .Ft int .Fn vprintf "const char *format" "va_list ap" @@ -69,8 +71,8 @@ .Fn vsprintf "char *str" "char *format" "va_list ap" .Ft int .Fn vsnprintf "char *str" "size_t size" "const char *format" "va_list ap" -.\" .Ft int -.\" .Fn vsmprintf "const char *format" "va_list ap" +.Ft int +.Fn vasprintf "char **ret" "const char *format" "va_list ap" .Sh DESCRIPTION The .Fn printf @@ -94,45 +96,47 @@ write output to the given output and .Fn vsnprintf write to the character string -.Fa str . -.\" .IR str ; -.\" and -.\" .I smprintf -.\" and -.\" .I vsmprintf -.\" dynamically allocate a new string with -.\" .IR malloc . +.Fa str ; +and +.Fn asprintf +and +.Fn vasprintf +dynamically allocate a new string with +.Xr malloc 3 +/ +.Xr realloc 3 . +.Pp These functions write the output under the control of a .Fa format string that specifies how subsequent arguments (or arguments accessed via the variable-length argument facilities of .Xr stdarg 3 ) are converted for output. -.\" Except for -.\" .I smprintf -.\" and -.\" .IR vsmprintf , -.\" all of these functions return +.Pp These functions return the number of characters printed (not including the trailing .Ql \e0 used to end output to strings). -.\" .I Smprintf -.\" and -.\" .I vsmprintf -.\" return a pointer to a string of an appropriate length; -.\" this pointer should be passed to -.\" .I free -.\" to release the associated storage -.\" when it is no longer needed. -.\" If sufficient space is not avaliable, -.\" .I smprintf -.\" and -.\" .I vsmprintf -.\" will return -.\" .SM -.\" .BR +.Pp +.Fn Asprintf +and +.Fn vasprintf +return a pointer to a buffer sufficiently large to hold the +string in the +.Fa ret +argument; +This pointer should be passed to +.Xr free 3 +to release the allocated storage when it is no longer needed. +If sufficient space cannot be allocated, +.Fn asprintf +and +.Fn vasprintf +will return -1 and set +.Fa ret +to be a NULL pointer. +.Pp .Fn Snprintf and .Fn vsnprintf @@ -147,6 +151,7 @@ if the return value is greater than or equal to the .Fa size argument, the string was too short and some of the printed characters were discarded. +.Pp .Fn Sprintf and .Fn vsprintf @@ -600,6 +605,15 @@ The functions and .Fn vsnprintf are new to this release. +.Pp +The functions +.Fn asprintf +and +.Fn vasprintf +first appeared in the GNU C library. This implementation is thought +to be compatable but is not derived from the GNU code. This implementation +was written by Peter Wemm <peter@FreeBSD.org> and first appeared in +FreeBSD-2.2. .Sh BUGS The conversion formats .Cm \&%D , diff --git a/lib/libc/stdio/putc.c b/lib/libc/stdio/putc.c index c18353b7044a..f1d42b11454b 100644 --- a/lib/libc/stdio/putc.c +++ b/lib/libc/stdio/putc.c @@ -39,15 +39,28 @@ static char sccsid[] = "@(#)putc.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include <stdio.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * A subroutine version of the macro putc. */ #undef putc +int putc(c, fp) int c; register FILE *fp; { - return (__sputc(c, fp)); + int retval; +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif + retval = __sputc(c, fp); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (retval); } diff --git a/lib/libc/stdio/putchar.c b/lib/libc/stdio/putchar.c index 036b8970772c..5e04a6c72f2c 100644 --- a/lib/libc/stdio/putchar.c +++ b/lib/libc/stdio/putchar.c @@ -39,16 +39,29 @@ static char sccsid[] = "@(#)putchar.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include <stdio.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif #undef putchar /* * A subroutine version of the macro putchar */ +int putchar(c) int c; { + int retval; register FILE *so = stdout; - return (__sputc(c, so)); +#ifdef _THREAD_SAFE + _thread_flockfile(so,__FILE__,__LINE__); +#endif + retval = __sputc(c, so); +#ifdef _THREAD_SAFE + _thread_funlockfile(so); +#endif + return (retval); } diff --git a/lib/libc/stdio/puts.c b/lib/libc/stdio/puts.c index 96a81842b86f..e8a35c533a51 100644 --- a/lib/libc/stdio/puts.c +++ b/lib/libc/stdio/puts.c @@ -41,13 +41,19 @@ static char sccsid[] = "@(#)puts.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #include <string.h> #include "fvwrite.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * Write the given string to stdout, appending a newline. */ +int puts(s) char const *s; { + int retval; size_t c = strlen(s); struct __suio uio; struct __siov iov[2]; @@ -59,5 +65,12 @@ puts(s) uio.uio_resid = c + 1; uio.uio_iov = &iov[0]; uio.uio_iovcnt = 2; - return (__sfvwrite(stdout, &uio) ? EOF : '\n'); +#ifdef _THREAD_SAFE + _thread_flockfile(stdout,__FILE__,__LINE__); +#endif + retval = __sfvwrite(stdout, &uio) ? EOF : '\n'; +#ifdef _THREAD_SAFE + _thread_funlockfile(stdout); +#endif + return (retval); } diff --git a/lib/libc/stdio/putw.c b/lib/libc/stdio/putw.c index 4ba898207f1e..604bed0b7925 100644 --- a/lib/libc/stdio/putw.c +++ b/lib/libc/stdio/putw.c @@ -40,11 +40,17 @@ static char sccsid[] = "@(#)putw.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #include "fvwrite.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif +int putw(w, fp) int w; FILE *fp; { + int retval; struct __suio uio; struct __siov iov; @@ -52,5 +58,12 @@ putw(w, fp) iov.iov_len = uio.uio_resid = sizeof(w); uio.uio_iov = &iov; uio.uio_iovcnt = 1; - return (__sfvwrite(fp, &uio)); +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif + retval = __sfvwrite(fp, &uio); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (retval); } diff --git a/lib/libc/stdio/rewind.c b/lib/libc/stdio/rewind.c index 4f8391b5030f..f20f6197f977 100644 --- a/lib/libc/stdio/rewind.c +++ b/lib/libc/stdio/rewind.c @@ -40,12 +40,22 @@ static char sccsid[] = "@(#)rewind.c 8.1 (Berkeley) 6/4/93"; #include <errno.h> #include <stdio.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif void rewind(fp) register FILE *fp; { +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif (void) fseek(fp, 0L, SEEK_SET); clearerr(fp); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif errno = 0; /* not required, but seems reasonable */ } diff --git a/lib/libc/stdio/scanf.c b/lib/libc/stdio/scanf.c index d36b13a9ed55..5faf018711d3 100644 --- a/lib/libc/stdio/scanf.c +++ b/lib/libc/stdio/scanf.c @@ -44,10 +44,16 @@ static char sccsid[] = "@(#)scanf.c 8.1 (Berkeley) 6/4/93"; #else #include <varargs.h> #endif +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif #if __STDC__ +int scanf(char const *fmt, ...) #else +int scanf(fmt, va_alist) char *fmt; va_dcl @@ -61,7 +67,13 @@ scanf(fmt, va_alist) #else va_start(ap); #endif +#ifdef _THREAD_SAFE + _thread_flockfile(stdin,__FILE__,__LINE__); +#endif ret = __svfscanf(stdin, fmt, ap); va_end(ap); +#ifdef _THREAD_SAFE + _thread_funlockfile(stdin); +#endif return (ret); } diff --git a/lib/libc/stdio/setvbuf.c b/lib/libc/stdio/setvbuf.c index 867f9b4951f6..c6c037d7e293 100644 --- a/lib/libc/stdio/setvbuf.c +++ b/lib/libc/stdio/setvbuf.c @@ -41,11 +41,16 @@ static char sccsid[] = "@(#)setvbuf.c 8.2 (Berkeley) 11/16/93"; #include <stdio.h> #include <stdlib.h> #include "local.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * Set one of the three kinds of buffering, optionally including * a buffer. */ +int setvbuf(fp, buf, mode, size) register FILE *fp; char *buf; @@ -65,6 +70,9 @@ setvbuf(fp, buf, mode, size) if ((mode != _IOFBF && mode != _IOLBF) || (int)size < 0) return (EOF); +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif /* * Write current buffer, if any. Discard unread input (including * ungetc data), cancel line buffering, and free old buffer if @@ -116,6 +124,9 @@ nbf: fp->_w = 0; fp->_bf._base = fp->_p = fp->_nbuf; fp->_bf._size = 1; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (ret); } flags |= __SMBF; @@ -156,5 +167,8 @@ nbf: } __cleanup = _cleanup; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (ret); } diff --git a/lib/libc/stdio/snprintf.c b/lib/libc/stdio/snprintf.c index 3c3cf7d8169b..82fad1a75904 100644 --- a/lib/libc/stdio/snprintf.c +++ b/lib/libc/stdio/snprintf.c @@ -46,8 +46,10 @@ static char sccsid[] = "@(#)snprintf.c 8.1 (Berkeley) 6/4/93"; #endif #if __STDC__ +int snprintf(char *str, size_t n, char const *fmt, ...) #else +int snprintf(str, n, fmt, va_alist) char *str; size_t n; @@ -66,6 +68,7 @@ snprintf(str, n, fmt, va_alist) #else va_start(ap); #endif + f._file = -1; f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = n - 1; diff --git a/lib/libc/stdio/sprintf.c b/lib/libc/stdio/sprintf.c index 254064fabd54..e71f7d091bc2 100644 --- a/lib/libc/stdio/sprintf.c +++ b/lib/libc/stdio/sprintf.c @@ -48,8 +48,10 @@ static char sccsid[] = "@(#)sprintf.c 8.1 (Berkeley) 6/4/93"; #include "local.h" #if __STDC__ +int sprintf(char *str, char const *fmt, ...) #else +int sprintf(str, fmt, va_alist) char *str; char *fmt; @@ -60,6 +62,7 @@ sprintf(str, fmt, va_alist) va_list ap; FILE f; + f._file = -1; f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = INT_MAX; diff --git a/lib/libc/stdio/sscanf.c b/lib/libc/stdio/sscanf.c index bb7274437802..dc96312a5635 100644 --- a/lib/libc/stdio/sscanf.c +++ b/lib/libc/stdio/sscanf.c @@ -59,8 +59,10 @@ eofread(cookie, buf, len) } #if __STDC__ +int sscanf(const char *str, char const *fmt, ...) #else +int sscanf(str, fmt, va_alist) char *str; char *fmt; @@ -71,6 +73,7 @@ sscanf(str, fmt, va_alist) va_list ap; FILE f; + f._file = -1; f._flags = __SRD; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._r = strlen(str); diff --git a/lib/libc/stdio/stdio.3 b/lib/libc/stdio/stdio.3 index 7ebc782d06e3..3bde13c391a7 100644 --- a/lib/libc/stdio/stdio.3 +++ b/lib/libc/stdio/stdio.3 @@ -63,7 +63,7 @@ If a file can support positioning requests (such as a disk file, as opposed to a terminal) then a .Em file position indicator associated with the stream is positioned at the start of the file (byte -zero), unless the file is opened with appended mode. If append mode +zero), unless the file is opened with append mode. If append mode is used, the position indicator will be placed the end-of-file. The position indicator is maintained by subsequent reads, writes and positioning requests. All input occurs as if the characters @@ -111,7 +111,7 @@ opened explicitly: (for reading conventional input), .It .Em standard output -(for writing conventional input), and +(for writing conventional output), and .It .Em standard error (for writing diagnostic output). @@ -229,7 +229,7 @@ feof check and reset stream status ferror check and reset stream status fflush flush a stream fgetc get next character or word from input stream -fgetline get a line from a stream +fgetln get a line from a stream fgetpos reposition a stream fgets get a line from a stream fileno check and reset stream status diff --git a/lib/libc/stdio/ungetc.c b/lib/libc/stdio/ungetc.c index deaed759992f..25f59d7420fb 100644 --- a/lib/libc/stdio/ungetc.c +++ b/lib/libc/stdio/ungetc.c @@ -42,6 +42,10 @@ static char sccsid[] = "@(#)ungetc.c 8.2 (Berkeley) 11/3/93"; #include <stdlib.h> #include <string.h> #include "local.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * Expand the ungetc buffer `in place'. That is, adjust fp->_p when @@ -49,7 +53,7 @@ static char sccsid[] = "@(#)ungetc.c 8.2 (Berkeley) 11/3/93"; * and move the bytes in the buffer around as necessary so that they * are all at the end (stack-style). */ -static +static int __submore(fp) register FILE *fp; { @@ -82,6 +86,7 @@ __submore(fp) return (0); } +int ungetc(c, fp) int c; register FILE *fp; @@ -90,16 +95,27 @@ ungetc(c, fp) return (EOF); if (!__sdidinit) __sinit(); +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif if ((fp->_flags & __SRD) == 0) { /* * Not already reading: no good unless reading-and-writing. * Otherwise, flush any current write stuff. */ - if ((fp->_flags & __SRW) == 0) + if ((fp->_flags & __SRW) == 0) { +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (EOF); + } if (fp->_flags & __SWR) { - if (__sflush(fp)) + if (__sflush(fp)) { +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (EOF); + } fp->_flags &= ~__SWR; fp->_w = 0; fp->_lbfsize = 0; @@ -113,10 +129,17 @@ ungetc(c, fp) * This may require expanding the current ungetc buffer. */ if (HASUB(fp)) { - if (fp->_r >= fp->_ub._size && __submore(fp)) + if (fp->_r >= fp->_ub._size && __submore(fp)) { +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (EOF); + } *--fp->_p = c; fp->_r++; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (c); } fp->_flags &= ~__SEOF; @@ -130,6 +153,9 @@ ungetc(c, fp) fp->_p[-1] == c) { fp->_p--; fp->_r++; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (c); } @@ -144,5 +170,8 @@ ungetc(c, fp) fp->_ubuf[sizeof(fp->_ubuf) - 1] = c; fp->_p = &fp->_ubuf[sizeof(fp->_ubuf) - 1]; fp->_r = 1; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (c); } diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c index f53db612ff60..0f241deebe10 100644 --- a/lib/libc/stdio/vfprintf.c +++ b/lib/libc/stdio/vfprintf.c @@ -59,6 +59,10 @@ static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93"; #include "local.h" #include "fvwrite.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* Define FLOATING_POINT to get floating point. */ #define FLOATING_POINT @@ -302,8 +306,7 @@ vfprintf(fp, fmt0, ap) u_quad_t uqval; /* %q integers */ int base; /* base for [diouxX] conversion */ int dprec; /* a copy of prec if [diouxX], 0 otherwise */ - int fieldsz; /* field size expanded by sign, etc */ - int realsz; /* field size expanded by dprec */ + int realsz; /* field size expanded by dprec, sign, etc */ int size; /* size of converted field or string */ char *xdigs; /* digits for [xX] conversion */ #define NIOV 8 @@ -366,14 +369,25 @@ vfprintf(fp, fmt0, ap) flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \ (u_long)va_arg(ap, u_int)) +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */ - if (cantwrite(fp)) + if (cantwrite(fp)) { +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (EOF); + } /* optimise fprintf(stderr) (and other unbuffered Unix files) */ if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && - fp->_file >= 0) + fp->_file >= 0) { +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (__sbprintf(fp, fmt0, ap)); + } fmt = (char *)fmt0; uio.uio_iov = iovp = iov; @@ -693,14 +707,13 @@ number: if ((dprec = prec) >= 0) * floating precision; finally, if LADJUST, pad with blanks. * * Compute actual size, so we know how much to pad. - * fieldsz excludes decimal prec; realsz includes it. + * size excludes decimal prec; realsz includes it. */ - fieldsz = size; + realsz = dprec > size ? dprec : size; if (sign) - fieldsz++; + realsz++; else if (flags & HEXPREFIX) - fieldsz += 2; - realsz = dprec > fieldsz ? dprec : fieldsz; + realsz += 2; /* right-adjusting blank padding */ if ((flags & (LADJUST|ZEROPAD)) == 0) @@ -720,7 +733,7 @@ number: if ((dprec = prec) >= 0) PAD(width - realsz, zeroes); /* leading zeroes from decimal precision */ - PAD(dprec - fieldsz, zeroes); + PAD(dprec - size, zeroes); /* the string or number proper */ #ifdef FLOATING_POINT @@ -782,7 +795,12 @@ number: if ((dprec = prec) >= 0) done: FLUSH(); error: - return (__sferror(fp) ? EOF : ret); + if (__sferror(fp)) + ret = EOF; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (ret); /* NOTREACHED */ } diff --git a/lib/libc/stdio/vscanf.c b/lib/libc/stdio/vscanf.c index 5d128650b54b..677039ecc8e4 100644 --- a/lib/libc/stdio/vscanf.c +++ b/lib/libc/stdio/vscanf.c @@ -39,11 +39,24 @@ static char sccsid[] = "@(#)vscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include <stdio.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif +int vscanf(fmt, ap) const char *fmt; _BSD_VA_LIST_ ap; { + int retval; - return (__svfscanf(stdin, fmt, ap)); +#ifdef _THREAD_SAFE + _thread_flockfile(stdin,__FILE__,__LINE__); +#endif + retval = __svfscanf(stdin, fmt, ap); +#ifdef _THREAD_SAFE + _thread_funlockfile(stdin); +#endif + return (retval); } diff --git a/lib/libc/stdio/vsnprintf.c b/lib/libc/stdio/vsnprintf.c index ccc8af63f355..1bff18bb8d3d 100644 --- a/lib/libc/stdio/vsnprintf.c +++ b/lib/libc/stdio/vsnprintf.c @@ -40,6 +40,7 @@ static char sccsid[] = "@(#)vsnprintf.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> +int vsnprintf(str, n, fmt, ap) char *str; size_t n; @@ -51,6 +52,7 @@ vsnprintf(str, n, fmt, ap) if ((int)n < 1) return (EOF); + f._file = -1; f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = n - 1; diff --git a/lib/libc/stdio/vsprintf.c b/lib/libc/stdio/vsprintf.c index c6e192ae07c6..cdfb9ebb91f5 100644 --- a/lib/libc/stdio/vsprintf.c +++ b/lib/libc/stdio/vsprintf.c @@ -41,6 +41,7 @@ static char sccsid[] = "@(#)vsprintf.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #include <limits.h> +int vsprintf(str, fmt, ap) char *str; const char *fmt; @@ -49,6 +50,7 @@ vsprintf(str, fmt, ap) int ret; FILE f; + f._file = -1; f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = INT_MAX; diff --git a/lib/libc/stdio/vsscanf.c b/lib/libc/stdio/vsscanf.c index 540f2906b89b..0d4d05a10a4f 100644 --- a/lib/libc/stdio/vsscanf.c +++ b/lib/libc/stdio/vsscanf.c @@ -52,14 +52,15 @@ eofread(cookie, buf, len) return (0); } +int vsscanf(str, fmt, ap) const char *str; const char *fmt; _BSD_VA_LIST_ ap; { - int ret; FILE f; + f._file = -1; f._flags = __SRD; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._r = strlen(str); |
