Sync libc/stdio with FreeBSD:
authorPeter Avalos <pavalos@dragonflybsd.org>
Sun, 19 Apr 2009 05:26:39 +0000 (05:26 +0000)
committerPeter Avalos <pavalos@dragonflybsd.org>
Tue, 21 Apr 2009 06:20:06 +0000 (06:20 +0000)
* Rewrite asprintf() as a wrapper around vasprintf().

* Add dprintf() and vdprintf() from POSIX.1-2008.

* Remove an obsolete comment from fclose.3 regarding the placement
of a FUNLOCKFILE() call.

* Remove useless variable 'nofile' in fdopen().

* Remove comment about clearerr() being the only method of clearing
the EOF indicator, fseek() may also be used for this.

* Add commentary explaining why we return EBADF upon attempts to fflush()
a read-only file.

* Fix a few style and whitespace nits.

* Suggest that fgets() be used instead of gets().

* Don't use __sgetc() to avoid overwriting fwide(3) orientation
(__srget() call by __sgetc() uses _SET_ORIENTATION macro).

* Fix a sign-compare issue in fgetwln().

* Use C99-style initializers.

* Correct some buffer sizes.

* Rework the floating point code in printf().  Significant changes:

 - We used to round long double arguments to double.  Now we print
 them properly.

 - Bugs involving '%F', corner cases of '#' and 'g' format
 specifiers, and the '.*' precision specifier have been fixed.

 - Added support for the "'" specifier to print thousands' grouping
 characters in a locale-dependent manner.

 - Implement the __vfprintf() side of hexadecimal floating point
 support.  All that is still needed is a routine to convert the
 mantissa to hex digits one nibble at a time in the style of ultoa().

* Add restrict qualifier.

* Add rewind() to the list of functions which may fail and set errno.

* Improve documentation for fgetpos() and fsetpos(), and discourage
users from assuming that fpos_t is an integral type.

* Describe the restrictions on seeking on wide character streams, and also
point out that fseek() clears the ungetwc() buffer.

* Save errno from getting clobbered where appropriate.

* Resulting fseek() offset must fit in long, required by POSIX,
so add LONG_MAX and final tests for it.

* Disallow negative seek as POSIX requires for fseek{o}.

* Catch few possible off_t overflows.

* Make fseek(... SEEK_CUR) fails if current file-position is unspecified.

* Move all stdio internal flags processing and setting out of __sread(),
__swrite() and __sseek() to higher level. According to funopen(3) they all
are just wrappers to something like standard read(2), write(2) and
lseek(2), i.e. must not touch stdio internals because they are replaceable
with any other functions knows nothing about stdio internals.

* Rename cantwrite() to prepwrite().  The latter is less confusing,
since the macro isn't really a predicate, and it has side-effects.
Also, don't set errno if prepwrite() fails, since this is done in
prepwrite() now.

* Fix a potential deadlock in _fwalk in a threaded environment.
A file flag (__SIGN) was added to stdio.h that, when set, tells
_fwalk to ignore it in its walk.  This seemed to be needed in
refill.c because each file needs to be locked when flushing.

* Call __sgetc() directly in getchar() instead of taking an expensive
detour through getc().

* Add getdelim() and getline().

* Document dependence of mktemp(3) on the non-reentrant arc4random(3).

* Fix a few bugs with the _gettemp() routine which implements mkstemp(),
mkstemps(), and mkdtemp().
 - Add proper range checking for the 'slen' parameter passed to mkstemps().
 - Try all possible permutations of a template if a collision is encountered.
 Previously, once a single template character reached 'z', it would not wrap
 around to '0' and keep going until it encountered the original starting
 letter.  In the edge case that the randomly generated starting name used
 all 'z' characters, only that single name would be tried before giving up.

* Use arc4random_uniform(3) since modulo size is not power of 2 in _gettemp.

* Write the message to stderr, not file descriptor 2, so that perror()
writes to the correct stream if stderr has been redirected with freopen().

* Use strerror_r() to format the error message so that strerror()'s static
buffer does not get clobbered in perror().

* Move the positional argument handling code for vfprintf() to a new file,
printf-pos.c, and move common definitions to printflocal.h.

* Remove advertising clause in the copyrights.

* In rewind.c:
 1) add missing __sinit() as in fseek() it pretends to be.
 2) use clearerr_unlocked() since we already lock stream before _fseeko()
 3) don't zero errno at the end, it explicitely required by POSIX as the
 only one method to test rewind() error condition.
 4) don't clearerr() if error happens in _fseeko()

* When __SOPT is cleared, clear __SOFF too.

* Save a few cycles and don't initialize the locking fields in FILE if
they aren't going to be used later.

* Add ENVIRONMENT section to tmpnam(3) and mention there that TMPDIR is
ignored when issetugid(3) is true.  Also add a SECURITY CONSIDERATIONS
section.

* Describe file-position behaviour from POSIX in ungetc(3).

* Remove duplicate check for EOF from ungetc(); __ungetc() already checks.

* In vasprintf, free the buffer when __vfprintf() fails and don't bother
trying to shrink the buffer with realloc() before returning it.

* Rework the floating point code in printf().  Significant changes:
 - We used to round long double arguments to double.  Now we print
 them properly.
 - Bugs involving '%F', corner cases of '#' and 'g' format
 specifiers, and the '.*' precision specifier have been fixed.
 - Added support for the "'" specifier to print thousands' grouping
 characters in a locale-dependent manner.
 - Implement the __vfprintf() side of hexadecimal floating point
 support.  All that is still needed is a routine to convert the
 mantissa to hex digits one nibble at a time in the style of ultoa().

* %e conversions with precision 0 should not cause a decimal point to
  be printed.

* Fix %f conversions where the number of significant digits is < expt.

* %E-like %g and %G conversions should remove trailing zeroes unless
the # flag is present.  Implement this behavior and add a comment
describing it.

* Implement __hdtoa() and __hldtoa() and enable printf() support for %a
and %A, which print floating-point numbers in hexadecimal.

* Add an extensible printf implementation compatible with GLIBC.

* Add support for multibyte decimal_point encodings, e.g., U+066B.

* Add support for multibyte thousands_sep encodings, e.g., U+066C.
The integer thousands' separator code is rewritten in order to
avoid having to preallocate a buffer for the largest possible
digit string with the most possible instances of the longest
possible multibyte thousands' separator. The new version inserts
thousands' separators for integers using the same code as floating point.

* Introduce a local variable and use it instead of passed in parameter
to get rid of restrict qualifier discarding in vswscanf().

* Set the error indicator on an attempt to write to a read-only stream
in wsetup.c.

* Move the format_arg() attribute handling to <sys/cdefs.h> where it
belongs.

Obtained-from:  FreeBSD & NetBSD

140 files changed:
include/Makefile
include/printf.h [new file with mode: 0644]
include/stdarg.h
include/stdio.h
lib/libc/include/libc_private.h
lib/libc/stdio/Makefile.inc
lib/libc/stdio/_flock_stub.c
lib/libc/stdio/asprintf.c
lib/libc/stdio/clrerr.c
lib/libc/stdio/dprintf.c [copied from lib/libc/stdio/wprintf.c with 83% similarity]
lib/libc/stdio/fclose.3
lib/libc/stdio/fclose.c
lib/libc/stdio/fcloseall.c [copied from lib/libc/stdio/getwc.c with 70% similarity]
lib/libc/stdio/fdopen.c
lib/libc/stdio/feof.c
lib/libc/stdio/ferror.3
lib/libc/stdio/ferror.c
lib/libc/stdio/fflush.3
lib/libc/stdio/fflush.c
lib/libc/stdio/fgetc.c
lib/libc/stdio/fgetln.3
lib/libc/stdio/fgetln.c
lib/libc/stdio/fgetpos.c
lib/libc/stdio/fgets.3
lib/libc/stdio/fgets.c
lib/libc/stdio/fgetwc.c
lib/libc/stdio/fgetwln.3
lib/libc/stdio/fgetwln.c
lib/libc/stdio/fgetws.c
lib/libc/stdio/fileno.c
lib/libc/stdio/findfp.c
lib/libc/stdio/flags.c
lib/libc/stdio/floatio.h
lib/libc/stdio/fopen.3
lib/libc/stdio/fopen.c
lib/libc/stdio/fprintf.c
lib/libc/stdio/fpurge.c
lib/libc/stdio/fputc.c
lib/libc/stdio/fputs.3
lib/libc/stdio/fputs.c
lib/libc/stdio/fread.3
lib/libc/stdio/fread.c
lib/libc/stdio/freopen.c
lib/libc/stdio/fscanf.c
lib/libc/stdio/fseek.3
lib/libc/stdio/fseek.c
lib/libc/stdio/fsetpos.c
lib/libc/stdio/ftell.c
lib/libc/stdio/funopen.3
lib/libc/stdio/funopen.c
lib/libc/stdio/fvwrite.c
lib/libc/stdio/fwalk.c
lib/libc/stdio/fwprintf.c
lib/libc/stdio/fwrite.c
lib/libc/stdio/fwscanf.c
lib/libc/stdio/getc.3
lib/libc/stdio/getc.c
lib/libc/stdio/getchar.c
lib/libc/stdio/getdelim.c [new file with mode: 0644]
lib/libc/stdio/getline.3 [new file with mode: 0644]
lib/libc/stdio/getline.c [copied from lib/libc/stdio/vwscanf.c with 80% similarity]
lib/libc/stdio/gets.c
lib/libc/stdio/getw.c
lib/libc/stdio/getwc.3
lib/libc/stdio/getwc.c
lib/libc/stdio/getwchar.c
lib/libc/stdio/local.h
lib/libc/stdio/makebuf.c
lib/libc/stdio/mktemp.3
lib/libc/stdio/mktemp.c
lib/libc/stdio/perror.c
lib/libc/stdio/printf-pos.c [new file with mode: 0644]
lib/libc/stdio/printf.3
lib/libc/stdio/printf.c
lib/libc/stdio/printfcommon.h [new file with mode: 0644]
lib/libc/stdio/printflocal.h [copied from lib/libc/stdio/putchar.c with 50% similarity]
lib/libc/stdio/priv_stdio.h
lib/libc/stdio/putc.3
lib/libc/stdio/putc.c
lib/libc/stdio/putchar.c
lib/libc/stdio/puts.c
lib/libc/stdio/putw.c
lib/libc/stdio/putwc.3
lib/libc/stdio/putwc.c
lib/libc/stdio/putwchar.c
lib/libc/stdio/refill.c
lib/libc/stdio/remove.3
lib/libc/stdio/remove.c
lib/libc/stdio/rewind.c
lib/libc/stdio/rget.c
lib/libc/stdio/scanf.3
lib/libc/stdio/scanf.c
lib/libc/stdio/setbuf.3
lib/libc/stdio/setbuf.c
lib/libc/stdio/setbuffer.c
lib/libc/stdio/setvbuf.c
lib/libc/stdio/snprintf.c
lib/libc/stdio/sprintf.c
lib/libc/stdio/sscanf.c
lib/libc/stdio/stdio.3
lib/libc/stdio/stdio.c
lib/libc/stdio/swprintf.c
lib/libc/stdio/swscanf.c
lib/libc/stdio/tempnam.c
lib/libc/stdio/tmpfile.c
lib/libc/stdio/tmpnam.3
lib/libc/stdio/tmpnam.c
lib/libc/stdio/ungetc.3
lib/libc/stdio/ungetc.c
lib/libc/stdio/vasprintf.c
lib/libc/stdio/vdprintf.c [copied from lib/libc/stdio/fwscanf.c with 65% similarity]
lib/libc/stdio/vfprintf.c
lib/libc/stdio/vfscanf.c
lib/libc/stdio/vfwprintf.c
lib/libc/stdio/vfwscanf.c
lib/libc/stdio/vprintf.c
lib/libc/stdio/vscanf.c
lib/libc/stdio/vsnprintf.c
lib/libc/stdio/vsprintf.c
lib/libc/stdio/vsscanf.c
lib/libc/stdio/vswprintf.c
lib/libc/stdio/vswscanf.c
lib/libc/stdio/vwprintf.c
lib/libc/stdio/vwscanf.c
lib/libc/stdio/wbuf.c
lib/libc/stdio/wprintf.3
lib/libc/stdio/wprintf.c
lib/libc/stdio/wscanf.3
lib/libc/stdio/wscanf.c
lib/libc/stdio/wsetup.c
lib/libc/stdio/xprintf.c [new file with mode: 0644]
lib/libc/stdio/xprintf_errno.c [copied from lib/libc/stdio/fwscanf.c with 61% similarity]
lib/libc/stdio/xprintf_float.c [new file with mode: 0644]
lib/libc/stdio/xprintf_hexdump.c [copied from lib/libc/stdio/fgetws.c with 53% similarity]
lib/libc/stdio/xprintf_int.c [new file with mode: 0644]
lib/libc/stdio/xprintf_quote.c [new file with mode: 0644]
lib/libc/stdio/xprintf_str.c [new file with mode: 0644]
lib/libc/stdio/xprintf_time.c [copied from lib/libc/stdio/getc.c with 50% similarity]
lib/libc/stdio/xprintf_vis.c [copied from lib/libc/stdio/fgetws.c with 57% similarity]
sys/sys/cdefs.h

index 231c074..2d086fc 100644 (file)
@@ -17,7 +17,7 @@ INCS= a.out.h ar.h assert.h bitstring.h complex.h cpio.h ctype.h db.h \
        langinfo.h libgen.h limits.h link.h locale.h malloc.h math.h memory.h \
        mpool.h monetary.h ndbm.h netconfig.h \
        netdb.h nl_types.h nlist.h nss.h nsswitch.h objformat.h \
-       paths.h pthread.h pthread_np.h pwd.h \
+       paths.h printf.h pthread.h pthread_np.h pwd.h \
        ranlib.h readpassphrase.h regex.h regexp.h \
        res_update.h resolv.h re_comp.h rmd160.h \
        search.h setjmp.h sgtty.h \
diff --git a/include/printf.h b/include/printf.h
new file mode 100644 (file)
index 0000000..ffa24e1
--- /dev/null
@@ -0,0 +1,163 @@
+/*-
+ * Copyright (c) 2005 Poul-Henning Kamp
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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: src/include/printf.h,v 1.4 2006/03/02 10:01:52 phk Exp $
+ */
+
+#ifndef _PRINTF_H_
+#define _PRINTF_H_
+
+#include <wchar.h>
+
+/*
+ * The API defined by glibc allows a renderer to take multiple arguments
+ * This is obviously usable for things like (ptr+len) pairs etc.
+ * But the do not actually provide support for it at the end of the day,
+ * they offer only one argument to the arginfo function, but do accept
+ * >1 returns, although the do not check the types of those arguments
+ * argument
+ * Be compatible for now.
+ */
+#define __PRINTFMAXARG         2
+
+struct printf_info {
+       /* GLIBC compatible */
+       int             prec;
+       int             width;
+       wchar_t         spec;
+       unsigned        is_long_double;
+       unsigned        is_char;
+       unsigned        is_short;
+       unsigned        is_long;
+       unsigned        alt;
+       unsigned        space;
+       unsigned        left;
+       unsigned        showsign;
+       unsigned        group;
+       unsigned        extra;
+       unsigned        wide;
+       wchar_t         pad;
+
+       /* FreeBSD extensions */
+
+       unsigned        is_quad;
+       unsigned        is_intmax;
+       unsigned        is_ptrdiff;
+       unsigned        is_size;
+
+       /* private */
+       int             sofar;
+       unsigned        get_width;
+       unsigned        get_prec;
+       const char      *begin;
+       const char      *end;
+       void            *arg[__PRINTFMAXARG];
+};
+
+enum {
+       PA_INT          = (1 << 0),     /* int */
+       PA_CHAR         = (1 << 1),     /* int, cast to char */
+       PA_WCHAR        = (1 << 2),     /* wide char */
+       PA_STRING       = (1 << 3),     /* const char * (with '\0') */
+       PA_WSTRING      = (1 << 4),     /* const wchar_t * */
+       PA_POINTER      = (1 << 5),     /* void * */
+       PA_FLOAT        = (1 << 6),     /* float */
+       PA_DOUBLE       = (1 << 7)      /* double */
+};
+
+#define        PA_FLAG_MASK            0xff0000
+#define        PA_FLAG_LONG_LONG       (1 << 16)
+#define        PA_FLAG_LONG            (1 << 17)
+#define        PA_FLAG_SHORT           (1 << 18)
+#define        PA_FLAG_PTR             (1 << 19)
+#define        PA_FLAG_QUAD            (1 << 20)
+#define        PA_FLAG_INTMAX          (1 << 21)
+#define        PA_FLAG_SIZE            (1 << 22)
+#define        PA_FLAG_PTRDIFF         (1 << 23)
+#define        PA_FLAG_LONG_DOUBLE     PA_FLAG_LONG_LONG
+
+typedef int printf_arginfo_function(const struct printf_info *, size_t, int *);
+typedef int printf_function(FILE *, const struct printf_info *, const void *const *);
+
+/* FreeBSD extension */
+struct __printf_io;
+typedef int printf_render(struct __printf_io *, const struct printf_info *, const void *const *);
+
+/* vprintf.c */
+extern const char __lowercase_hex[17];
+extern const char __uppercase_hex[17];
+
+void __printf_flush(struct __printf_io *io);
+int __printf_puts(struct __printf_io *io, const void *ptr, int len);
+int __printf_pad(struct __printf_io *io, int n, int zero);
+int __printf_out(struct __printf_io *io, const struct printf_info *pi, const void *ptr, int len);
+
+int __xvprintf(FILE *fp, const char *fmt0, va_list ap);
+extern int __use_xprintf;
+
+/* GLIBC compat */
+int register_printf_function(int spec, printf_function *render, printf_arginfo_function *arginfo);
+
+/* FreeBSD */
+int register_printf_render(int spec, printf_render *render, printf_arginfo_function *arginfo);
+int register_printf_render_std(const unsigned char *specs);
+
+/* vprintf_errno.c */
+printf_arginfo_function                __printf_arginfo_errno;
+printf_render                  __printf_render_errno;
+
+/* vprintf_float.c */
+printf_arginfo_function                __printf_arginfo_float;
+printf_render                  __printf_render_float;
+
+/* vprintf_hexdump.c */
+printf_arginfo_function                __printf_arginfo_hexdump;
+printf_render                  __printf_render_hexdump;
+
+/* vprintf_int.c */
+printf_arginfo_function                __printf_arginfo_ptr;
+printf_arginfo_function                __printf_arginfo_int;
+printf_render                  __printf_render_ptr;
+printf_render                  __printf_render_int;
+
+/* vprintf_quoute.c */
+printf_arginfo_function                __printf_arginfo_quote;
+printf_render                  __printf_render_quote;
+
+/* vprintf_str.c */
+printf_arginfo_function                __printf_arginfo_chr;
+printf_render                  __printf_render_chr;
+printf_arginfo_function                __printf_arginfo_str;
+printf_render                  __printf_render_str;
+
+/* vprintf_time.c */
+printf_arginfo_function                __printf_arginfo_time;
+printf_render                  __printf_render_time;
+
+/* vprintf_vis.c */
+printf_arginfo_function                __printf_arginfo_vis;
+printf_render                  __printf_render_vis;
+
+#endif /* !_PRINTF_H */
index f8c48a5..f26be77 100644 (file)
 #include <machine/stdarg.h>
 #endif
 
+#ifndef _VA_LIST_DECLARED
 typedef        __va_list       va_list;
+#define        _VA_LIST_DECLARED
+#endif
 
 #define va_start(ap, last)     __va_start(ap, last)
 #define va_arg(ap, type)       __va_arg(ap, type)
index 06ba005..90f6d29 100644 (file)
@@ -34,7 +34,7 @@
  * SUCH DAMAGE.
  *
  *     @(#)stdio.h     8.5 (Berkeley) 4/29/95
- * $FreeBSD: src/include/stdio.h,v 1.24.2.5 2002/11/09 08:07:20 imp Exp $
+ * $FreeBSD: src/include/stdio.h,v 1.78 2009/03/25 08:07:52 das Exp $
  * $DragonFly: src/include/stdio.h,v 1.14 2008/06/05 17:53:10 swildner Exp $
  */
 
 #define        _STDIO_H_
 
 #include <sys/cdefs.h>
-#ifndef _SYS_STDINT_H_
-#include <sys/stdint.h>
-#endif
-#ifndef _MACHINE_STDARG_H_
-#include <machine/stdarg.h>
-#endif
+#include <sys/_null.h>
+#include <sys/types.h>
+
+typedef        __off_t         fpos_t;
 
 #ifndef _SIZE_T_DECLARED
-#define _SIZE_T_DECLARED
-typedef __size_t       size_t;
+typedef        __size_t        size_t;
+#define        _SIZE_T_DECLARED
 #endif
 
-#include <sys/_null.h>
+#if __BSD_VISIBLE || __POSIX_VISIBLE >= 200809
+#ifndef _OFF_T_DECLARED
+#define        _OFF_T_DECLARED
+typedef        __off_t         off_t;
+#endif
+#ifndef _SSIZE_T_DECLARED
+#define        _SSIZE_T_DECLARED
+typedef        __ssize_t       ssize_t;
+#endif
+#endif
 
-typedef        __off_t fpos_t;
+#if __BSD_VISIBLE || __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE
+#ifndef _VA_LIST_DECLARED
+typedef        __va_list       va_list;
+#define        _VA_LIST_DECLARED
+#endif
+#endif
+
+#define        _FSTDIO                 /* Define for new stdio with functions. */
 
 /*
  * stdio state variables.
@@ -81,7 +95,7 @@ typedef       __off_t fpos_t;
 typedef struct __FILE FILE;
 
 struct __FILE_public {
-       unsigned char   *_p;    /* current position in (some) buffer */
+       unsigned char   *_p;            /* current position in (some) buffer */
        int             _flags;         /* flags, below; this FILE is free if 0 */
        int             _fileno;        /* fileno, if Unix descriptor, else -1 */
        __ssize_t       _r;             /* read space left for getc() */
@@ -89,9 +103,14 @@ struct __FILE_public {
        __ssize_t       _lbfsize;       /* 0 or -_bf._size, for inline putc */
 };
 
+#ifndef _STDSTREAM_DECLARED
 __BEGIN_DECLS
-extern FILE *__stdinp, *__stdoutp, *__stderrp;
+extern FILE *__stdinp;
+extern FILE *__stdoutp;
+extern FILE *__stderrp;
 __END_DECLS
+#define        _STDSTREAM_DECLARED
+#endif
 
 #define        __SLBF  0x0001          /* line buffered */
 #define        __SNBF  0x0002          /* unbuffered */
@@ -109,6 +128,7 @@ __END_DECLS
 #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
@@ -132,11 +152,13 @@ __END_DECLS
  * (which could fail).  Do not use this for anything.
  */
                                /* must be == _POSIX_STREAM_MAX <limits.h> */
+#ifndef FOPEN_MAX
 #define        FOPEN_MAX       20      /* must be <= OPEN_MAX <sys/syslimits.h> */
+#endif
 #define        FILENAME_MAX    1024    /* must be <= PATH_MAX <sys/syslimits.h> */
 
 /* System V/ANSI C; this is the wrong way to do this, do *not* use these. */
-#ifndef _ANSI_SOURCE
+#if __XSI_VISIBLE
 #define        P_tmpdir        "/tmp/"
 #endif
 #define        L_tmpnam        1024    /* XXX must be == PATH_MAX */
@@ -152,178 +174,229 @@ __END_DECLS
 #define        SEEK_END        2       /* set file offset to EOF plus offset */
 #endif
 
-#define        stdin   (__stdinp)
-#define        stdout  (__stdoutp)
-#define        stderr  (__stderrp)
+#define        stdin   __stdinp
+#define        stdout  __stdoutp
+#define        stderr  __stderrp
 
+__BEGIN_DECLS
 /*
  * Functions defined in ANSI C standard.
  */
-__BEGIN_DECLS
 void    clearerr(FILE *);
 int     fclose(FILE *);
 int     feof(FILE *);
-int     feof_unlocked(FILE *);
 int     ferror(FILE *);
-int     ferror_unlocked(FILE *);
 int     fflush(FILE *);
 int     fgetc(FILE *);
-int     fgetpos(FILE *, fpos_t *);
-char   *fgets(char *, int, FILE *);
-FILE   *fopen(const char *, const char *);
-int     fprintf(FILE *, const char *, ...);
+int     fgetpos(FILE * __restrict, fpos_t * __restrict);
+char   *fgets(char * __restrict, int, FILE * __restrict);
+FILE   *fopen(const char * __restrict, const char * __restrict);
+int     fprintf(FILE * __restrict, const char * __restrict, ...);
 int     fputc(int, FILE *);
-int     fputs(const char *, FILE *);
-size_t  fread(void *, size_t, size_t, FILE *);
-FILE   *freopen(const char *, const char *, FILE *);
-int     fscanf(FILE *, const char *, ...);
+int     fputs(const char * __restrict, FILE * __restrict);
+size_t  fread(void * __restrict, size_t, size_t, FILE * __restrict);
+FILE   *freopen(const char * __restrict, const char * __restrict,
+                FILE * __restrict);
+int     fscanf(FILE * __restrict, const char * __restrict, ...);
 int     fseek(FILE *, long, int);
 int     fsetpos(FILE *, const fpos_t *);
 long    ftell(FILE *);
-size_t  fwrite(const void *, size_t, size_t, FILE *);
+size_t  fwrite(const void * __restrict, size_t, size_t, FILE * __restrict);
 int     getc(FILE *);
-int     getc_unlocked(FILE *);
 int     getchar(void);
-int     getchar_unlocked(void);
 char   *gets(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(const char *);
-int     printf(const char *, ...);
+int     printf(const char * __restrict, ...);
 int     putc(int, FILE *);
-int     putc_unlocked(int, FILE *);
 int     putchar(int);
-int     putchar_unlocked(int);
 int     puts(const char *);
 int     remove(const char *);
 int     rename(const char *, const char *);
 void    rewind(FILE *);
-int     scanf(const char *, ...);
-void    setbuf(FILE *, char *);
-int     setvbuf(FILE *, char *, int, size_t);
-int     sprintf(char *, const char *, ...);
-int     sscanf(const char *, const char *, ...);
+int     scanf(const char * __restrict, ...);
+void    setbuf(FILE * __restrict, char * __restrict);
+int     setvbuf(FILE * __restrict, char * __restrict, int, size_t);
+int     sprintf(char * __restrict, const char * __restrict, ...);
+int     sscanf(const char * __restrict, const char * __restrict, ...);
 FILE   *tmpfile(void);
 char   *tmpnam(char *);
 int     ungetc(int, FILE *);
-int     vfprintf(FILE *, const char *, __va_list);
-int     vprintf(const char *, __va_list);
-int     vsprintf(char *, const char *, __va_list);
-__END_DECLS
+int     vfprintf(FILE * __restrict, const char * __restrict, __va_list);
+int     vprintf(const char * __restrict, __va_list);
+int     vsprintf(char * __restrict, const char * __restrict, __va_list);
+
+#if __ISO_C_VISIBLE >= 1999
+int     snprintf(char * __restrict, size_t, const char * __restrict, ...)
+           __printflike(3, 4);
+int     vfscanf(FILE * __restrict, const char * __restrict, __va_list)
+           __scanflike(2, 0);
+int     vscanf(const char * __restrict, __va_list) __scanflike(1, 0);
+int     vsnprintf(char * __restrict, size_t, const char * __restrict,
+                  __va_list) __printflike(3, 0);
+int     vsscanf(const char * __restrict, const char * __restrict, __va_list)
+           __scanflike(2, 0);
+#endif
 
 /*
- * Functions defined in POSIX 1003.1.
+ * Functions defined in all versions of POSIX 1003.1.
  */
-#ifndef _ANSI_SOURCE
+#if __BSD_VISIBLE || __POSIX_VISIBLE <= 199506
 /* size for cuserid(3); UT_NAMESIZE + 1, see <utmp.h> */
-#define        L_cuserid       17
+#define        L_cuserid       17      /* legacy */
+#endif
 
+#if __POSIX_VISIBLE
 #define        L_ctermid       1024    /* size for ctermid(3); PATH_MAX */
 
-__BEGIN_DECLS
 char   *ctermid(char *);
 FILE   *fdopen(int, const char *);
 int     fileno(FILE *);
-int     fileno_unlocked(FILE *);
+#endif /* __POSIX_VISIBLE */
+
+#if __POSIX_VISIBLE >= 199209
+int     pclose(FILE *);
+FILE   *popen(const char *, const char *);
+#endif
+
+#if __POSIX_VISIBLE >= 199506
 int     ftrylockfile(FILE *);
 void    flockfile(FILE *);
 void    funlockfile(FILE *);
-__END_DECLS
-#endif /* not ANSI */
 
 /*
- * Portability hacks.  See <sys/types.h>.
+ * These are normally used through macros as defined below, but POSIX
+ * requires functions as well.
  */
-#if !defined (_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
-#ifndef _FTRUNCATE_DECLARED
-#define        _FTRUNCATE_DECLARED
-int     ftruncate(int, __off_t);
+int     getc_unlocked(FILE *);
+int     getchar_unlocked(void);
+int     putc_unlocked(int, FILE *);
+int     putchar_unlocked(int);
 #endif
-#ifndef _LSEEK_DECLARED
-#define        _LSEEK_DECLARED
-__off_t         lseek(int, __off_t, int);
+#if __BSD_VISIBLE
+void    clearerr_unlocked(FILE *);
+int     feof_unlocked(FILE *);
+int     ferror_unlocked(FILE *);
+int     fileno_unlocked(FILE *);
 #endif
-#ifndef _MMAP_DECLARED
-#define        _MMAP_DECLARED
-void   *mmap(void *, size_t, int, int, int, __off_t);
+
+#if __POSIX_VISIBLE >= 200112
+int     fseeko(FILE *, __off_t, int);
+__off_t         ftello(FILE *);
 #endif
-#ifndef _TRUNCATE_DECLARED
-#define        _TRUNCATE_DECLARED
-int     truncate(const char *, __off_t);
+
+#if __BSD_VISIBLE || __XSI_VISIBLE > 0 && __XSI_VISIBLE < 600
+int     getw(FILE *);
+int     putw(int, FILE *);
+#endif /* BSD or X/Open before issue 6 */
+
+#if __XSI_VISIBLE
+char   *tempnam(const char *, const char *);
 #endif
-__END_DECLS
-#endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */
+
+#if __BSD_VISIBLE || __POSIX_VISIBLE >= 200809
+ssize_t         getdelim(char ** __restrict, size_t * __restrict, int,
+                 FILE * __restrict);
+/* int  renameat(int, const char *, int, const char *); */
+int     vdprintf(int, const char * __restrict, __va_list);
+
+/*
+ * Every programmer and his dog wrote functions called getline() and dprintf()
+ * before POSIX.1-2008 came along and decided to usurp the names, so we
+ * don't prototype them by default unless one of the following is true:
+ *   a) the app has requested them specifically by defining _WITH_GETLINE or
+ *      _WITH_DPRINTF, respectively
+ *   b) the app has requested a POSIX.1-2008 environment via _POSIX_C_SOURCE
+ *   c) the app defines a GNUism such as _BSD_SOURCE or _GNU_SOURCE
+ */
+#ifndef _WITH_GETLINE
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#define        _WITH_GETLINE
+#elif defined(_POSIX_C_SOURCE)
+#if _POSIX_C_SOURCE >= 200809
+#define        _WITH_GETLINE
+#endif
+#endif
+#endif
+
+#ifdef _WITH_GETLINE
+ssize_t         getline(char ** __restrict, size_t * __restrict, FILE * __restrict);
+#endif
+
+#ifndef _WITH_DPRINTF
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#define        _WITH_DPRINTF
+#elif defined(_POSIX_C_SOURCE)
+#if _POSIX_C_SOURCE >= 200809
+#define        _WITH_DPRINTF
+#endif
+#endif
+#endif
+
+#ifdef _WITH_DPRINTF
+int     dprintf(int, const char * __restrict, ...);
+#endif
+
+#endif /* __BSD_VISIBLE || __POSIX_VISIBLE >= 200809 */
 
 /*
  * Routines that are purely local.
  */
-#if !defined (_ANSI_SOURCE) && !defined(_POSIX_SOURCE)
-__BEGIN_DECLS
+#if __BSD_VISIBLE
 int     asprintf(char **, const char *, ...) __printflike(2, 3);
 char   *ctermid_r(char *);
+void    fcloseall(void);
 void   *fcookie(FILE *);
 char   *fgetln(FILE *, size_t *);
-#if __GNUC__ == 2 && __GNUC_MINOR__ >= 7 || __GNUC__ >= 3
-#define        __ATTR_FORMAT_ARG       __attribute__((__format_arg__(2)))
-#else
-#define        __ATTR_FORMAT_ARG
-#endif
-const char *fmtcheck(const char *, const char *) __ATTR_FORMAT_ARG;
+const char *fmtcheck(const char *, const char *) __format_arg(2);
 __ssize_t __fpending(const FILE *);
 int     fpurge(FILE *);
-int     fseeko(FILE *, __off_t, int);
-__off_t         ftello(FILE *);
-int     getw(FILE *);
-int     pclose(FILE *);
-FILE   *popen(const char *, const char *);
-int     putw(int, FILE *);
 void    setbuffer(FILE *, char *, int);
 int     setlinebuf(FILE *);
-char   *tempnam(const char *, const char *);
-int     snprintf(char *, size_t, const char *, ...) __printflike(3, 4);
-int     vasprintf(char **, const char *, __va_list)
-           __printflike(2, 0);
-int     vsnprintf (char *, size_t, const char *, __va_list)
-           __printflike(3, 0);
-int     vscanf(const char *, __va_list) __scanflike(1, 0);
-int     vsscanf(const char *, const char *, __va_list)
-           __scanflike(2, 0);
-__END_DECLS
+int     vasprintf(char **, const char *, __va_list) __printflike(2, 0);
 
 /*
- * 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.
+ * The system error table contains messages for the first sys_nerr
+ * positive errno values.  Use strerror() or strerror_r() from <string.h>
+ * instead.
  */
-#define         vfscanf        __vfscanf
+extern __const int sys_nerr;
+extern __const char *__const sys_errlist[];
 
 /*
  * Stdio function-access interface.
  */
-__BEGIN_DECLS
-FILE   *funopen(const void *,
-                int (*)(void *, char *, int),
+FILE   *funopen(const void *, int (*)(void *, char *, int),
                 int (*)(void *, const char *, int),
-                fpos_t (*)(void *, fpos_t, int),
-                int (*)(void *));
-__END_DECLS
+                fpos_t (*)(void *, fpos_t, int), int (*)(void *));
 #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 */
+
+/*
+ * Portability hacks.  See <sys/types.h>.
+ */
+#ifndef _FTRUNCATE_DECLARED
+#define        _FTRUNCATE_DECLARED
+int     ftruncate(int, __off_t);
+#endif
+#ifndef _LSEEK_DECLARED
+#define        _LSEEK_DECLARED
+__off_t         lseek(int, __off_t, int);
+#endif
+#ifndef _MMAP_DECLARED
+#define        _MMAP_DECLARED
+void   *mmap(void *, size_t, int, int, int, __off_t);
+#endif
+#ifndef _TRUNCATE_DECLARED
+#define        _TRUNCATE_DECLARED
+int     truncate(const char *, __off_t);
+#endif
+#endif /* __BSD_VISIBLE */
 
 /*
  * Functions internal to the implementation.
  */
-__BEGIN_DECLS
 int    __srget(FILE *);
-int    __vfscanf(FILE *, const char *, __va_list);
-int    __svfscanf(FILE *, const char *, __va_list);
 int    __swbuf(int, FILE *);
-size_t __sreadahead(FILE *);
-__END_DECLS
 
 /*
  * The __sfoo functions are here so that we can
@@ -383,6 +456,23 @@ __sfileno(FILE *_fp)
        return (_p->_fileno);
 }
 
+extern int __isthreaded;
+
+#define        feof(p)         (!__isthreaded ? __sfeof(p) : (feof)(p))
+#define        ferror(p)       (!__isthreaded ? __sferror(p) : (ferror)(p))
+#define        clearerr(p)     (!__isthreaded ? __sclearerr(p) : (clearerr)(p))
+
+#if __POSIX_VISIBLE
+#define        fileno(p)       (!__isthreaded ? __sfileno(p) : (fileno)(p))
+#endif
+
+#define        getc(fp)        (!__isthreaded ? __sgetc(fp) : (getc)(fp))
+#define        putc(x, fp)     (!__isthreaded ? __sputc(x, fp) : (putc)(x, fp))
+
+#define        getchar()       getc(stdin)
+#define        putchar(x)      putc(x, stdout)
+
+#if __BSD_VISIBLE
 /*
  * 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.
@@ -390,15 +480,15 @@ __sfileno(FILE *_fp)
 #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)
+#if __POSIX_VISIBLE >= 199506
+#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
 
+__END_DECLS
 #endif /* !_STDIO_H_ */
index 18a8e49..7b95fa4 100644 (file)
@@ -64,14 +64,6 @@ extern int   __isthreaded;
 #define        FLOCKFILE(fp)           if (__isthreaded) _FLOCKFILE(fp)
 #define        FUNLOCKFILE(fp)         if (__isthreaded) _funlockfile(fp)
 
-/*
- * Internal _*() functions (XXX add all of them)
- */
-
-#ifdef _STDIO_H_
-int _fseeko(FILE *, __off_t, int);
-#endif
-
 /*
  * Initialise TLS static programs
  */
index f08f176..376574a 100644 (file)
@@ -6,30 +6,40 @@
 .PATH: ${.CURDIR}/../libc/stdio
 
 SRCS+= __fpending.c _flock_stub.c \
-       asprintf.c clrerr.c fclose.c fcookie.c fdopen.c feof.c ferror.c \
+       asprintf.c clrerr.c dprintf.c \
+       fclose.c fcloseall.c fcookie.c fdopen.c feof.c ferror.c \
        fflush.c fgetc.c fgetln.c fgetpos.c fgets.c fgetwc.c fgetwln.c \
        fgetws.c fileno.c findfp.c flags.c fopen.c fprintf.c fpurge.c \
        fputc.c fputs.c fputwc.c fputws.c fread.c freopen.c fscanf.c \
        fseek.c fsetpos.c ftell.c funopen.c fvwrite.c fwalk.c fwide.c \
-       fwprintf.c fwrite.c fwscanf.c getc.c getchar.c gets.c getw.c \
-       getwc.c getwchar.c makebuf.c mktemp.c perror.c printf.c putc.c \
+       fwprintf.c fwrite.c fwscanf.c getc.c getchar.c \
+       getdelim.c getline.c gets.c getw.c \
+       getwc.c getwchar.c makebuf.c mktemp.c perror.c \
+       printf-pos.c printf.c putc.c \
        putchar.c puts.c putw.c putwc.c putwchar.c refill.c remove.c rewind.c \
        rget.c scanf.c setbuf.c setbuffer.c setvbuf.c snprintf.c sprintf.c \
        sreadahead.c \
        sscanf.c stdio.c swprintf.c swscanf.c tempnam.c tmpfile.c tmpnam.c \
-       ungetc.c ungetwc.c vasprintf.c vfprintf.c vfscanf.c vfwprintf.c \
+       ungetc.c ungetwc.c vasprintf.c vdprintf.c \
+       vfprintf.c vfscanf.c vfwprintf.c \
        vfwscanf.c vprintf.c vscanf.c vsnprintf.c vsprintf.c vsscanf.c \
        vswprintf.c vswscanf.c vwprintf.c vwscanf.c wbuf.c wprintf.c \
-       wscanf.c wsetup.c
+       wscanf.c wsetup.c xprintf.c xprintf_errno.c xprintf_float.c \
+       xprintf_hexdump.c xprintf_int.c xprintf_quote.c xprintf_str.c \
+       xprintf_time.c xprintf_vis.c
 
 
 .if ${LIB} == "c"
 MAN+=  fclose.3 ferror.3 fflush.3 fgetln.3 fgets.3 fgetwln.3 fgetws.3 \
        flockfile.3 fopen.3 fputs.3 fputws.3 fread.3 fseek.3 funopen.3 \
-       fwide.3 getc.3  getwc.3 mktemp.3 printf.3 putc.3 putwc.3 remove.3 \
+       fwide.3 getc.3 getline.3 \
+       getwc.3 mktemp.3 printf.3 putc.3 putwc.3 remove.3 \
        scanf.3 setbuf.3 stdio.3 tmpnam.3 ungetc.3 ungetwc.3 wprintf.3 wscanf.3
 
-MLINKS+=ferror.3 clearerr.3 ferror.3 feof.3 ferror.3 fileno.3
+MLINKS+=fclose.3 fcloseall.3
+MLINKS+=ferror.3 clearerr.3 ferror.3 clearerr_unlocked.3 \
+       ferror.3 feof.3 ferror.3 feof_unlocked.3 ferror.3 ferror_unlocked.3 \
+       ferror.3 fileno.3 ferror.3 fileno_unlocked.3
 MLINKS+=fflush.3 fpurge.3
 MLINKS+=fgets.3 gets.3
 MLINKS+=flockfile.3 funlockfile.3 \
@@ -42,11 +52,12 @@ MLINKS+=fseek.3 fgetpos.3 fseek.3 fseeko.3 fseek.3 fsetpos.3 fseek.3 ftell.3 \
 MLINKS+=funopen.3 fropen.3 funopen.3 fwopen.3
 MLINKS+=getc.3 fgetc.3 getc.3 getc_unlocked.3 getc.3 getchar_unlocked.3 \
        getc.3 getchar.3 getc.3 getw.3
+MLINKS+=getline.3 getdelim.3
 MLINKS+=getwc.3 fgetwc.3 getwc.3 getwchar.3
 MLINKS+=mktemp.3 mkdtemp.3 mktemp.3 mkstemp.3 mktemp.3 mkstemps.3
-MLINKS+=printf.3 asprintf.3 printf.3 fprintf.3 \
+MLINKS+=printf.3 asprintf.3 printf.3 dprintf.3 printf.3 fprintf.3 \
        printf.3 snprintf.3 printf.3 sprintf.3 \
-       printf.3 vasprintf.3 \
+       printf.3 vasprintf.3 printf.3 vdprintf.3 \
        printf.3 vfprintf.3 printf.3 vprintf.3 printf.3 vsnprintf.3 \
        printf.3 vsprintf.3
 MLINKS+=putc.3 fputc.3 putc.3 putc_unlocked.3 putc.3 putchar_unlocked.3 \
index c055a25..97ecc8b 100644 (file)
  * 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 John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libc/stdio/_flock_stub.c,v 1.3 1999/08/28 00:00:55 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/_flock_stub.c,v 1.16 2008/04/17 22:17:53 jhb Exp $
  * $DragonFly: src/lib/libc/stdio/_flock_stub.c,v 1.10 2005/07/23 23:14:44 joerg Exp $
+ */
+
+/*
+ * POSIX stdio FILE locking functions. These assume that the locking
+ * is only required at FILE structure level, not at file descriptor
+ * level too.
  *
  */
 
 #include "local.h"
 #include "priv_stdio.h"
 
-void __flockfile(FILE *fp);
-void __flockfile_debug(FILE *fp, char *fname, int lineno);
-int  __ftrylockfile(FILE *fp);
-void __funlockfile(FILE *fp);
 
 /*
- * Externally visible weak symbols.
+ * Weak symbols for externally visible functions in this file:
  */
-__weak_reference(__flockfile, flockfile);
-__weak_reference(__flockfile, _flockfile);
-__weak_reference(__flockfile_debug, _flockfile_debug);
-__weak_reference(__ftrylockfile, ftrylockfile);
-__weak_reference(__ftrylockfile, _ftrylockfile);
-__weak_reference(__funlockfile, funlockfile);
-__weak_reference(__funlockfile, _funlockfile);
+__weak_reference(_flockfile, flockfile);
+__weak_reference(_flockfile_debug_stub, _flockfile_debug);
+__weak_reference(_ftrylockfile, ftrylockfile);
+__weak_reference(_funlockfile, funlockfile);
 
 void
-__flockfile(FILE *fp)
+_flockfile(FILE *fp)
 {
        pthread_t curthread = _pthread_self();
 
-       if (fp->fl_owner == curthread)
-               fp->fl_count++;
+       if (fp->_fl_owner == curthread)
+               fp->_fl_count++;
        else {
                /*
                 * Make sure this mutex is treated as a private
                 * internal mutex:
                 */
-               _pthread_mutex_lock(&fp->fl_mutex);
-               fp->fl_owner = curthread;
-               fp->fl_count = 1;
+               _pthread_mutex_lock(&fp->_fl_mutex);
+               fp->_fl_owner = curthread;
+               fp->_fl_count = 1;
        }
 }
 
+/*
+ * This can be overriden by the threads library if it is linked in.
+ */
 void
-__flockfile_debug(FILE *fp, char *fname __unused, int lineno __unused)
+_flockfile_debug_stub(FILE *fp, char *fname __unused, int lineno __unused)
 {
        _flockfile(fp);
 }
 
 int
-__ftrylockfile(FILE *fp)
+_ftrylockfile(FILE *fp)
 {
        pthread_t curthread = _pthread_self();
        int     ret = 0;
 
-       if (fp->fl_owner == curthread)
-               fp->fl_count++;
+       if (fp->_fl_owner == curthread)
+               fp->_fl_count++;
        /*
         * Make sure this mutex is treated as a private
         * internal mutex:
         */
-       else if (_pthread_mutex_trylock(&fp->fl_mutex) == 0) {
-               fp->fl_owner = curthread;
-               fp->fl_count = 1;
+       else if (_pthread_mutex_trylock(&fp->_fl_mutex) == 0) {
+               fp->_fl_owner = curthread;
+               fp->_fl_count = 1;
        }
        else
                ret = -1;
@@ -104,33 +103,33 @@ __ftrylockfile(FILE *fp)
 }
 
 void
-__funlockfile(FILE *fp)
+_funlockfile(FILE *fp)
 {
        pthread_t       curthread = _pthread_self();
 
        /*
         * Check if this file is owned by the current thread:
         */
-       if (fp->fl_owner == curthread) {
+       if (fp->_fl_owner == curthread) {
                /*
                 * Check if this thread has locked the FILE
                 * more than once:
                 */
-               if (fp->fl_count > 1)
+               if (fp->_fl_count > 1) {
                        /*
                         * Decrement the count of the number of
                         * times the running thread has locked this
                         * file:
                         */
-                       fp->fl_count--;
-               else {
+                       fp->_fl_count--;
+               else {
                        /*
                         * The running thread will release the
                         * lock now:
                         */
-                       fp->fl_count = 0;
-                       fp->fl_owner = NULL;
-                       _pthread_mutex_unlock(&fp->fl_mutex);
+                       fp->_fl_count = 0;
+                       fp->_fl_owner = NULL;
+                       _pthread_mutex_unlock(&fp->_fl_mutex);
                }
        }
 }
index b5006aa..3ece30f 100644 (file)
@@ -1,8 +1,9 @@
-/*     $OpenBSD: asprintf.c,v 1.4 1998/06/21 22:13:46 millert Exp $    */
-
-/*
- * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
- * All rights reserved.
+/*-
+ * 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
  * 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. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
+ * 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 ``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 AUTHOR 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.
+ * 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.
  *
- * $FreeBSD: src/lib/libc/stdio/asprintf.c,v 1.6 1999/08/28 00:00:55 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/asprintf.c,v 1.15 2009/03/02 04:11:42 das Exp $
  * $DragonFly: src/lib/libc/stdio/asprintf.c,v 1.8 2006/03/02 18:05:30 joerg Exp $
  */
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
 #include <stdarg.h>
-
-#include "local.h"
-#include "priv_stdio.h"
+#include <stdio.h>
 
 int
-asprintf(char **str, char const *fmt, ...)
+asprintf(char ** __restrict s, const char * __restrict fmt, ...)
 {
        int ret;
        va_list ap;
-       FILE f;
 
-       f.pub._fileno = -1;
-       f.pub._flags = __SWR | __SSTR | __SALC;
-       f._bf._base = f.pub._p = (unsigned char *)malloc(128);
-       if (f._bf._base == NULL) {
-               *str = NULL;
-               errno = ENOMEM;
-               return (-1);
-       }
-       f._bf._size = f.pub._w = 127;           /* Leave room for the NUL */
-       f._up = NULL;
-       f.fl_mutex = PTHREAD_MUTEX_INITIALIZER;
-       f.fl_owner = NULL;
-       f.fl_count = 0;
-       memset(WCIO_GET(&f), 0, sizeof(struct wchar_io_data));
        va_start(ap, fmt);
-       ret = __vfprintf(&f, fmt, ap);          /* Use unlocked __vfprintf */
+       ret = vasprintf(s, fmt, ap);
        va_end(ap);
-       if (ret < 0) {
-               free(f._bf._base);
-               *str = NULL;
-               errno = ENOMEM;
-               return (-1);
-       }
-       *f.pub._p = '\0';
-       *str = (char *)f._bf._base;
        return (ret);
 }
index 9d6b509..53fc843 100644 (file)
  * 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.
@@ -34,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)clrerr.c        8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/clrerr.c,v 1.7 1999/08/28 00:00:55 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/clrerr.c,v 1.12 2008/05/05 16:03:52 jhb Exp $
  * $DragonFly: src/lib/libc/stdio/clrerr.c,v 1.4 2005/01/31 22:29:40 dillon Exp $
  */
 
@@ -42,7 +38,9 @@
 #include <stdio.h>
 #include "un-namespace.h"
 #include "libc_private.h"
-#undef clearerr
+
+#undef clearerr
+#undef clearerr_unlocked
 
 void
 clearerr(FILE *fp)
@@ -51,3 +49,9 @@ clearerr(FILE *fp)
        __sclearerr(fp);
        FUNLOCKFILE(fp);
 }
+
+void
+clearerr_unlocked(FILE *fp)
+{
+       __sclearerr(fp);
+}
similarity index 83%
copy from lib/libc/stdio/wprintf.c
copy to lib/libc/stdio/dprintf.c
index 7441ab2..9e777fa 100644 (file)
@@ -1,8 +1,5 @@
-/*     $NetBSD: wprintf.c,v 1.1 2005/05/14 23:51:02 christos Exp $     */
-/*     $DragonFly: src/lib/libc/stdio/wprintf.c,v 1.1 2005/07/25 00:37:41 joerg Exp $ */
-
 /*-
- * Copyright (c) 2002 Tim J. Robbins
+ * Copyright (c) 2009 David Schultz <das@FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * 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: src/lib/libc/stdio/dprintf.c,v 1.1 2009/03/04 03:38:51 das Exp $
  */
 
+#define        _WITH_DPRINTF
+#include "namespace.h"
 #include <stdarg.h>
 #include <stdio.h>
-#include <wchar.h>
+#include "un-namespace.h"
 
 int
-wprintf(const wchar_t * __restrict fmt, ...)
+dprintf(int fd, const char * __restrict fmt, ...)
 {
-       int ret;
        va_list ap;
+       int ret;
 
        va_start(ap, fmt);
-       ret = vfwprintf(stdout, fmt, ap);
+       ret = vdprintf(fd, fmt, ap);
        va_end(ap);
-
        return (ret);
 }
index bb26a8d..467daa5 100644 (file)
 .\" 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.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)fclose.3   8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdio/fclose.3,v 1.7.2.4 2001/12/14 18:33:57 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdio/fclose.3,v 1.15 2007/01/09 00:28:06 imp Exp $
 .\" $DragonFly: src/lib/libc/stdio/fclose.3,v 1.4 2004/06/07 16:37:56 hmp Exp $
 .\"
-.Dd June 4, 1993
+.Dd April 22, 2006
 .Dt FCLOSE 3
 .Os
 .Sh NAME
-.Nm fclose
+.Nm fclose ,
+.Nm fcloseall
 .Nd close a stream
 .Sh LIBRARY
 .Lb libc
@@ -49,6 +46,8 @@
 .In stdio.h
 .Ft int
 .Fn fclose "FILE *stream"
+.Ft void
+.Fn fcloseall void
 .Sh DESCRIPTION
 The
 .Fn fclose
@@ -59,6 +58,12 @@ from its underlying file or set of functions.
 If the stream was being used for output, any buffered data is written
 first, using
 .Xr fflush 3 .
+.Pp
+The
+.Fn fcloseall
+function calls
+.Fn fclose
+on all open streams.
 .Sh RETURN VALUES
 Upon successful completion 0 is returned.
 Otherwise,
@@ -100,3 +105,8 @@ The
 function
 conforms to
 .St -isoC .
+.Pp
+The
+.Fn fcloseall
+function first appeared in
+.Dx 2.3 .
index 1e1a56e..d145475 100644 (file)
  * 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.
@@ -34,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)fclose.c        8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/fclose.c,v 1.8 1999/11/21 22:34:57 dt Exp $
+ * $FreeBSD: src/lib/libc/stdio/fclose.c,v 1.12 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/fclose.c,v 1.9 2005/07/23 20:23:05 joerg Exp $
  */
 
@@ -67,23 +63,9 @@ fclose(FILE *fp)
                FREEUB(fp);
        if (HASLB(fp))
                FREELB(fp);
-       /*
-        * XXX-HITEN the FUNLOCKFILE(fp) cannot be moved below because of
-        * the way the funlockfile() implementation works; it surrounds
-        * the code with a if (fp->_file >= 0)... terrible, just terrible.
-        *
-        * This mess will be cleaned up when I rewrite the file contention
-        * locking code.
-        */
-       FUNLOCKFILE(fp);
        fp->pub._fileno = -1;
        fp->pub._r = fp->pub._w = 0;    /* Mess up if reaccessed. */
-#if 0
-       if (fp->_lock != NULL) {
-               _pthread_mutex_destroy((pthread_mutex_t *)&fp->_lock);
-               fp->_lock = NULL;
-       }
-#endif
        fp->pub._flags = 0;             /* Release this FILE for reuse. */
+       FUNLOCKFILE(fp);
        return (r);
 }
similarity index 70%
copy from lib/libc/stdio/getwc.c
copy to lib/libc/stdio/fcloseall.c
index 5ef66b5..c8f7fe1 100644 (file)
@@ -1,9 +1,5 @@
-/* $NetBSD: getwc.c,v 1.3 2005/06/12 05:21:27 lukem Exp $ */
-/* $DragonFly: src/lib/libc/stdio/getwc.c,v 1.1 2005/07/25 00:37:41 joerg Exp $ */
-
 /*-
- * Copyright (c)2001 Citrus Project,
- * All rights reserved.
+ * Copyright (C) 2006 Daniel M. Eischen.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR 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)
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Citrus$
+ * $FreeBSD: src/lib/libc/stdio/fcloseall.c,v 1.2 2006/04/22 16:47:59 deischen Exp $
  */
 
 #include <stdio.h>
-#include <wchar.h>
+#include "local.h"
 
-/*
- * A subroutine version of the macro getwc.
- */
-#undef getwc
+__weak_reference(__fcloseall, fcloseall);
 
-wint_t
-getwc(FILE *fp)
+void
+__fcloseall(void)
 {
-
-       return fgetwc(fp);
+       _fwalk(fclose);
 }
index 87d1284..eae564d 100644 (file)
  * 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.
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libc/stdio/fdopen.c,v 1.3 2000/01/27 23:06:44 jasone Exp $
- * $DragonFly: src/lib/libc/stdio/fdopen.c,v 1.6 2005/07/23 20:23:05 joerg Exp $
- *
  * @(#)fdopen.c        8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdio/fdopen.c,v 1.11 2008/05/10 18:39:20 antoine Exp $
+ * $DragonFly: src/lib/libc/stdio/fdopen.c,v 1.6 2005/07/23 20:23:05 joerg Exp $
  */
 
 #include "namespace.h"
@@ -54,12 +49,8 @@ FILE *
 fdopen(int fd, const char *mode)
 {
        FILE *fp;
-       static int nofile;
        int flags, oflags, fdflags, tmp;
 
-       if (nofile == 0)
-               nofile = getdtablesize();
-
        if ((flags = __sflags(mode, &oflags)) == 0)
                return (NULL);
 
@@ -77,8 +68,8 @@ fdopen(int fd, const char *mode)
        fp->pub._flags = flags;
        /*
         * If opened for appending, but underlying descriptor does not have
-        * O_APPEND bit set, assert __SAPP so that __swrite() will lseek to
-        * end before each write.
+        * O_APPEND bit set, assert __SAPP so that __swrite() caller
+        * will _sseek() to the end before write.
         */
        if ((oflags & O_APPEND) && !(fdflags & O_APPEND))
                fp->pub._flags |= __SAPP;
index 7ad9c2c..6a67ff7 100644 (file)
  * 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.
  * SUCH DAMAGE.
  *
  * @(#)feof.c  8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/feof.c,v 1.6 1999/08/28 00:00:57 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/feof.c,v 1.12 2008/05/05 16:03:52 jhb Exp $
  * $DragonFly: src/lib/libc/stdio/feof.c,v 1.6 2005/08/27 21:35:01 joerg Exp $
  */
 
+#include "namespace.h"
 #include <stdio.h>
+#include "un-namespace.h"
 #include "libc_private.h"
 
-/*
- * A subroutine version of the macros feof and feof_unlocked.
- */
+#undef feof
 #undef feof_unlocked
 
 int
 feof(FILE *fp)
 {
-       return(__sfeof(fp));
+       int     ret;
+
+       FLOCKFILE(fp);
+       ret= __sfeof(fp);
+       FUNLOCKFILE(fp);
+       return (ret);
 }
 
 int
 feof_unlocked(FILE *fp)
 {
-       return(__sfeof(fp));
+       return (__sfeof(fp));
 }
index 9f76a04..39f5a72 100644 (file)
 .\" 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.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)ferror.3   8.2 (Berkeley) 4/19/94
-.\" $FreeBSD: src/lib/libc/stdio/ferror.3,v 1.3.2.4 2001/12/14 18:33:57 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdio/ferror.3,v 1.13 2009/01/28 14:38:41 trhodes Exp $
 .\" $DragonFly: src/lib/libc/stdio/ferror.3,v 1.2 2003/06/17 04:26:45 dillon Exp $
 .\"
-.Dd April 19, 1994
+.Dd January 28, 2009
 .Dt FERROR 3
 .Os
 .Sh NAME
 .Nm clearerr ,
+.Nm clearerr_unlocked ,
 .Nm feof ,
+.Nm feof_unlocked ,
 .Nm ferror ,
-.Nm fileno
+.Nm ferror_unlocked ,
+.Nm fileno ,
+.Nm fileno_unlocked
 .Nd check and reset stream status
 .Sh LIBRARY
 .Lb libc
 .In stdio.h
 .Ft void
 .Fn clearerr "FILE *stream"
+.Ft void
+.Fn clearerr_unlocked "FILE *stream"
 .Ft int
 .Fn feof "FILE *stream"
 .Ft int
+.Fn feof_unlocked "FILE *stream"
+.Ft int
 .Fn ferror "FILE *stream"
 .Ft int
+.Fn ferror_unlocked "FILE *stream"
+.Ft int
 .Fn fileno "FILE *stream"
+.Ft int
+.Fn fileno_unlocked "FILE *stream"
 .Sh DESCRIPTION
 The function
 .Fn clearerr
@@ -70,23 +78,41 @@ The function
 tests the end-of-file indicator for the stream pointed to by
 .Fa stream ,
 returning non-zero if it is set.
-The end-of-file indicator can only be cleared by the function
-.Fn clearerr .
+The end-of-file indicator may be cleared by explicitly calling
+.Fn clearerr ,
+or as a side-effect of other operations, e.g.\&
+.Fn fseek .
 .Pp
 The function
 .Fn ferror
 tests the error indicator for the stream pointed to by
 .Fa stream ,
 returning non-zero if it is set.
-The error indicator can only be reset by the
-.Fn clearerr
-function.
 .Pp
 The function
 .Fn fileno
 examines the argument
 .Fa stream
 and returns its integer descriptor.
+.Pp
+The
+.Fn clearerr_unlocked ,
+.Fn feof_unlocked ,
+.Fn ferror_unlocked ,
+and
+.Fn fileno_unlocked
+functions are equivalent to
+.Fn clearerr ,
+.Fn feof ,
+.Fn ferror ,
+and
+.Fn fileno
+respectively, except that the caller is responsible for locking the stream
+with
+.Xr flockfile 3
+before calling them.
+These functions may be used to avoid the overhead of locking the stream
+and to prevent races when multiple threads are operating on the same stream.
 .Sh ERRORS
 These functions should not fail and do not set the external
 variable
@@ -94,6 +120,7 @@ variable
 .Sh SEE ALSO
 .Xr open 2 ,
 .Xr fdopen 3 ,
+.Xr flockfile 3 ,
 .Xr stdio 3
 .Sh STANDARDS
 The functions
index 981b23d..dbb5243 100644 (file)
  * 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.
  * SUCH DAMAGE.
  *
  * @(#)ferror.c        8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/ferror.c,v 1.6 1999/08/28 00:00:57 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/ferror.c,v 1.12 2008/05/05 16:03:52 jhb Exp $
  * $DragonFly: src/lib/libc/stdio/ferror.c,v 1.4 2005/08/27 21:35:01 joerg Exp $
  */
 
+#include "namespace.h"
 #include <stdio.h>
+#include "un-namespace.h"
+#include "libc_private.h"
 
-/*
- * A subroutine version of the macros ferror and ferror_unlocked.
- */
+#undef ferror
 #undef ferror_unlocked
 
 int
 ferror(FILE *fp)
 {
-       return (__sferror(fp));
+       int     ret;
+
+       FLOCKFILE(fp);
+       ret = __sferror(fp);
+       FUNLOCKFILE(fp);
+       return (ret);
 }
 
 int
index 20a9918..e1b1cfc 100644 (file)
 .\" 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.
@@ -34,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)fflush.3   8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdio/fflush.3,v 1.4.2.4 2001/12/14 18:33:57 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdio/fflush.3,v 1.11 2007/01/09 00:28:06 imp Exp $
 .\" $DragonFly: src/lib/libc/stdio/fflush.3,v 1.3 2004/06/08 00:29:47 hmp Exp $
 .\"
 .Dd June 4, 1993
index 03024c2..73f7363 100644 (file)
  * 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.
@@ -34,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)fflush.c        8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/fflush.c,v 1.7 1999/08/28 00:00:58 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/fflush.c,v 1.14 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/fflush.c,v 1.6 2005/07/23 20:23:05 joerg Exp $
  */
 
@@ -47,6 +43,8 @@
 #include "local.h"
 #include "priv_stdio.h"
 
+static int     sflush_locked(FILE *);
+
 /*
  * Flush a single file, or (if fp is NULL) all files.
  * MT-safe version
@@ -57,14 +55,26 @@ fflush(FILE *fp)
        int retval;
 
        if (fp == NULL)
-               return (_fwalk(__sflush));
+               return (_fwalk(sflush_locked));
        FLOCKFILE(fp);
+
+       /*
+        * There is disagreement about the correct behaviour of fflush()
+        * when passed a file which is not open for reading.  According to
+        * the ISO C standard, the behaviour is undefined.
+        * Under linux, such an fflush returns success and has no effect;
+        * under Windows, such an fflush is documented as behaving instead
+        * as fpurge().
+        * Given that applications may be written with the expectation of
+        * either of these two behaviours, the only safe (non-astonishing)
+        * option is to return EBADF and ask that applications be fixed.
+        */
        if ((fp->pub._flags & (__SWR | __SRW)) == 0) {
                errno = EBADF;
                retval = EOF;
-       } else 
+       } else {
                retval = __sflush(fp);
-       
+       }
        FUNLOCKFILE(fp);
        return (retval);
 }
@@ -79,12 +89,13 @@ __fflush(FILE *fp)
        int retval;
 
        if (fp == NULL)
-               return (_fwalk(__sflush));
+               return (_fwalk(sflush_locked));
        if ((fp->pub._flags & (__SWR | __SRW)) == 0) {
                errno = EBADF;
                retval = EOF;
-       } else
+       } else {
                retval = __sflush(fp);
+       }
        return (retval);
 }
 
@@ -101,7 +112,7 @@ __sflush(FILE *fp)
        if ((p = fp->_bf._base) == NULL)
                return (0);
 
-       n = fp->pub._p - p;             /* write this much */
+       n = fp->pub._p - p;     /* write this much */
 
        /*
         * Set these immediately to avoid problems with longjmp and to allow
@@ -111,7 +122,7 @@ __sflush(FILE *fp)
        fp->pub._w = t & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
 
        for (; n > 0; n -= t, p += t) {
-               t = (*fp->_write)(fp->_cookie, (char *)p, n);
+               t = _swrite(fp, (char *)p, n);
                if (t <= 0) {
                        fp->pub._flags |= __SERR;
                        return (EOF);
@@ -119,3 +130,14 @@ __sflush(FILE *fp)
        }
        return (0);
 }
+
+static int
+sflush_locked(FILE *fp)
+{
+       int     ret;
+
+       FLOCKFILE(fp);
+       ret = __sflush(fp);
+       FUNLOCKFILE(fp);
+       return (ret);
+}
index bb4b1f1..807850f 100644 (file)
  * 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.
@@ -34,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)fgetc.c 8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/fgetc.c,v 1.7 1999/08/28 00:00:58 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/fgetc.c,v 1.13 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/fgetc.c,v 1.5 2005/07/23 20:23:05 joerg Exp $
  */
 
index 4175512..881e601 100644 (file)
@@ -9,10 +9,6 @@
 .\" 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.
@@ -30,7 +26,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)fgetln.3   8.3 (Berkeley) 4/19/94
-.\" $FreeBSD: src/lib/libc/stdio/fgetln.3,v 1.4.2.3 2001/12/14 18:33:57 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdio/fgetln.3,v 1.10 2009/02/28 06:00:58 das Exp $
 .\" $DragonFly: src/lib/libc/stdio/fgetln.3,v 1.2 2003/06/17 04:26:45 dillon Exp $
 .\"
 .Dd April 19, 1994
@@ -119,7 +115,9 @@ or
 .Sh SEE ALSO
 .Xr ferror 3 ,
 .Xr fgets 3 ,
+.Xr fgetwln 3 ,
 .Xr fopen 3 ,
+.Xr getline 3 ,
 .Xr putc 3
 .Sh HISTORY
 The
index 6ad3c3c..92000f2 100644 (file)
  * 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.
  * SUCH DAMAGE.
  *
  * @(#)fgetln.c        8.2 (Berkeley) 1/2/94
- * $FreeBSD: src/lib/libc/stdio/fgetln.c,v 1.6 1999/08/28 00:00:59 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/fgetln.c,v 1.11 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/fgetln.c,v 1.7 2005/11/20 11:07:30 swildner Exp $
  */
 
+#include "namespace.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include "un-namespace.h"
+
+#include "libc_private.h"
 #include "local.h"
 #include "priv_stdio.h"
 
@@ -82,9 +82,12 @@ fgetln(FILE *fp, size_t *lenp)
        size_t len;
        size_t off;
 
+       FLOCKFILE(fp);
+       ORIENT(fp, -1);
        /* make sure there is input */
        if (fp->pub._r <= 0 && __srefill(fp)) {
                *lenp = 0;
+               FUNLOCKFILE(fp);
                return (NULL);
        }
 
@@ -103,6 +106,7 @@ fgetln(FILE *fp, size_t *lenp)
                fp->pub._flags |= __SMOD;
                fp->pub._r -= len;
                fp->pub._p = p;
+               FUNLOCKFILE(fp);
                return (ret);
        }
 
@@ -141,8 +145,7 @@ fgetln(FILE *fp, size_t *lenp)
                len += diff;
                if (__slbexpand(fp, len))
                        goto error;
-               memcpy((void *)(fp->_lb._base + off), (void *)fp->pub._p,
-                   diff);
+               memcpy((void *)(fp->_lb._base + off), (void *)fp->pub._p, diff);
                fp->pub._r -= diff;
                fp->pub._p = p;
                break;
@@ -151,9 +154,11 @@ fgetln(FILE *fp, size_t *lenp)
 #ifdef notdef
        fp->_lb._base[len] = 0;
 #endif
+       FUNLOCKFILE(fp);
        return ((char *)fp->_lb._base);
 
 error:
        *lenp = 0;              /* ??? */
+       FUNLOCKFILE(fp);
        return (NULL);          /* ??? */
 }
index 59f1596..af50883 100644 (file)
  * 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.
  * SUCH DAMAGE.
  *
  * @(#)fgetpos.c       8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/fgetpos.c,v 1.8 1999/08/28 00:00:59 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/fgetpos.c,v 1.13 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/fgetpos.c,v 1.5 2005/01/31 22:29:40 dillon Exp $
  */
 
-#include "namespace.h"
 #include <stdio.h>
-#include "un-namespace.h"
-#include "libc_private.h"
 
 int
-fgetpos(FILE *fp, fpos_t *pos)
+fgetpos(FILE * __restrict fp, fpos_t * __restrict pos)
 {
-       int retval;
-       FLOCKFILE(fp);
-       retval = (*pos = ftello(fp)) == (fpos_t)-1 ? -1 : 0;
-       FUNLOCKFILE(fp);
-       return(retval);
+       /*
+        * ftello is thread-safe; no need to lock fp.
+        */
+       if ((*pos = ftello(fp)) == (fpos_t)-1)
+               return (-1);
+       else
+               return (0);
 }
index fc95b84..12b4a5b 100644 (file)
 .\" 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.
@@ -34,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)fgets.3    8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdio/fgets.3,v 1.6.2.7 2002/07/02 19:51:21 archie Exp $
+.\" $FreeBSD: src/lib/libc/stdio/fgets.3,v 1.22 2009/02/28 06:00:58 das Exp $
 .\" $DragonFly: src/lib/libc/stdio/fgets.3,v 1.3 2004/06/08 00:29:03 hmp Exp $
 .\"
 .Dd June 4, 1993
@@ -49,7 +45,7 @@
 .Sh SYNOPSIS
 .In stdio.h
 .Ft char *
-.Fn fgets "char *str" "int size" "FILE *stream"
+.Fn fgets "char * restrict str" "int size" "FILE * restrict stream"
 .Ft char *
 .Fn gets "char *str"
 .Sh DESCRIPTION
@@ -143,14 +139,19 @@ to reliably determine the length of the next incoming line,
 the use of this function enables malicious users
 to arbitrarily change a running program's functionality through
 a buffer overflow attack.
+It is strongly suggested that the
+.Fn fgets
+function be used in all cases.
 .Sh SEE ALSO
 .Xr feof 3 ,
 .Xr ferror 3 ,
-.Xr fgetln 3
+.Xr fgetln 3 ,
+.Xr fgetws 3 ,
+.Xr getline 3
 .Sh STANDARDS
 The functions
 .Fn fgets
 and
 .Fn gets
 conform to
-.St -isoC .
+.St -isoC-99 .
index 49a56d6..0958c5b 100644 (file)
  * 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.
@@ -34,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)fgets.c 8.2 (Berkeley) 12/22/93
- * $FreeBSD: src/lib/libc/stdio/fgets.c,v 1.9 1999/08/28 00:01:00 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/fgets.c,v 1.14 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/fgets.c,v 1.7 2005/11/20 11:07:30 swildner Exp $
  */
 
@@ -43,7 +39,6 @@
 #include <string.h>
 #include "un-namespace.h"
 #include "local.h"
-
 #include "libc_private.h"
 #include "priv_stdio.h"
 
@@ -63,6 +58,7 @@ fgets(char *buf, int n, FILE *fp)
                return (NULL);
 
        FLOCKFILE(fp);
+       ORIENT(fp, -1);
        s = buf;
        n--;                    /* leave space for NUL */
        while (n != 0) {
index 8b5084b..54991f3 100644 (file)
@@ -1,4 +1,4 @@
-/* $NetBSD: fgetwc.c,v 1.4 2005/06/12 05:21:27 lukem Exp $ */
+/* $NetBSD: fgetwc.c,v 1.8 2007/04/01 18:35:53 tnozaki Exp $ */
 /* $DragonFly: src/lib/libc/stdio/fgetwc.c,v 1.1 2005/07/25 00:37:41 joerg Exp $ */
 
 /*-
@@ -44,45 +44,43 @@ wint_t
 __fgetwc_unlock(FILE *fp)
 {
        struct wchar_io_data *wcio;
-       mbstate_t *st;
        wchar_t wc;
-       size_t size;
+       size_t nr;
 
        _DIAGASSERT(fp != NULL);
 
        _SET_ORIENTATION(fp, 1);
        wcio = WCIO_GET(fp);
-       if (wcio == 0) {
-               errno = ENOMEM;
-               return WEOF;
-       }
+       _DIAGASSERT(wcio != NULL);
 
        /* if there're ungetwc'ed wchars, use them */
-       if (wcio->wcio_ungetwc_inbuf) {
-               wc = wcio->wcio_ungetwc_buf[--wcio->wcio_ungetwc_inbuf];
-
-               return wc;
-       }
-
-       st = &wcio->wcio_mbstate_in;
-
-       do {
-               char c;
-               int ch = __sgetc(fp);
-
-               if (ch == EOF) {
-                       return WEOF;
-               }
+       if (wcio->wcio_ungetwc_inbuf)
+               return(wcio->wcio_ungetwc_buf[--wcio->wcio_ungetwc_inbuf]);
 
-               c = ch;
-               size = mbrtowc(&wc, &c, 1, st);
-               if (size == (size_t)-1) {
-                       errno = EILSEQ;
+       if (fp->pub._r <= 0) {
+restart:
+               if (__srefill(fp) != 0)
                        return WEOF;
+       }
+       nr = mbrtowc(&wc, (const char *)fp->pub._p,
+           (size_t)fp->pub._r, &wcio->wcio_mbstate_in);
+       if (nr == (size_t)-1) {
+               fp->pub._flags |= __SERR;
+               return WEOF;
+       } else if (nr == (size_t)-2) {
+               fp->pub._p += fp->pub._r;
+               fp->pub._r = 0;
+               goto restart;
+       }
+       if (wc == L'\0') {
+               while (*fp->pub._p != '\0') {
+                       ++fp->pub._p;
+                       --fp->pub._r;
                }
-       } while (size == (size_t)-2);
-
-       _DIAGASSERT(size == 1);
+               nr = 1;
+       }
+       fp->pub._p += nr;
+       fp->pub._r -= nr;
 
        return wc;
 }
index 4e547df..514814e 100644 (file)
@@ -1,5 +1,3 @@
-.\"    $NetBSD: fgetwln.3,v 1.1 2005/05/14 23:51:02 christos Exp $
-.\"    $DragonFly: src/lib/libc/stdio/fgetwln.3,v 1.1 2005/07/25 00:37:41 joerg Exp $
 .\" Copyright (c) 1990, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
 .\"
@@ -11,10 +9,6 @@
 .\" 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.
@@ -32,7 +26,8 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)fgetln.3   8.3 (Berkeley) 4/19/94
-.\" $FreeBSD: src/lib/libc/stdio/fgetwln.3,v 1.1 2004/07/16 06:06:09 tjr Exp $
+.\" $FreeBSD: src/lib/libc/stdio/fgetwln.3,v 1.3 2007/01/09 00:28:06 imp Exp $
+.\" $DragonFly: src/lib/libc/stdio/fgetwln.3,v 1.1 2005/07/25 00:37:41 joerg Exp $
 .\"
 .Dd July 16, 2004
 .Dt FGETWLN 3
index 9f64d32..9c71134 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: fgetwln.c,v 1.1 2005/05/14 23:51:02 christos Exp $     */
+/*     $NetBSD: fgetwln.c,v 1.2 2009/01/31 06:08:28 lukem Exp $        */
 /*     $DragonFly: src/lib/libc/stdio/fgetwln.c,v 1.1 2005/07/25 00:37:41 joerg Exp $ */
 
 /*-
@@ -48,7 +48,7 @@ fgetwln(FILE * __restrict fp, size_t *lenp)
        len = 0;
        while ((wc = __fgetwc_unlock(fp)) != WEOF) {
 #define        GROW    512
-               if (len * sizeof(wchar_t) >= fp->_lb._size &&
+               if (len * sizeof(wchar_t) >= (size_t)fp->_lb._size &&
                    __slbexpand(fp, (len + GROW) * sizeof(wchar_t)))
                        goto error;
                *((wchar_t *)(void *)fp->_lb._base + len++) = wc;
index 95a8560..31170da 100644 (file)
@@ -1,4 +1,4 @@
-/* $NetBSD: fgetws.c,v 1.1 2003/03/07 07:11:37 tshiozak Exp $ */
+/* $NetBSD: fgetws.c,v 1.2 2006/07/03 17:06:36 tnozaki Exp $ */
 /* $DragonFly: src/lib/libc/stdio/fgetws.c,v 1.1 2005/07/25 00:37:41 joerg Exp $ */
 
 /*-
@@ -61,10 +61,10 @@ fgetws(wchar_t * __restrict ws, int n, FILE * __restrict fp)
 
        wsp = ws;
        while (n-- > 1) {
-               if ((wc = __fgetwc_unlock(fp)) == WEOF && errno == EILSEQ) {
+               wc = __fgetwc_unlock(fp);
+               if (__sferror(fp) != 0)
                        goto error;
-               }
-               if (wc == WEOF) {
+               if (__sfeof(fp) != 0) {
                        if (wsp == ws) {
                                /* EOF/error, no characters read yet. */
                                goto error;
index f755bff..ea1e4bc 100644 (file)
  * 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.
  * SUCH DAMAGE.
  *
  * @(#)fileno.c        8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/fileno.c,v 1.6 1999/08/28 00:01:01 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/fileno.c,v 1.13 2008/05/05 16:03:52 jhb Exp $
  * $DragonFly: src/lib/libc/stdio/fileno.c,v 1.6 2005/08/27 21:35:01 joerg Exp $
  */
 
 #include "namespace.h"
 #include <stdio.h>
 #include "un-namespace.h"
-
 #include "libc_private.h"
 
+#undef fileno
 #undef fileno_unlocked
 
-/*
- * A subroutine version of the macros fileno and fileno_unlocked.
- */
 int
 fileno(FILE *fp)
 {
@@ -64,5 +57,5 @@ fileno(FILE *fp)
 int
 fileno_unlocked(FILE *fp)
 {
-       return(__sfileno(fp));
+       return (__sfileno(fp));
 }
index d37fd6c..eddf08f 100644 (file)
  * 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.
@@ -34,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)findfp.c        8.2 (Berkeley) 1/4/94
- * $FreeBSD: src/lib/libc/stdio/findfp.c,v 1.7.2.3 2001/08/17 02:56:31 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/findfp.c,v 1.33 2009/03/01 19:25:40 das Exp $
  * $DragonFly: src/lib/libc/stdio/findfp.c,v 1.11 2006/03/02 18:05:30 joerg Exp $
  */
 
@@ -47,7 +43,7 @@
 
 #include <spinlock.h>
 
-#include <libc_private.h>
+#include "libc_private.h"
 #include "local.h"
 #include "priv_stdio.h"
 
@@ -55,53 +51,45 @@ int __sdidinit;
 
 #define        NDYNAMIC 10             /* add ten more whenever necessary */
 
-#define        std(flags, file) \
-       {{0,flags,file,0,0,0},{NULL, 0},__sF+file,__sclose,__sread,__sseek,__swrite, \
-        {NULL,0}, 0, {0,0,0}, {0}, {NULL,0}, 0,0, NULL, PTHREAD_MUTEX_INITIALIZER, NULL, 0 }
-/*      p flags file r w _bf  cookie      close    read    seek    write */
-/*     _ub */
-
+#define        std(flags, file) {              \
+       .pub._flags = (flags),          \
+       .pub._fileno = (file),          \
+       ._cookie = __sF + (file),       \
+       ._close = __sclose,             \
+       ._read = __sread,               \
+       ._seek = __sseek,               \
+       ._write = __swrite,             \
+}
                                /* the usual - (stdin + stdout + stderr) */
 static FILE usual[FOPEN_MAX - 3];
 static struct glue uglue = { NULL, FOPEN_MAX - 3, usual };
 
-FILE __sF[3] = {
-       std(__SRD, STDIN_FILENO),               /* stdin */
-       std(__SWR, STDOUT_FILENO),              /* stdout */
-       std(__SWR|__SNBF, STDERR_FILENO)        /* stderr */
+static FILE __sF[3] = {
+       std(__SRD, STDIN_FILENO),
+       std(__SWR, STDOUT_FILENO),
+       std(__SWR|__SNBF, STDERR_FILENO)
 };
 
-/*
- * note: __sglue starts the walk chain for exit flushing and other things.
- */
-struct glue __sglue = { &uglue, 3, __sF };     /* GLOBAL, START OF LIST */
-static struct glue *lastglue = &uglue;
-
-/*
- * The following kludge is done to ensure enough binary compatibility
- * with future versions of libc.  Or rather it allows us to work with
- * libraries that have been built with a newer libc that defines these
- * symbols and expects libc to provide them.  We only have need to support
- * i386 and alpha because they are the only "old" systems we have deployed.
- */
 FILE *__stdinp = &__sF[0];
 FILE *__stdoutp = &__sF[1];
 FILE *__stderrp = &__sF[2];
 
-static struct glue *   moreglue (int);
+struct glue __sglue = { &uglue, 3, __sF };
+static struct glue *lastglue = &uglue;
+
+static struct glue *   moreglue(int);
 
 static spinlock_t thread_lock = _SPINLOCK_INITIALIZER;
 #define THREAD_LOCK()  if (__isthreaded) _SPINLOCK(&thread_lock)
 #define THREAD_UNLOCK()        if (__isthreaded) _SPINUNLOCK(&thread_lock)
 
 #if NOT_YET
-#define        SET_GLUE_PTR(ptr, val)  atomic_set_ptr(&(ptr), (uintptr_t)(val))
+#define        SET_GLUE_PTR(ptr, val)  atomic_set_rel_ptr(&(ptr), (uintptr_t)(val))
 #else
 #define        SET_GLUE_PTR(ptr, val)  ptr = val
 #endif
 
-static
-struct glue *
+static struct glue *
 moreglue(int n)
 {
        struct glue *g;
@@ -115,10 +103,8 @@ moreglue(int n)
        g->next = NULL;
        g->niobs = n;
        g->iobs = p;
-       while (--n >= 0) {
-               *p = empty;
-               p++;
-       }
+       while (--n >= 0)
+               *p++ = empty;
        return (g);
 }
 
@@ -128,8 +114,8 @@ moreglue(int n)
 FILE *
 __sfp(void)
 {
-       FILE *fp;
-       int n;
+       FILE    *fp;
+       int     n;
        struct glue *g;
 
        if (!__sdidinit)
@@ -165,12 +151,8 @@ found:
        fp->_ub._size = 0;
        fp->_lb._base = NULL;   /* no line buffer */
        fp->_lb._size = 0;
-       fp->_up = NULL;
-       fp->fl_mutex = PTHREAD_MUTEX_INITIALIZER;
-       fp->fl_owner = NULL;
-       fp->fl_count = 0;
+/*     fp->_lock = NULL; */    /* once set always set (reused) */
        memset(WCIO_GET(fp), 0, sizeof(struct wchar_io_data));
-       /* fp->_lock = NULL; */
        return (fp);
 }
 
@@ -178,8 +160,6 @@ found:
  * XXX.  Force immediate allocation of internal memory.  Not used by stdio,
  * but documented historically for certain applications.  Bad applications.
  */
-void   f_prealloc(void);
-
 __warn_references(f_prealloc, 
        "warning: this program uses f_prealloc(), which is not recommended.");
 
@@ -225,11 +205,8 @@ _cleanup(void)
 void
 __sinit(void)
 {
-       THREAD_LOCK();
-       if (__sdidinit == 0) {
-               /* Make sure we clean up on exit. */
-               __cleanup = _cleanup;           /* conservative */
-               __sdidinit = 1;
-       }
-       THREAD_UNLOCK();
+
+       /* Make sure we clean up on exit. */
+       __cleanup = _cleanup;           /* conservative */
+       __sdidinit = 1;
 }
index 0323e37..42dcd3e 100644 (file)
  * 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.
@@ -34,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)flags.c 8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/flags.c,v 1.6.2.1 2001/03/05 10:51:22 obrien Exp $
+ * $FreeBSD: src/lib/libc/stdio/flags.c,v 1.10 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/flags.c,v 1.5 2005/01/31 22:29:40 dillon Exp $
  */
 
index 3c4bebf..24efb03 100644 (file)
  * 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.
@@ -34,6 +30,7 @@
  * SUCH DAMAGE.
  *
  *     @(#)floatio.h   8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdio/floatio.h,v 1.6 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/floatio.h,v 1.2 2005/08/02 00:44:39 joerg Exp $
  */
 
  * Floating point scanf/printf (input/output) definitions.
  */
 
-/* 11-bit exponent (VAX G floating point) is 308 decimal digits */
-#define        MAXEXPDIG       308
-/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */
-#define        MAXFRACT        39
+/*
+ * MAXEXPDIG is the maximum number of decimal digits needed to store a
+ * floating point exponent in the largest supported format.  It should
+ * be ceil(log10(LDBL_MAX_10_EXP)) or, if hexadecimal floating point
+ * conversions are supported, ceil(log10(LDBL_MAX_EXP)).  But since it
+ * is presently never greater than 5 in practice, we fudge it.
+ */
+#define        MAXEXPDIG       6
+#if LDBL_MAX_EXP > 999999
+#error "floating point buffers too small"
+#endif
+
+char *__hdtoa(double, const char *, int, int *, int *, char **);
+char *__hldtoa(long double, const char *, int, int *, int *, char **);
+char *__ldtoa(long double *, int, int, int *, int *, char **);
index 369d699..e9f0ed5 100644 (file)
 .\" 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.
@@ -34,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)fopen.3    8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdio/fopen.3,v 1.7.2.6 2001/12/14 18:33:57 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdio/fopen.3,v 1.20 2007/01/09 00:28:06 imp Exp $
 .\" $DragonFly: src/lib/libc/stdio/fopen.3,v 1.4 2007/04/04 18:36:55 swildner Exp $
 .\"
 .Dd June 8, 2004
@@ -50,7 +46,7 @@
 .Sh SYNOPSIS
 .In stdio.h
 .Ft FILE *
-.Fn fopen "const char *path" "const char *mode"
+.Fn fopen "const char * restrict path" "const char * restrict mode"
 .Ft FILE *
 .Fn fdopen "int fildes" "const char *mode"
 .Ft FILE *
@@ -75,7 +71,7 @@ The stream is positioned at the beginning of the file.
 Open for reading and writing.
 The stream is positioned at the beginning of the file.
 .It Dq Li w
-Truncate file to zero length or create text file for writing.
+Truncate to zero length or create text file for writing.
 The stream is positioned at the beginning of the file.
 .It Dq Li w+
 Open for reading and writing.
index dade4e4..f12b2ba 100644 (file)
  * 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.
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libc/stdio/fopen.c,v 1.3.2.1 2001/03/05 10:53:51 obrien Exp $
- * $DragonFly: src/lib/libc/stdio/fopen.c,v 1.6 2005/11/20 11:07:30 swildner Exp $
- *
  * @(#)fopen.c 8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdio/fopen.c,v 1.14 2008/04/22 17:03:32 jhb Exp $
+ * $DragonFly: src/lib/libc/stdio/fopen.c,v 1.6 2005/11/20 11:07:30 swildner Exp $
  */
 
 #include "namespace.h"
@@ -51,7 +46,7 @@
 #include "priv_stdio.h"
 
 FILE *
-fopen(const char *file, const char *mode)
+fopen(const char * __restrict file, const char * __restrict mode)
 {
        FILE *fp;
        int f;
@@ -62,7 +57,7 @@ fopen(const char *file, const char *mode)
        if ((fp = __sfp()) == NULL)
                return (NULL);
        if ((f = _open(file, oflags, DEFFILEMODE)) < 0) {
-               fp->pub._flags = 0;                     /* release */
+               fp->pub._flags = 0;             /* release */
                return (NULL);
        }
        fp->pub._fileno = f;
@@ -72,7 +67,6 @@ fopen(const char *file, const char *mode)
        fp->_write = __swrite;
        fp->_seek = __sseek;
        fp->_close = __sclose;
-       /* fp->_lock = NULL; */
        /*
         * When opening in append mode, even though we use O_APPEND,
         * we need to seek to the end so that ftell() gets the right
@@ -82,6 +76,6 @@ fopen(const char *file, const char *mode)
         * fseek and ftell.)
         */
        if (oflags & O_APPEND)
-               __sseek((void *)fp, (fpos_t)0, SEEK_END);
+               _sseek(fp, (fpos_t)0, SEEK_END);
        return (fp);
 }
index 6dcc6d8..5084302 100644 (file)
  * 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.
@@ -34,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)fprintf.c       8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/fprintf.c,v 1.6 1999/08/28 00:01:02 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/fprintf.c,v 1.11 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/fprintf.c,v 1.4 2004/07/27 07:59:10 asmodai Exp $
  */
 
@@ -42,7 +38,7 @@
 #include <stdarg.h>
 
 int
-fprintf(FILE *fp, const char *fmt, ...)
+fprintf(FILE * __restrict fp, const char * __restrict fmt, ...)
 {
        int ret;
        va_list ap;
index 54e3333..2150149 100644 (file)
  * 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.
@@ -34,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)fpurge.c        8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/fpurge.c,v 1.7 1999/08/28 00:01:02 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/fpurge.c,v 1.11 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/fpurge.c,v 1.6 2005/07/23 20:23:06 joerg Exp $
  */
 
@@ -43,7 +39,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include "un-namespace.h"
-
 #include "local.h"
 #include "libc_private.h"
 #include "priv_stdio.h"
index 5837049..1f9859b 100644 (file)
  * 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.
  * SUCH DAMAGE.
  *
  * @(#)fputc.c 8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/fputc.c,v 1.7 1999/08/28 00:01:03 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/fputc.c,v 1.14 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/fputc.c,v 1.5 2005/01/31 22:29:40 dillon Exp $
  */
 
 #include "namespace.h"
 #include <stdio.h>
 #include "un-namespace.h"
+#include "local.h"
 #include "libc_private.h"
 
 int
@@ -48,7 +45,7 @@ fputc(int c, FILE *fp)
 {
        int retval;
        FLOCKFILE(fp);
-       retval = putc(c, fp);
+       retval = __sputc(c, fp);
        FUNLOCKFILE(fp);
        return (retval);
 }
index 56ff190..19d6acd 100644 (file)
 .\" 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.
@@ -34,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)fputs.3    8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdio/fputs.3,v 1.4.2.4 2001/12/14 18:33:57 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdio/fputs.3,v 1.14 2007/04/19 14:01:04 phk Exp $
 .\" $DragonFly: src/lib/libc/stdio/fputs.3,v 1.2 2003/06/17 04:26:46 dillon Exp $
 .\"
 .Dd June 4, 1993
@@ -69,16 +65,13 @@ writes the string
 .Fa str ,
 and a terminating newline character,
 to the stream
-.Em stdout .
+.Dv stdout .
 .Sh RETURN VALUES
-The
+The functions
 .Fn fputs
-function
-returns 0 on success and
-.Dv EOF
-on error;
+and
 .Fn puts
-returns a nonnegative integer on success and
+return a nonnegative integer on success and
 .Dv EOF
 on error.
 .Sh ERRORS
@@ -86,7 +79,7 @@ on error.
 .It Bq Er EBADF
 The
 .Fa stream
-supplied
+argument
 is not a writable stream.
 .El
 .Pp
@@ -100,6 +93,7 @@ for any of the errors specified for the routines
 .Xr write 2 .
 .Sh SEE ALSO
 .Xr ferror 3 ,
+.Xr fputws 3 ,
 .Xr putc 3 ,
 .Xr stdio 3
 .Sh STANDARDS
index b8f4100..e4d0523 100644 (file)
  * 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.
  * SUCH DAMAGE.
  *
  * @(#)fputs.c 8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/fputs.c,v 1.7 1999/08/28 00:01:03 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/fputs.c,v 1.12 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/fputs.c,v 1.5 2005/07/23 20:23:06 joerg Exp $
  */
 
 #include "namespace.h"
-#include <sys/types.h>
 #include <stdio.h>
 #include <string.h>
 #include "un-namespace.h"
-#include "priv_stdio.h"
-
 #include "libc_private.h"
+#include "local.h"
+#include "priv_stdio.h"
 
 /*
  * Write the given string to the given file.
  */
 int
-fputs(const char *s, FILE *fp)
+fputs(const char * __restrict s, FILE * __restrict fp)
 {
        int retval;
        struct __suio uio;
@@ -62,6 +57,7 @@ fputs(const char *s, FILE *fp)
        uio.uio_iov = &iov;
        uio.uio_iovcnt = 1;
        FLOCKFILE(fp);
+       ORIENT(fp, -1);
        retval = __sfvwrite(fp, &uio);
        FUNLOCKFILE(fp);
        return (retval);
index 1a8fd30..7e72970 100644 (file)
 .\" 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.
@@ -34,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)fread.3    8.2 (Berkeley) 3/8/94
-.\" $FreeBSD: src/lib/libc/stdio/fread.3,v 1.5.2.3 2001/12/14 18:33:57 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdio/fread.3,v 1.10 2007/01/09 00:28:06 imp Exp $
 .\" $DragonFly: src/lib/libc/stdio/fread.3,v 1.2 2003/06/17 04:26:46 dillon Exp $
 .\"
 .Dd March 8, 1994
@@ -49,9 +45,9 @@
 .Sh SYNOPSIS
 .In stdio.h
 .Ft size_t
-.Fn fread "void *ptr" "size_t size" "size_t nmemb" "FILE *stream"
+.Fn fread "void * restrict ptr" "size_t size" "size_t nmemb" "FILE * restrict stream"
 .Ft size_t
-.Fn fwrite "const void *ptr" "size_t size" "size_t nmemb" "FILE *stream"
+.Fn fwrite "const void * restrict ptr" "size_t size" "size_t nmemb" "FILE * restrict stream"
 .Sh DESCRIPTION
 The function
 .Fn fread
index 521eef6..db3e245 100644 (file)
  * 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.
@@ -34,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)fread.c 8.2 (Berkeley) 12/11/93
- * $FreeBSD: src/lib/libc/stdio/fread.c,v 1.7 1999/08/28 00:01:04 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/fread.c,v 1.15 2008/12/01 14:33:34 ru Exp $
  * $DragonFly: src/lib/libc/stdio/fread.c,v 1.8 2005/12/20 00:21:53 davidxu Exp $
  */
 
 #include <stdio.h>
 #include <string.h>
 #include "un-namespace.h"
-
 #include "local.h"
 #include "libc_private.h"
 #include "priv_stdio.h"
 
+/*
+ * MT-safe version
+ */
+
 size_t
-fread(void *buf, size_t size, size_t count, FILE *fp)
+fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp)
 {
        size_t ret;
 
@@ -59,7 +58,7 @@ fread(void *buf, size_t size, size_t count, FILE *fp)
 }
 
 size_t
-__fread(void *buf, size_t size, size_t count, FILE *fp)
+__fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp)
 {
        size_t resid;
        char *p;
@@ -73,6 +72,7 @@ __fread(void *buf, size_t size, size_t count, FILE *fp)
         */
        if ((resid = count * size) == 0)
                return (0);
+       ORIENT(fp, -1);
        if (fp->pub._r < 0)
                fp->pub._r = 0;
        total = resid;
@@ -80,7 +80,7 @@ __fread(void *buf, size_t size, size_t count, FILE *fp)
        while (resid > (r = fp->pub._r)) {
                memcpy((void *)p, (void *)fp->pub._p, (size_t)r);
                fp->pub._p += r;
-               /* fp->_r = 0 ... done in __srefill */
+               /* fp->pub._r = 0 ... done in __srefill */
                p += r;
                resid -= r;
                if (__srefill(fp)) {
index 3967116..4692597 100644 (file)
  * 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.
@@ -34,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)freopen.c       8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/freopen.c,v 1.5.2.1 2001/03/05 10:54:53 obrien Exp $
+ * $FreeBSD: src/lib/libc/stdio/freopen.c,v 1.21 2008/04/17 22:17:54 jhb Exp $
  * $DragonFly: src/lib/libc/stdio/freopen.c,v 1.7 2005/11/20 11:07:30 swildner Exp $
  */
 
@@ -47,7 +43,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include "un-namespace.h"
-
 #include "libc_private.h"
 #include "local.h"
 #include "priv_stdio.h"
  * all possible, no matter what.
  */
 FILE *
-freopen(const char *file, const char *mode, FILE *fp)
+freopen(const char * __restrict file, const char * __restrict mode, FILE *fp)
 {
        int f;
        int dflags, flags, isopen, oflags, sverrno, wantfd;
 
        if ((flags = __sflags(mode, &oflags)) == 0) {
+               sverrno = errno;
                fclose(fp);
+               errno = sverrno;
                return (NULL);
        }
 
@@ -73,8 +70,6 @@ freopen(const char *file, const char *mode, FILE *fp)
        if (!__sdidinit)
                __sinit();
 
-       sverrno = 0;
-
        /*
         * If the filename is a NULL pointer, the caller is asking us to
         * re-open the same file with a different mode. We allow this only
@@ -101,6 +96,8 @@ freopen(const char *file, const char *mode, FILE *fp)
                        errno = EINVAL;
                        return (NULL);
                }
+               if (fp->pub._flags & __SWR)
+                       __sflush(fp);
                if ((oflags ^ dflags) & O_APPEND) {
                        dflags &= ~O_APPEND;
                        dflags |= oflags & O_APPEND;
@@ -113,15 +110,9 @@ freopen(const char *file, const char *mode, FILE *fp)
                        }
                }
                if (oflags & O_TRUNC)
-                       ftruncate(fp->pub._fileno, 0);
-               if (_fseeko(fp, 0, oflags & O_APPEND ? SEEK_END : SEEK_SET) < 0 &&
-                   errno != ESPIPE) {
-                       sverrno = errno;
-                       fclose(fp);
-                       FUNLOCKFILE(fp);
-                       errno = sverrno;
-                       return (NULL);
-               }
+                       ftruncate(fp->pub._fileno, (off_t)0);
+               if (!(oflags & O_APPEND))
+                       _sseek(fp, (fpos_t)0, SEEK_SET);
                f = fp->pub._fileno;
                isopen = 0;
                wantfd = -1;
@@ -186,11 +177,12 @@ finish:
        if (HASLB(fp))
                FREELB(fp);
        fp->_lb._size = 0;
+       memset(WCIO_GET(fp), 0, sizeof(struct wchar_io_data));
 
        if (f < 0) {                    /* did not get it after all */
                fp->pub._flags = 0;             /* set it free */
-               errno = sverrno;        /* restore in case _close clobbered */
                FUNLOCKFILE(fp);
+               errno = sverrno;        /* restore in case _close clobbered */
                return (NULL);
        }
 
@@ -213,6 +205,16 @@ finish:
        fp->_write = __swrite;
        fp->_seek = __sseek;
        fp->_close = __sclose;
+       /*
+        * When opening in append mode, even though we use O_APPEND,
+        * we need to seek to the end so that ftell() gets the right
+        * answer.  If the user then alters the seek pointer, or
+        * the file extends, this will fail, but there is not much
+        * we can do about this.  (We could set __SAPP and check in
+        * fseek and ftell.)
+        */
+       if (oflags & O_APPEND)
+               _sseek(fp, (fpos_t)0, SEEK_END);
        FUNLOCKFILE(fp);
        return (fp);
 }
index 7cb4519..f432630 100644 (file)
  * 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.
@@ -34,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)fscanf.c        8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/fscanf.c,v 1.7 1999/08/28 00:01:04 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/fscanf.c,v 1.13 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/fscanf.c,v 1.4 2005/01/31 22:29:40 dillon Exp $
  */
 
 #include <stdarg.h>
 #include "un-namespace.h"
 #include "libc_private.h"
+#include "local.h"
 
 int
-fscanf(FILE *fp, char const *fmt, ...)
+fscanf(FILE * __restrict fp, const char * __restrict fmt, ...)
 {
        int ret;
        va_list ap;
index a73ca90..18c2465 100644 (file)
 .\" 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.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)fseek.3    8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdio/fseek.3,v 1.5.2.7 2001/12/14 18:33:57 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdio/fseek.3,v 1.27 2007/06/18 02:13:04 ache Exp $
 .\" $DragonFly: src/lib/libc/stdio/fseek.3,v 1.3 2007/07/30 22:11:33 swildner Exp $
 .\"
-.Dd March 5, 1999
+.Dd March 19, 2004
 .Dt FSEEK 3
 .Os
 .Sh NAME
@@ -60,7 +56,7 @@
 .Ft void
 .Fn rewind "FILE *stream"
 .Ft int
-.Fn fgetpos "FILE *stream" "fpos_t *pos"
+.Fn fgetpos "FILE * restrict stream" "fpos_t * restrict pos"
 .Ft int
 .Fn fsetpos "FILE *stream" "const fpos_t *pos"
 .In sys/types.h
@@ -93,7 +89,9 @@ A successful call to the
 function clears the end-of-file indicator for the stream and undoes
 any effects of the
 .Xr ungetc 3
-function on the same stream.
+and
+.Xr ungetwc 3
+functions on the same stream.
 .Pp
 The
 .Fn ftell
@@ -116,6 +114,17 @@ except that the error indicator for the stream is also cleared
 (see
 .Xr clearerr 3 ) .
 .Pp
+Since
+.Fn rewind
+does not return a value,
+an application wishing to detect errors should clear
+.Va errno ,
+then call
+.Fn rewind ,
+and if
+.Va errno
+is non-zero, assume an error has occurred.
+.Pp
 The
 .Fn fseeko
 function is identical to
@@ -137,21 +146,37 @@ The
 and
 .Fn fsetpos
 functions
-are alternate interfaces equivalent to
+are alternate interfaces for retrieving and setting the current position in
+the file, similar to
 .Fn ftell
 and
-.Fn fseek
-(with whence set to
-.Dv SEEK_SET ) ,
-setting and storing the current value of
-the file offset into or from the object referenced by
+.Fn fseek ,
+except that the current position is stored in an opaque object of
+type
+.Vt fpos_t
+pointed to by
 .Fa pos .
-On some
-.Pq non- Ns Ux
-systems an
-.Dq Fa fpos_t
-object may be a complex object
-and these routines may be the only way to portably reposition a text stream.
+These functions provide a portable way to seek to offsets larger than
+those that can be represented by a
+.Vt long int .
+They may also store additional state information in the
+.Vt fpos_t
+object to facilitate seeking within files containing multibyte
+characters with state-dependent encodings.
+Although
+.Vt fpos_t
+has traditionally been an integral type,
+applications cannot assume that it is;
+in particular, they must not perform arithmetic on objects
+of this type.
+.Pp
+If the stream is a wide character stream (see
+.Xr fwide 3 ) ,
+the position specified by the combination of
+.Fa offset
+and
+.Fa whence
+must contain the first byte of a multibyte sequence.
 .Sh RETURN VALUES
 The
 .Fn rewind
@@ -173,23 +198,33 @@ is set to indicate the error.
 .It Bq Er EBADF
 The
 .Fa stream
-specified
+argument
 is not a seekable stream.
 .It Bq Er EINVAL
 The
 .Fa whence
-argument to
-.Fn fseek
-was not
-.Dv SEEK_SET ,
-.Dv SEEK_END ,
-or
-.Dv SEEK_CUR .
+argument is invalid or
+the resulting file-position
+indicator would be set to a negative value.
 .It Bq Er EOVERFLOW
-For
-.Fn ftell ,
-the resulting file offset would be a value which
-cannot be represented correctly in an object of type long.
+The resulting file offset would be a value which
+cannot be represented correctly in an object of type
+.Fa off_t
+for
+.Fn fseeko
+and
+.Fn ftello
+or
+.Fa long
+for
+.Fn fseek
+and
+.Fn ftell .
+.It Bq Er ESPIPE
+The file descriptor underlying stream is associated with a pipe or FIFO
+or file-position indicator value is unspecified
+(see
+.Xr ungetc 3 ) .
 .El
 .Pp
 The functions
@@ -198,8 +233,9 @@ The functions
 .Fn fseeko ,
 .Fn fsetpos ,
 .Fn ftell ,
+.Fn ftello ,
 and
-.Fn ftello
+.Fn rewind
 may also fail and set
 .Va errno
 for any of the errors specified for the routines
@@ -209,7 +245,11 @@ for any of the errors specified for the routines
 and
 .Xr malloc 3 .
 .Sh SEE ALSO
-.Xr lseek 2
+.Xr lseek 2 ,
+.Xr clearerr 3 ,
+.Xr fwide 3 ,
+.Xr ungetc 3 ,
+.Xr ungetwc 3
 .Sh STANDARDS
 The
 .Fn fgetpos ,
@@ -227,4 +267,4 @@ The
 and
 .Fn ftello
 functions conform to
-.St -susv2 .
+.St -p1003.1-2001 .
index 0a428f9..8ba8afe 100644 (file)
  * 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.
  * SUCH DAMAGE.
  *
  * @(#)fseek.c 8.3 (Berkeley) 1/2/94
- * $FreeBSD: src/lib/libc/stdio/fseek.c,v 1.9.2.1 2001/03/05 10:56:58 obrien Exp $
+ * $FreeBSD: src/lib/libc/stdio/fseek.c,v 1.44 2008/04/17 22:17:54 jhb Exp $
  * $DragonFly: src/lib/libc/stdio/fseek.c,v 1.10 2005/11/20 11:07:30 swildner Exp $
  */
 
 #include "namespace.h"
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <errno.h>
 #include <fcntl.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <errno.h>
 #include "un-namespace.h"
-
 #include "local.h"
 #include "libc_private.h"
 #include "priv_stdio.h"
 int
 fseek(FILE *fp, long offset, int whence)
 {
-       return (fseeko(fp, offset, whence));
+       int ret;
+       int serrno = errno;
+
+       /* make sure stdio is set up */
+       if (!__sdidinit)
+               __sinit();
+
+       FLOCKFILE(fp);
+       ret = _fseeko(fp, (off_t)offset, whence, 1);
+       FUNLOCKFILE(fp);
+       if (ret == 0)
+               errno = serrno;
+       return (ret);
 }
 
 int
 fseeko(FILE *fp, off_t offset, int whence)
 {
        int ret;
+       int serrno = errno;
 
        /* make sure stdio is set up */
        if (!__sdidinit)
                __sinit();
 
        FLOCKFILE(fp);
-       ret = _fseeko(fp, offset, whence);
+       ret = _fseeko(fp, offset, whence, 0);
        FUNLOCKFILE(fp);
+       if (ret == 0)
+               errno = serrno;
        return (ret);
 }
 
@@ -79,10 +90,10 @@ fseeko(FILE *fp, off_t offset, int whence)
  * `Whence' must be one of the three SEEK_* macros.
  */
 int
-_fseeko(FILE *fp, off_t offset, int whence)
+_fseeko(FILE *fp, off_t offset, int whence, int ltest)
 {
-       fpos_t (*seekfn) (void *, fpos_t, int);
-       fpos_t target, curoff;
+       fpos_t (*seekfn)(void *, fpos_t, int);
+       fpos_t target, curoff, ret;
        size_t n;
        struct stat st;
        int havepos;
@@ -92,7 +103,7 @@ _fseeko(FILE *fp, off_t offset, int whence)
         */
        if ((seekfn = fp->_seek) == NULL) {
                errno = ESPIPE;         /* historic practice */
-               return (EOF);
+               return (-1);
        }
 
        /*
@@ -104,30 +115,38 @@ _fseeko(FILE *fp, off_t offset, int whence)
        case SEEK_CUR:
                /*
                 * In order to seek relative to the current stream offset,
-                * we have to first find the current stream offset a la
+                * we have to first find the current stream offset via
                 * ftell (see ftell for details).
                 */
-               if (fp->pub._flags & __SOFF)
-                       curoff = fp->_offset;
-               else {
-                       curoff = (*seekfn)(fp->_cookie, (fpos_t)0, SEEK_CUR);
-                       if (curoff == -1) {
-                               return (EOF);
-                       }
+               if (_ftello(fp, &curoff))
+                       return (-1);
+               if (curoff < 0) {
+                       /* Unspecified position because of ungetc() at 0 */
+                       errno = ESPIPE;
+                       return (-1);
+               }
+               if (offset > 0 && curoff > OFF_MAX - offset) {
+                       errno = EOVERFLOW;
+                       return (-1);
                }
-               if (fp->pub._flags & __SRD) {
-                       curoff -= fp->pub._r;
-                       if (HASUB(fp))
-                               curoff -= fp->_ur;
-               } else if (fp->pub._flags & __SWR && fp->pub._p != NULL)
-                       curoff += fp->pub._p - fp->_bf._base;
-
                offset += curoff;
+               if (offset < 0) {
+                       errno = EINVAL;
+                       return (-1);
+               }
+               if (ltest && offset > LONG_MAX) {
+                       errno = EOVERFLOW;
+                       return (-1);
+               }
                whence = SEEK_SET;
                havepos = 1;
                break;
 
        case SEEK_SET:
+               if (offset < 0) {
+                       errno = EINVAL;
+                       return (-1);
+               }
        case SEEK_END:
                curoff = 0;             /* XXX just to keep gcc quiet */
                havepos = 0;
@@ -135,7 +154,7 @@ _fseeko(FILE *fp, off_t offset, int whence)
 
        default:
                errno = EINVAL;
-               return (EOF);
+               return (-1);
        }
 
        /*
@@ -170,22 +189,31 @@ _fseeko(FILE *fp, off_t offset, int whence)
        else {
                if (_fstat(fp->pub._fileno, &st))
                        goto dumb;
+               if (offset > 0 && st.st_size > OFF_MAX - offset) {
+                       errno = EOVERFLOW;
+                       return (-1);
+               }
                target = st.st_size + offset;
-       }
-
-       if (!havepos) {
-               if (fp->pub._flags & __SOFF)
-                       curoff = fp->_offset;
-               else {
-                       curoff = (*seekfn)(fp->_cookie, (fpos_t)0, SEEK_CUR);
-                       if (curoff == POS_ERR)
-                               goto dumb;
+               if ((off_t)target < 0) {
+                       errno = EINVAL;
+                       return (-1);
+               }
+               if (ltest && (off_t)target > LONG_MAX) {
+                       errno = EOVERFLOW;
+                       return (-1);
                }
-               curoff -= fp->pub._r;
-               if (HASUB(fp))
-                       curoff -= fp->_ur;
        }
 
+       if (!havepos && _ftello(fp, &curoff))
+               goto dumb;
+
+       /*
+        * (If the buffer was modified, we have to
+        * skip this; see fgetln.c.)
+        */
+       if (fp->pub._flags & __SMOD)
+               goto abspos;
+
        /*
         * Compute the number of bytes in the input buffer (pretending
         * that any ungetc() input has been discarded).  Adjust current
@@ -206,21 +234,21 @@ _fseeko(FILE *fp, off_t offset, int whence)
        /*
         * If the target offset is within the current buffer,
         * simply adjust the pointers, clear EOF, undo ungetc(),
-        * and return.  (If the buffer was modified, we have to
-        * skip this; see fgetln.c.)
+        * and return.
         */
-       if ((fp->pub._flags & __SMOD) == 0 &&
-           target >= curoff && target < curoff + n) {
-               int o = target - curoff;
+       if (target >= curoff && target < curoff + n) {
+               size_t o = target - curoff;
 
                fp->pub._p = fp->_bf._base + o;
                fp->pub._r = n - o;
                if (HASUB(fp))
                        FREEUB(fp);
                fp->pub._flags &= ~__SEOF;
+               memset(WCIO_GET(fp), 0, sizeof(struct wchar_io_data));
                return (0);
        }
 
+abspos:
        /*
         * The place we want to get to is not within the current buffer,
         * but we can still be kind to the kernel copyout mechanism.
@@ -230,13 +258,12 @@ _fseeko(FILE *fp, off_t offset, int whence)
         * ensures that we only read one block, rather than two.
         */
        curoff = target & ~(fp->_blksize - 1);
-       if ((*seekfn)(fp->_cookie, curoff, SEEK_SET) == POS_ERR)
+       if (_sseek(fp, curoff, SEEK_SET) == POS_ERR)
                goto dumb;
        fp->pub._r = 0;
        fp->pub._p = fp->_bf._base;
        if (HASUB(fp))
                FREEUB(fp);
-       fp->pub._flags &= ~__SEOF;
        n = target - curoff;
        if (n) {
                if (__srefill(fp) || fp->pub._r < n)
@@ -244,6 +271,8 @@ _fseeko(FILE *fp, off_t offset, int whence)
                fp->pub._p += n;
                fp->pub._r -= n;
        }
+       fp->pub._flags &= ~__SEOF;
+       memset(WCIO_GET(fp), 0, sizeof(struct wchar_io_data));
        return (0);
 
        /*
@@ -252,8 +281,12 @@ _fseeko(FILE *fp, off_t offset, int whence)
         */
 dumb:
        if (__sflush(fp) ||
-           (*seekfn)(fp->_cookie, (fpos_t)offset, whence) == POS_ERR) {
-               return (EOF);
+           (ret = _sseek(fp, (fpos_t)offset, whence)) == POS_ERR)
+               return (-1);
+       if (ltest && ret > LONG_MAX) {
+               fp->pub._flags |= __SERR;
+               errno = EOVERFLOW;
+               return (-1);
        }
        /* success: clear EOF indicator and discard ungetc() data */
        if (HASUB(fp))
@@ -262,5 +295,6 @@ dumb:
        fp->pub._r = 0;
        /* fp->pub._w = 0; */   /* unnecessary (I think...) */
        fp->pub._flags &= ~__SEOF;
+       memset(WCIO_GET(fp), 0, sizeof(struct wchar_io_data));
        return (0);
 }
index a74be9e..3266388 100644 (file)
  * 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.
@@ -34,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)fsetpos.c       8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/fsetpos.c,v 1.7 1999/08/28 00:01:05 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/fsetpos.c,v 1.9 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/fsetpos.c,v 1.3 2004/06/07 20:35:41 hmp Exp $
  */
 
index 9837c59..2e53cae 100644 (file)
  * 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.
  * SUCH DAMAGE.
  *
  * @(#)ftell.c 8.2 (Berkeley) 5/4/95
- * $FreeBSD: src/lib/libc/stdio/ftell.c,v 1.11 1999/08/28 00:01:06 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/ftell.c,v 1.27 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/ftell.c,v 1.6 2005/07/23 20:23:06 joerg Exp $
  */
 
 #include "namespace.h"
 #include <sys/types.h>
-#include <stdio.h>
 #include <errno.h>
+#include <limits.h>
+#include <stdio.h>
 #include "un-namespace.h"
-
 #include "local.h"
 #include "libc_private.h"
 #include "priv_stdio.h"
@@ -55,8 +51,9 @@ long
 ftell(FILE *fp)
 {
        off_t rv;
+
        rv = ftello(fp);
-       if ((long)rv != rv) {
+       if (rv > LONG_MAX) {
                errno = EOVERFLOW;
                return (-1);
        }
@@ -68,15 +65,33 @@ ftell(FILE *fp)
  */
 off_t
 ftello(FILE *fp)
+{
+       fpos_t rv;
+       int ret;
+
+       FLOCKFILE(fp);
+       ret = _ftello(fp, &rv);
+       FUNLOCKFILE(fp);
+       if (ret)
+               return (-1);
+       if (rv < 0) {   /* Unspecified value because of ungetc() at 0 */
+               errno = ESPIPE;
+               return (-1);
+       }
+       return (rv);
+}
+
+int
+_ftello(FILE *fp, fpos_t *offset)
 {
        fpos_t pos;
+       size_t n;
 
        if (fp->_seek == NULL) {
                errno = ESPIPE;                 /* historic practice */
-               return (-1L);
+               return (1);
        }
 
-       FLOCKFILE(fp);
        /*
         * Find offset of underlying I/O object, then
         * adjust for buffered bytes.
@@ -84,11 +99,9 @@ ftello(FILE *fp)
        if (fp->pub._flags & __SOFF)
                pos = fp->_offset;
        else {
-               pos = (*fp->_seek)(fp->_cookie, (fpos_t)0, SEEK_CUR);
-               if (pos == -1) {
-                       FUNLOCKFILE(fp);
-                       return (pos);
-               }
+               pos = _sseek(fp, (fpos_t)0, SEEK_CUR);
+               if (pos == -1)
+                       return (1);
        }
        if (fp->pub._flags & __SRD) {
                /*
@@ -96,17 +109,26 @@ ftello(FILE *fp)
                 * those from ungetc) cause the position to be
                 * smaller than that in the underlying object.
                 */
-               pos -= fp->pub._r;
+               if ((pos -= (HASUB(fp) ? fp->_ur : fp->pub._r)) < 0) {
+                       fp->pub._flags |= __SERR;
+                       errno = EIO;
+                       return (1);
+               }
                if (HASUB(fp))
-                       pos -= fp->_ur;
-       } else if (fp->pub._flags & __SWR && fp->pub._p != NULL) {
+                       pos -= fp->pub._r;  /* Can be negative at this point. */
+       } else if ((fp->pub._flags & __SWR) && fp->pub._p != NULL) {
                /*
                 * Writing.  Any buffered characters cause the
                 * position to be greater than that in the
                 * underlying object.
                 */
-               pos += fp->pub._p - fp->_bf._base;
+               n = fp->pub._p - fp->_bf._base;
+               if (pos > OFF_MAX - n) {
+                       errno = EOVERFLOW;
+                       return (1);
+               }
+               pos += n;
        }
-       FUNLOCKFILE(fp);
-       return (pos);
+       *offset = pos;
+       return (0);
 }
index 7bcc2dd..6696319 100644 (file)
 .\" 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.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)funopen.3  8.1 (Berkeley) 6/9/93
-.\" $FreeBSD: src/lib/libc/stdio/funopen.3,v 1.7.2.4 2001/12/14 18:33:57 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdio/funopen.3,v 1.16 2007/01/09 00:28:06 imp Exp $
 .\" $DragonFly: src/lib/libc/stdio/funopen.3,v 1.3 2006/05/26 19:39:37 swildner Exp $
 .\"
-.Dd June 9, 1993
+.Dd March 19, 2004
 .Dt FUNOPEN 3
 .Os
 .Sh NAME
@@ -50,9 +46,9 @@
 .Ft FILE *
 .Fn funopen "const void *cookie" "int (*readfn)(void *, char *, int)" "int (*writefn)(void *, const char *, int)" "fpos_t (*seekfn)(void *, fpos_t, int)" "int (*closefn)(void *)"
 .Ft FILE *
-.Fn fropen "void  *cookie" "int  (*readfn)(void *, char *, int)"
+.Fn fropen "void *cookie" "int (*readfn)(void *, char *, int)"
 .Ft FILE *
-.Fn fwopen "void  *cookie" "int  (*writefn)(void *, const char *, int)"
+.Fn fwopen "void *cookie" "int (*writefn)(void *, const char *, int)"
 .Sh DESCRIPTION
 The
 .Fn funopen
@@ -171,3 +167,11 @@ The
 function
 may not be portable to systems other than
 .Bx .
+.Pp
+The
+.Fn funopen
+interface erroneously assumes that
+.Vt fpos_t
+is an integral type; see
+.Xr fseek 3
+for a discussion of this issue.
index 2d55b86..3a9c073 100644 (file)
  * 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.
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libc/stdio/funopen.c,v 1.1.1.1.14.1 2001/03/05 10:57:52 obrien Exp $
- * $DragonFly: src/lib/libc/stdio/funopen.c,v 1.5 2005/07/23 20:23:06 joerg Exp $
- *
  * @(#)funopen.c       8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdio/funopen.c,v 1.6 2007/01/09 00:28:06 imp Exp $
+ * $DragonFly: src/lib/libc/stdio/funopen.c,v 1.5 2005/07/23 20:23:06 joerg Exp $
  */
 
 #include <stdio.h>
@@ -48,8 +43,7 @@
 FILE *
 funopen(const void *cookie, int (*readfn)(void *, char *, int),
        int (*writefn)(void *, const char *, int),
-       fpos_t (*seekfn)(void *cookie, fpos_t off, int whence),
-       int (*closefn)(void *))
+       fpos_t (*seekfn)(void *, fpos_t, int), int (*closefn)(void *))
 {
        FILE *fp;
        int flags;
index f2cb447..b709f8d 100644 (file)
  * 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.
  * SUCH DAMAGE.
  *
  * @(#)fvwrite.c       8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/fvwrite.c,v 1.10 1999/08/28 00:01:06 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/fvwrite.c,v 1.18 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/fvwrite.c,v 1.7 2005/07/23 20:23:06 joerg Exp $
  */
 
-#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -64,24 +59,22 @@ __sfvwrite(FILE *fp, struct __suio *uio)
        if ((len = uio->uio_resid) == 0)
                return (0);
        /* make sure we can write */
-       if (cantwrite(fp)) {
-               errno = EBADF;
+       if (prepwrite(fp) != 0)
                return (EOF);
-       }
 
-#define        MIN(a, b) ((a) < (b) ? (a) : (b))
-#define        COPY(n)   (void)memcpy((void *)fp->pub._p, (void *)p, (size_t)(n))
+#define        MIN(a, b)       ((a) < (b) ? (a) : (b))
+#define        COPY(n)         memcpy((void *)fp->pub._p, (void *)p, (size_t)(n))
 
        iov = uio->uio_iov;
        p = iov->iov_base;
        len = iov->iov_len;
        iov++;
-#define GETIOV(extra_work) \
-       while (len == 0) { \
-               extra_work; \
-               p = iov->iov_base; \
-               len = iov->iov_len; \
-               iov++; \
+#define        GETIOV(extra_work)              \
+       while (len == 0) {              \
+               extra_work;             \
+               p = iov->iov_base;      \
+               len = iov->iov_len;     \
+               iov++;                  \
        }
        if (fp->pub._flags & __SNBF) {
                /*
@@ -89,7 +82,7 @@ __sfvwrite(FILE *fp, struct __suio *uio)
                 */
                do {
                        GETIOV(;);
-                       w = (*fp->_write)(fp->_cookie, p, MIN(len, BUFSIZ));
+                       w = _swrite(fp, p, MIN(len, BUFSIZ));
                        if (w <= 0)
                                goto err;
                        p += w;
@@ -130,7 +123,7 @@ __sfvwrite(FILE *fp, struct __suio *uio)
                                if (len < w)
                                        w = len;
                                if (w > 0) {
-                                       COPY(w);        /* copy MIN(fp->_w,len), */
+                                       COPY(w);        /* copy MIN(fp->pub._w, len), */
                                        fp->pub._w -= w;
                                        fp->pub._p += w;
                                }
@@ -138,13 +131,13 @@ __sfvwrite(FILE *fp, struct __suio *uio)
                        } else if (fp->pub._p > fp->_bf._base && len > w) {
                                /* fill and flush */
                                COPY(w);
-                               /* fp->_w -= w; */ /* unneeded */
+                               /* fp->pub._w -= w; */ /* unneeded */
                                fp->pub._p += w;
                                if (__fflush(fp))
                                        goto err;
                        } else if (len >= (w = fp->_bf._size)) {
                                /* write directly */
-                               w = (*fp->_write)(fp->_cookie, p, w);
+                               w = _swrite(fp, p, w);
                                if (w <= 0)
                                        goto err;
                        } else {
@@ -178,12 +171,12 @@ __sfvwrite(FILE *fp, struct __suio *uio)
                        w = fp->pub._w + fp->_bf._size;
                        if (fp->pub._p > fp->_bf._base && s > w) {
                                COPY(w);
-                               /* fp->_w -= w; */
+                               /* fp->pub._w -= w; */
                                fp->pub._p += w;
                                if (__fflush(fp))
                                        goto err;
                        } else if (s >= (w = fp->_bf._size)) {
-                               w = (*fp->_write)(fp->_cookie, p, w);
+                               w = _swrite(fp, p, w);
                                if (w <= 0)
                                        goto err;
                        } else {
index b54d521..2e9f07d 100644 (file)
  * 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.
  * SUCH DAMAGE.
  *
  * @(#)fwalk.c 8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/fwalk.c,v 1.6.2.1 2001/03/05 11:27:49 obrien Exp $
+ * $FreeBSD: src/lib/libc/stdio/fwalk.c,v 1.10 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/fwalk.c,v 1.5 2005/07/23 20:23:06 joerg Exp $
  */
 
-#include <stdio.h>
 #include <sys/types.h>
 #include <machine/atomic.h>
+#include <stdio.h>
 #include "local.h"
 #include "priv_stdio.h"
 
@@ -53,13 +49,17 @@ _fwalk(int (*function)(FILE *))
 
        ret = 0;
        /*
-        * It should be safe to walk  the list without locking it;
+        * It should be safe to walk the list without locking it;
         * new nodes are only added to the end and none are ever
         * removed.
+        *
+        * Avoid locking this list while walking it or else you will
+        * introduce a potential deadlock in [at least] refill.c.
         */
        for (g = &__sglue; g != NULL; g = g->next)
                for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
-                       if (fp->pub._flags != 0)
+                       if ((fp->pub._flags != 0) &&
+                           ((fp->pub._flags & __SIGN) == 0))
                                ret |= (*function)(fp);
        return (ret);
 }
index 27b43b6..479f9b3 100644 (file)
@@ -1,6 +1,3 @@
-/*     $NetBSD: fwprintf.c,v 1.1 2005/05/14 23:51:02 christos Exp $    */
-/*     $DragonFly: src/lib/libc/stdio/fwprintf.c,v 1.1 2005/07/25 00:37:41 joerg Exp $ */
-
 /*-
  * Copyright (c) 2002 Tim J. Robbins
  * All rights reserved.
@@ -25,6 +22,9 @@
  * 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: src/lib/libc/stdio/fwprintf.c,v 1.1 2002/09/21 13:00:30 tjr Exp $
+ * $DragonFly: src/lib/libc/stdio/fwprintf.c,v 1.1 2005/07/25 00:37:41 joerg Exp $
  */
 
 #include <stdarg.h>
index 61e720e..65825b3 100644 (file)
  * 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.
  * SUCH DAMAGE.
  *
  * @(#)fwrite.c        8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/fwrite.c,v 1.7 1999/08/28 00:01:07 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/fwrite.c,v 1.12 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/fwrite.c,v 1.5 2005/07/23 20:23:06 joerg Exp $
  */
 
 #include "namespace.h"
-#include <sys/types.h>
 #include <stdio.h>
 #include "un-namespace.h"
 #include "local.h"
@@ -51,7 +46,8 @@
  * Return the number of whole objects written.
  */
 size_t
-fwrite(const void *buf, size_t size, size_t count, FILE *fp)
+fwrite(const void * __restrict buf, size_t size, size_t count,
+       FILE * __restrict fp)
 {
        size_t n;
        struct __suio uio;
@@ -63,6 +59,7 @@ fwrite(const void *buf, size_t size, size_t count, FILE *fp)
        uio.uio_iovcnt = 1;
 
        FLOCKFILE(fp);
+       ORIENT(fp, -1);
        /*
         * The usual case is success (__sfvwrite returns 0);
         * skip the divide if this happens, since divides are
index 71f4244..fd4ecdf 100644 (file)
@@ -1,6 +1,3 @@
-/*     $NetBSD: fwscanf.c,v 1.1 2005/05/14 23:51:02 christos Exp $     */
-/*     $DragonFly: src/lib/libc/stdio/fwscanf.c,v 1.1 2005/07/25 00:37:41 joerg Exp $ */
-
 /*-
  * Copyright (c) 2002 Tim J. Robbins
  * All rights reserved.
  * 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: src/lib/libc/stdio/fwscanf.c,v 1.1 2002/09/23 12:40:06 tjr Exp $
+ * $DragonFly: src/lib/libc/stdio/fwscanf.c,v 1.1 2005/07/25 00:37:41 joerg Exp $
  */
 
 #include <stdarg.h>
 #include <stdio.h>
 #include <wchar.h>
 
-#include "local.h"
-
 int
 fwscanf(FILE * __restrict fp, const wchar_t * __restrict fmt, ...)
 {
index 78fd31c..a26c8ad 100644 (file)
 .\" 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.
@@ -34,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)getc.3     8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdio/getc.3,v 1.5.2.6 2002/05/19 00:24:57 fanf Exp $
+.\" $FreeBSD: src/lib/libc/stdio/getc.3,v 1.21 2007/01/09 00:28:06 imp Exp $
 .\" $DragonFly: src/lib/libc/stdio/getc.3,v 1.3 2005/09/25 20:49:55 asmodai Exp $
 .\"
 .Dd March 22, 2009
@@ -59,7 +55,7 @@
 .Ft int
 .Fn getc_unlocked "FILE *stream"
 .Ft int
-.Fn getchar "void"
+.Fn getchar void
 .Ft int
 .Fn getchar_unlocked "void"
 .Ft int
@@ -77,7 +73,8 @@ The
 .Fn getc
 function
 acts essentially identically to
-.Fn fgetc .
+.Fn fgetc ,
+but is a macro that expands in-line.
 .Pp
 The
 .Fn getchar
@@ -89,7 +86,7 @@ The
 .Fn getw
 function
 obtains the next
-.Em int
+.Vt int
 (if present)
 from the stream pointed at by
 .Fa stream .
@@ -105,7 +102,7 @@ and
 respectively,
 except that the caller is responsible for locking the stream
 with
-.Fn flockfile
+.Xr flockfile 3
 before calling them.
 These functions may be used to avoid the overhead of locking the stream
 for each character, and to avoid input being dispersed among multiple
@@ -115,9 +112,9 @@ If successful, these routines return the next requested object
 from the
 .Fa stream .
 Character values are returned as an
-.Li unsigned char
+.Vt "unsigned char"
 converted to an
-.Li int .
+.Vt int .
 If the stream is at end-of-file or a read error occurs,
 the routines return
 .Dv EOF .
@@ -139,6 +136,7 @@ until the condition is cleared with
 .Xr flockfile 3 ,
 .Xr fopen 3 ,
 .Xr fread 3 ,
+.Xr getwc 3 ,
 .Xr putc 3 ,
 .Xr ungetc 3
 .Sh STANDARDS
@@ -166,7 +164,7 @@ and
 must be used to check for failure after calling
 .Fn getw .
 The size and byte order of an
-.Em int
+.Vt int
 varies from one machine to another, and
 .Fn getw
 is not recommended for portable applications.
index e2853b3..f559b0c 100644 (file)
  * 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.
@@ -34,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)getc.c  8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/getc.c,v 1.7.2.1 2001/03/05 11:27:49 obrien Exp $
+ * $FreeBSD: src/lib/libc/stdio/getc.c,v 1.16 2008/05/05 16:03:52 jhb Exp $
  * $DragonFly: src/lib/libc/stdio/getc.c,v 1.4 2005/08/27 21:35:01 joerg Exp $
  */
 
@@ -42,7 +38,9 @@
 #include <stdio.h>
 #include "un-namespace.h"
 #include "libc_private.h"
+#include "local.h"
 
+#undef getc
 #undef getc_unlocked
 
 int
@@ -58,5 +56,5 @@ getc(FILE *fp)
 int
 getc_unlocked(FILE *fp)
 {
-       return(__sgetc(fp));
+       return (__sgetc(fp));
 }
index 3d03ff5..0c275d2 100644 (file)
  * 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.
  * SUCH DAMAGE.
  *
  * @(#)getchar.c       8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/getchar.c,v 1.7 1999/08/28 00:01:09 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/getchar.c,v 1.15 2008/05/05 16:03:52 jhb Exp $
  * $DragonFly: src/lib/libc/stdio/getchar.c,v 1.5 2005/08/27 21:35:01 joerg Exp $
  */
 
 /*
- * A subroutine version of the macros getchar and getchar_unlocked.
+ * A subroutine version of the macro getchar.
  */
 #include "namespace.h"
 #include <stdio.h>
 #include "un-namespace.h"
+#include "local.h"
 #include "libc_private.h"
 
+#undef getchar
 #undef getchar_unlocked
 
 int
 getchar(void)
 {
-       return(getc(stdin));
+       int retval;
+       FLOCKFILE(stdin);
+       retval = __sgetc(stdin);
+       FUNLOCKFILE(stdin);
+       return (retval);
 }
 
 int
 getchar_unlocked(void)
 {
-       return(getc_unlocked(stdin));
+       return (__sgetc(stdin));
 }
diff --git a/lib/libc/stdio/getdelim.c b/lib/libc/stdio/getdelim.c
new file mode 100644 (file)
index 0000000..bb88633
--- /dev/null
@@ -0,0 +1,160 @@
+/*-
+ * Copyright (c) 2009 David Schultz <das@FreeBSD.org>
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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: src/lib/libc/stdio/getdelim.c,v 1.2 2009/04/06 13:50:04 das Exp $
+ */
+
+#include "namespace.h"
+#include <sys/param.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "un-namespace.h"
+
+#include "libc_private.h"
+#include "local.h"
+#include "priv_stdio.h"
+
+static inline size_t
+p2roundup(size_t n)
+{
+
+       if (!powerof2(n)) {
+               n--;
+               n |= n >> 1;
+               n |= n >> 2;
+               n |= n >> 4;
+               n |= n >> 8;
+               n |= n >> 16;
+#if SIZE_T_MAX > 0xffffffffU
+               n |= n >> 32;
+#endif
+               n++;
+       }
+       return (n);
+}
+
+/*
+ * Expand *linep to hold len bytes (up to SSIZE_MAX + 1).
+ */
+static inline int
+expandtofit(char ** __restrict linep, size_t len, size_t * __restrict capp)
+{
+       char *newline;
+       size_t newcap;
+
+       if (len > (size_t)SSIZE_MAX + 1) {
+               errno = EOVERFLOW;
+               return (-1);
+       }
+       if (len > *capp) {
+               if (len == (size_t)SSIZE_MAX + 1)       /* avoid overflow */
+                       newcap = (size_t)SSIZE_MAX + 1;
+               else
+                       newcap = p2roundup(len);
+               newline = realloc(*linep, newcap);
+               if (newline == NULL)
+                       return (-1);
+               *capp = newcap;
+               *linep = newline;
+       }
+       return (0);
+}
+
+/*
+ * Append the src buffer to the *dstp buffer. The buffers are of
+ * length srclen and *dstlenp, respectively, and dst has space for
+ * *dstlenp bytes. After the call, *dstlenp and *dstcapp are updated
+ * appropriately, and *dstp is reallocated if needed. Returns 0 on
+ * success, -1 on allocation failure.
+ */
+static int
+sappend(char ** __restrict dstp, size_t * __restrict dstlenp,
+       size_t * __restrict dstcapp, char * __restrict src, size_t srclen)
+{
+
+       /* ensure room for srclen + dstlen + terminating NUL */
+       if (expandtofit(dstp, srclen + *dstlenp + 1, dstcapp))
+               return (-1);
+       memcpy(*dstp + *dstlenp, src, srclen);
+       *dstlenp += srclen;
+       return (0);
+}
+
+ssize_t
+getdelim(char ** __restrict linep, size_t * __restrict linecapp, int delim,
+        FILE * __restrict fp)
+{
+       u_char *endp;
+       size_t linelen;
+
+       FLOCKFILE(fp);
+       ORIENT(fp, -1);
+
+       if (linep == NULL || linecapp == NULL) {
+               errno = EINVAL;
+               goto error;
+       }
+
+       if (*linecapp == 0)
+               *linep = NULL;
+
+       if (fp->pub._r <= 0 && __srefill(fp)) {
+               /* If fp is at EOF already, we just need space for the NUL. */
+               if (__sferror(fp) || expandtofit(linep, 1, linecapp))
+                       goto error;
+               FUNLOCKFILE(fp);
+               (*linep)[0] = '\0';
+               return (-1);
+       }
+
+       linelen = 0;
+       while ((endp = memchr(fp->pub._p, delim, fp->pub._r)) == NULL) {
+               if (sappend(linep, &linelen, linecapp, fp->pub._p, fp->pub._r))
+                       goto error;
+               if (__srefill(fp)) {
+                       if (__sferror(fp))
+                               goto error;
+                       goto done;      /* hit EOF */
+               }
+       }
+       endp++; /* snarf the delimiter, too */
+       if (sappend(linep, &linelen, linecapp, fp->pub._p, endp - fp->pub._p))
+               goto error;
+       fp->pub._r -= endp - fp->pub._p;
+       fp->pub._p = endp;
+done:
+       /* Invariant: *linep has space for at least linelen+1 bytes. */
+       (*linep)[linelen] = '\0';
+       FUNLOCKFILE(fp);
+       return (linelen);
+
+error:
+       fp->pub._flags |= __SERR;
+       FUNLOCKFILE(fp);
+       return (-1);
+}
diff --git a/lib/libc/stdio/getline.3 b/lib/libc/stdio/getline.3
new file mode 100644 (file)
index 0000000..40c5701
--- /dev/null
@@ -0,0 +1,164 @@
+.\" Copyright (c) 2009 David Schultz <das@FreeBSD.org>
+.\" All rights reserved.
+.\"
+.\" 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.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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: src/lib/libc/stdio/getline.3,v 1.2 2009/04/06 13:50:04 das Exp $
+.\"
+.Dd March 29, 2009
+.Dt GETLINE 3
+.Os
+.Sh NAME
+.Nm getdelim ,
+.Nm getline
+.Nd get a line from a stream
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.Fd "#define _WITH_GETLINE"
+.In stdio.h
+.Ft ssize_t
+.Fn getdelim "char ** restrict linep" "size_t * restrict linecapp" "int delimiter" " FILE * restrict stream"
+.Ft ssize_t
+.Fn getline "char ** restrict linep" "size_t * restrict linecapp" " FILE * restrict stream"
+.Sh DESCRIPTION
+The
+.Fn getdelim
+function reads a line from
+.Fa stream ,
+delimited by the character
+.Fa delimiter .
+The
+.Fn getline
+function is equivalent to
+.Fn getdelim
+with the newline character as the delimiter.
+The delimiter character is included as part of the line, unless
+the end of the file is reached.
+The caller may provide a pointer to a malloc buffer for the line in
+.Fa *linep ,
+and the capacity of that buffer in
+.Fa *linecapp ;
+if
+.Fa *linecapp
+is 0, then
+.Fa *linep
+is treated as
+.Dv NULL .
+These functions may expand the buffer as needed, as if via
+.Fn realloc ,
+and update
+.Fa *linep
+and
+.Fa *linecapp
+accordingly.
+.Sh RETURN VALUES
+The
+.Fn getdelim
+and
+.Fn getline
+functions return the number of characters written, excluding the
+terminating
+.Dv NUL .
+The value \-1 is returned if an error occurs, or if end-of-file is reached.
+.Sh EXAMPLES
+The following code fragment reads lines from a file and
+writes them to standard output.
+The
+.Fn fwrite
+function is used in case the line contains embedded
+.Dv NUL
+characters.
+.Bd -literal -offset indent
+char *line = NULL;
+size_t linecap = 0;
+ssize_t linelen;
+while ((linelen = getline(&line, &linecap, fp)) > 0)
+       fwrite(line, linelen, 1, stdout);
+.Ed
+.Sh COMPATIBILITY
+Many application writers used the name
+.Va getline
+before the
+.Fn getline
+function was introduced in
+.St -p1003.1 ,
+so a prototype is not provided by default in order to avoid
+compatibility problems.
+Applications that wish to use the
+.Fn getline
+function described herein should either request a strict
+.St -p1003.1-2008
+environment by defining the macro
+.Dv _POSIX_C_SOURCE
+to the value 200809 or greater, or by defining the macro
+.Dv _WITH_GETLINE ,
+prior to the inclusion of
+.In stdio.h .
+For compatibility with GNU libc, defining either
+.Dv _BSD_SOURCE
+or
+.Dv _GNU_SOURCE
+prior to the inclusion of
+.In stdio.h
+will also make
+.Fn getline
+available.
+.Sh ERRORS
+These functions may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+Either
+.Fa linep
+or
+.Fa linecapp
+is
+.Dv NULL .
+.It Bq Er EOVERFLOW
+No delimiter was found in the first
+.Dv SSIZE_MAX
+characters.
+.El
+.Pp
+These functions may also fail for any of the errors specified for
+.Fn fgets
+and
+.Fn malloc .
+.Sh SEE ALSO
+.Xr fgetln 3 ,
+.Xr fgets 3 ,
+.Xr malloc 3
+.Sh STANDARDS
+The
+.Fn getdelim
+and
+.Fn getline
+functions conform to
+.St -p1003.1-2008 .
+.Sh HISTORY
+These routines first appeared in
+.Dx 2.3 .
+.Sh BUGS
+There are no wide character versions of
+.Fn getdelim
+or
+.Fn getline .
similarity index 80%
copy from lib/libc/stdio/vwscanf.c
copy to lib/libc/stdio/getline.c
index e1d2529..82ec92d 100644 (file)
@@ -1,8 +1,5 @@
-/*     $NetBSD: vwscanf.c,v 1.1 2005/05/14 23:51:02 christos Exp $     */
-/*     $DragonFly: src/lib/libc/stdio/vwscanf.c,v 1.1 2005/07/25 00:37:41 joerg Exp $ */
-
 /*-
- * Copyright (c) 2002 Tim J. Robbins
+ * Copyright (c) 2009 David Schultz <das@FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * 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: src/lib/libc/stdio/getline.c,v 1.1 2009/02/28 06:00:58 das Exp $
  */
 
-#include <stdarg.h>
+#define        _WITH_GETLINE
 #include <stdio.h>
-#include <wchar.h>
 
-int
-vwscanf(const wchar_t * __restrict fmt, va_list ap)
+ssize_t
+getline(char ** __restrict linep, size_t * __restrict linecapp,
+       FILE * __restrict fp)
 {
-
-       return (vfwscanf(stdin, fmt, ap));
+       return (getdelim(linep, linecapp, '\n', fp));
 }
index 907e700..df2be71 100644 (file)
  * 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.
@@ -34,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)gets.c  8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/gets.c,v 1.9 2000/01/27 23:06:45 jasone Exp $
+ * $FreeBSD: src/lib/libc/stdio/gets.c,v 1.17 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/gets.c,v 1.6 2005/11/20 11:07:30 swildner Exp $
  */
 
@@ -43,6 +39,9 @@
 #include <stdio.h>
 #include <sys/cdefs.h>
 #include "un-namespace.h"
+#include "libc_private.h"
+#include "local.h"
+#include "priv_stdio.h"
 
 __warn_references(gets, "warning: this program uses gets(), which is unsafe.");
 
@@ -55,18 +54,22 @@ gets(char *buf)
        static char w[] =
            "warning: this program uses gets(), which is unsafe.\n";
 
+       FLOCKFILE(stdin);
+       ORIENT(stdin, -1);
        if (!warned) {
                _write(STDERR_FILENO, w, sizeof(w) - 1);
                warned = 1;
        }
-       for (s = buf; (c = getchar()) != '\n';)
+       for (s = buf; (c = __sgetc(stdin)) != '\n';)
                if (c == EOF)
-                       if (s == buf)
+                       if (s == buf) {
+                               FUNLOCKFILE(stdin);
                                return (NULL);
-                       else
+                       else
                                break;
                else
                        *s++ = c;
        *s = 0;
+       FUNLOCKFILE(stdin);
        return (buf);
 }
index ccdb05b..2b4b7f4 100644 (file)
  * 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.
@@ -34,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)getw.c  8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/getw.c,v 1.6 1999/08/28 00:01:09 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/getw.c,v 1.8 2007/01/09 00:28:06 imp Exp $
  * $DragonFly: src/lib/libc/stdio/getw.c,v 1.3 2004/06/07 20:35:41 hmp Exp $
  */
 
index 2118b19..fe4f138 100644 (file)
@@ -1,5 +1,4 @@
-.\"    $NetBSD: getwc.3,v 1.7 2003/09/08 17:54:32 wiz Exp $
-.\"    $DragonFly: src/lib/libc/stdio/getwc.3,v 1.1 2005/07/25 00:37:41 joerg Exp $
+.\"    $NetBSD: getwc.3,v 1.3 2002/02/07 07:00:26 ross Exp $
 .\"
 .\" Copyright (c) 1990, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -16,7 +15,7 @@
 .\" 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. Neither the name of the University nor the names of 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.
 .\"
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)getc.3     8.1 (Berkeley) 6/4/93
+.\" $FreeBSD: src/lib/libc/stdio/getwc.3,v 1.8 2007/01/09 00:28:06 imp Exp $
+.\" $DragonFly: src/lib/libc/stdio/getwc.3,v 1.1 2005/07/25 00:37:41 joerg Exp $
 .\"
-.Dd October 24, 2001
+.Dd March 3, 2004
 .Dt GETWC 3
 .Os
 .Sh NAME
 .Nm fgetwc ,
 .Nm getwc ,
-.Nm getwchar ,
-.Nd get next wide-character from input stream
+.Nm getwchar
+.Nd get next wide character from input stream
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
 .Ft wint_t
 .Fn getwc "FILE *stream"
 .Ft wint_t
-.Fn getwchar
+.Fn getwchar void
 .Sh DESCRIPTION
 The
 .Fn fgetwc
 function
-obtains the next input wide-character (if present) from the stream pointed at by
+obtains the next input wide character (if present) from the stream pointed at by
 .Fa stream ,
 or the next character pushed back on the stream via
 .Xr ungetwc 3 .
@@ -66,17 +67,17 @@ The
 .Fn getwc
 function
 acts essentially identically to
-.Fn fgetwc ,
-but is a macro that expands in-line.
+.Fn fgetwc .
 .Pp
 The
 .Fn getwchar
 function
 is equivalent to
 .Fn getwc
-with the argument stdin.
+with the argument
+.Dv stdin .
 .Sh RETURN VALUES
-If successful, these routines return the next wide-character
+If successful, these routines return the next wide character
 from the
 .Fa stream .
 If the stream is at end-of-file or a read error occurs,
@@ -99,6 +100,7 @@ until the condition is cleared with
 .Xr ferror 3 ,
 .Xr fopen 3 ,
 .Xr fread 3 ,
+.Xr getc 3 ,
 .Xr putwc 3 ,
 .Xr stdio 3 ,
 .Xr ungetwc 3
index 5ef66b5..4eb88d0 100644 (file)
@@ -1,8 +1,5 @@
-/* $NetBSD: getwc.c,v 1.3 2005/06/12 05:21:27 lukem Exp $ */
-/* $DragonFly: src/lib/libc/stdio/getwc.c,v 1.1 2005/07/25 00:37:41 joerg Exp $ */
-
 /*-
- * Copyright (c)2001 Citrus Project,
+ * Copyright (c) 2002 Tim J. Robbins.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Citrus$
+ * $FreeBSD: src/lib/libc/stdio/getwc.c,v 1.3 2004/05/25 10:42:52 tjr Exp $
+ * $DragonFly: src/lib/libc/stdio/getwc.c,v 1.1 2005/07/25 00:37:41 joerg Exp $
  */
 
+#include "namespace.h"
 #include <stdio.h>
 #include <wchar.h>
+#include "un-namespace.h"
+#include "libc_private.h"
+#include "local.h"
 
-/*
- * A subroutine version of the macro getwc.
- */
 #undef getwc
 
+/*
+ * Synonym for fgetwc(). The only difference is that getwc(), if it is a
+ * macro, may evaluate `fp' more than once.
+ */
 wint_t
 getwc(FILE *fp)
 {
 
-       return fgetwc(fp);
+       return (fgetwc(fp));
 }
index 95028cd..00f40d8 100644 (file)
@@ -1,8 +1,5 @@
-/* $NetBSD: getwchar.c,v 1.3 2005/06/12 05:21:27 lukem Exp $ */
-/* $DragonFly: src/lib/libc/stdio/getwchar.c,v 1.2 2005/11/20 11:07:30 swildner Exp $ */
-
 /*-
- * Copyright (c)2001 Citrus Project,
+ * Copyright (c) 2002 Tim J. Robbins.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Citrus$
+ * $FreeBSD: src/lib/libc/stdio/getwchar.c,v 1.3 2004/05/25 10:42:52 tjr Exp $
+ * $DragonFly: src/lib/libc/stdio/getwchar.c,v 1.2 2005/11/20 11:07:30 swildner Exp $
  */
 
+#include "namespace.h"
 #include <stdio.h>
 #include <wchar.h>
+#include "un-namespace.h"
+#include "libc_private.h"
+#include "local.h"
 
-/*
- * A subroutine version of the macro getwchar.
- */
 #undef getwchar
 
+/*
+ * Synonym for fgetwc(stdin).
+ */
 wint_t
 getwchar(void)
 {
 
-       return fgetwc(stdin);
+       return (fgetwc(stdin));
 }
index 258edc0..6c8b010 100644 (file)
  * 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.
  * SUCH DAMAGE.
  *
  *     @(#)local.h     8.3 (Berkeley) 7/3/94
- *
- * $FreeBSD: src/lib/libc/stdio/local.h,v 1.1.1.2.6.1 2001/03/05 11:27:49 obrien Exp $
+ * $FreeBSD: src/lib/libc/stdio/local.h,v 1.33 2008/05/05 16:03:52 jhb Exp $
  * $DragonFly: src/lib/libc/stdio/local.h,v 1.11 2007/11/25 01:28:22 swildner Exp $
  */
 
-#include <sys/types.h> /* for off_t */
+#include <sys/types.h> /* for off_t */
+#include <pthread.h>
 #include <string.h>
-#include <wchar.h> /* for wchar_t */
+#include <wchar.h>
 
-#ifndef _MACHINE_STDINT_H_
-#include <machine/stdint.h>    /* __size_t */
-#endif
+#include "wcio.h"
 
 /*
  * Information local to this implementation of stdio,
  * in particular, macros and private variables.
  */
 
-extern int     __slbexpand(FILE *, size_t);
-extern int     __sflush (FILE *);
-extern FILE    *__sfp (void);
-extern int     __srefill (FILE *);
-extern int     __sread (void *, char *, int);
-extern int     __swrite (void *, char const *, int);
-extern fpos_t  __sseek (void *, fpos_t, int);
-extern int     __sclose (void *);
-extern void    __sinit (void);
-extern void    _cleanup (void);
-extern void    (*__cleanup) (void);
-extern void    __smakebuf (FILE *);
-extern int     __swhatbuf (FILE *, __size_t *, int *);
-extern int     _fwalk (int (*)(FILE *));
-extern int     __swsetup (FILE *);
-extern int     __sflags (const char *, int *);
-extern int     __vfprintf(FILE *, const char *, __va_list);
+extern int     _sread(FILE *, char *, int);
+extern int     _swrite(FILE *, const char *, int);
+extern fpos_t  _sseek(FILE *, fpos_t, int);
+extern int     _ftello(FILE *, fpos_t *);
+extern int     _fseeko(FILE *, off_t, int, int);
+extern int     __fflush(FILE *fp);
+extern void    __fcloseall(void);
 extern wint_t  __fgetwc_unlock(FILE *);
 extern wint_t  __fputwc_unlock(wchar_t, FILE *);
-extern int     __vfwprintf_unlocked(FILE *, const wchar_t *, __va_list);
-extern size_t  __fread(void *buf, size_t size, size_t count, FILE *fp);
-
+extern int     __sflush(FILE *);
+extern FILE    *__sfp(void);
+extern int     __slbexpand(FILE *, size_t);
+extern int     __srefill(FILE *);
+extern int     __sread(void *, char *, int);
+extern int     __swrite(void *, const char *, int);
+extern fpos_t  __sseek(void *, fpos_t, int);
+extern int     __sclose(void *);
+extern void    __sinit(void);
+extern void    _cleanup(void);
+extern void    __smakebuf(FILE *);
+extern int     __swhatbuf(FILE *, size_t *, int *);
+extern int     _fwalk(int (*)(FILE *));
+extern int     __svfscanf(FILE *, const char *, __va_list);
+extern int     __swsetup(FILE *);
+extern int     __sflags(const char *, int *);
+extern int     __ungetc(int, FILE *);
+extern int     __vfprintf(FILE *, const char *, __va_list);
+extern int     __vfscanf(FILE *, const char *, __va_list);
+extern int     __vfwprintf(FILE *, const wchar_t *, __va_list);
+extern int     __vfwscanf(FILE * __restrict, const wchar_t * __restrict,
+                          __va_list);
+extern size_t  __fread(void * __restrict buf, size_t size, size_t count,
+                       FILE * __restrict fp);
 extern int     __sdidinit;
 
+
 /*
- * Return true iff the given FILE cannot be written now.
+ * Prepare the given FILE for writing, and return 0 iff it
+ * can be written now.  Otherwise, return EOF and set errno.
  */
-#define        cantwrite(fp) \
-       ((((fp)->pub._flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \
+#define        prepwrite(fp) \
+       ((((fp)->pub._flags & __SWR) == 0 || \
+           ((fp)->_bf._base == NULL && ((fp)->pub._flags & __SSTR) == 0)) && \
         __swsetup(fp))
 
 /*
@@ -102,3 +110,9 @@ extern int  __sdidinit;
        free((char *)(fp)->_lb._base); \
        (fp)->_lb._base = NULL; \
 }
+
+/*
+ * Set the orientation for a stream. If o > 0, the stream has wide-
+ * orientation. If o < 0, the stream has byte-orientation.
+ */
+#define        ORIENT(fp, o)   _SET_ORIENTATION(fp, o)
index 97208ed..47e3a38 100644 (file)
  * 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.
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libc/stdio/makebuf.c,v 1.1.1.1.14.1 2001/03/05 11:27:49 obrien Exp $
- * $DragonFly: src/lib/libc/stdio/makebuf.c,v 1.6 2005/07/23 20:23:06 joerg Exp $
- *
  * @(#)makebuf.c       8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdio/makebuf.c,v 1.6 2007/01/09 00:28:07 imp Exp $
+ * $DragonFly: src/lib/libc/stdio/makebuf.c,v 1.6 2005/07/23 20:23:06 joerg Exp $
  */
 
 #include "namespace.h"
@@ -47,6 +42,7 @@
 #include <stdlib.h>
 #include "un-namespace.h"
 
+#include "libc_private.h"
 #include "local.h"
 #include "priv_stdio.h"
 
index 1f831c1..e7c019d 100644 (file)
@@ -9,10 +9,6 @@
 .\" 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.
@@ -30,7 +26,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)mktemp.3   8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdio/mktemp.3,v 1.11.2.6 2001/12/14 18:33:57 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdio/mktemp.3,v 1.22 2007/01/09 00:28:07 imp Exp $
 .\" $DragonFly: src/lib/libc/stdio/mktemp.3,v 1.3 2006/02/17 19:35:06 swildner Exp $
 .\"
 .Dd February 11, 1998
@@ -95,13 +91,15 @@ function acts the same as
 except it permits a suffix to exist in the template.
 The template should be of the form
 .Pa /tmp/tmpXXXXXXsuffix .
+The
 .Fn mkstemps
+function
 is told the length of the suffix string.
 .Pp
 The
 .Fn mkdtemp
 function makes the same replacement to the template as in
-.Xr mktemp 3
+.Fn mktemp
 and creates the template directory, mode 0700.
 .Sh RETURN VALUES
 The
@@ -245,3 +243,10 @@ and the return status of the call should be tested for failure.
 This will ensure that the program does not continue blindly
 in the event that an attacker has already created the file
 with the intention of manipulating or reading its contents.
+.Pp
+The implementation of these functions calls
+.Xr arc4random 3 ,
+which is not reentrant.
+You must provide your own locking around this and other consumers of the
+.Xr arc4random 3
+API.
index b9e8a03..97c9159 100644 (file)
  * 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.
  * SUCH DAMAGE.
  *
  * @(#)mktemp.c        8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/mktemp.c,v 1.19.2.3 2002/06/18 09:53:07 robert Exp $
+ * $FreeBSD: src/lib/libc/stdio/mktemp.c,v 1.31 2008/07/28 21:18:59 jhb Exp $
  * $DragonFly: src/lib/libc/stdio/mktemp.c,v 1.7 2005/11/20 11:07:30 swildner Exp $
  */
 
-/* #include "namespace.h" */
-#include <sys/types.h>
+#include "namespace.h"
+#include <sys/param.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <string.h>
 #include <ctype.h>
 #include <unistd.h>
-/* #include "un-namespace.h" */
+#include "un-namespace.h"
 
-char *_mktemp (char *);
+char *_mktemp(char *);
 
-static int _gettemp (char *, int *, int, int);
+static int _gettemp(char *, int *, int, int);
 
 static const unsigned char padchar[] =
 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
@@ -94,13 +90,14 @@ mktemp(char *path)
 static int
 _gettemp(char *path, int *doopen, int domkdir, int slen)
 {
-       char *start, *trv, *suffp;
+       char *start, *trv, *suffp, *carryp;
        char *pad;
        struct stat sbuf;
        int rval;
-       uint32_t psrand;
+       uint32_t rand;
+       char carrybuf[MAXPATHLEN];
 
-       if (doopen != NULL && domkdir) {
+       if ((doopen != NULL && domkdir) || slen < 0) {
                errno = EINVAL;
                return (0);
        }
@@ -110,18 +107,21 @@ _gettemp(char *path, int *doopen, int domkdir, int slen)
        trv -= slen;
        suffp = trv;
        --trv;
-       if (trv < path) {
+       if (trv < path || NULL != strchr(suffp, '/')) {
                errno = EINVAL;
                return (0);
        }
 
        /* Fill space with random characters */
        while (trv >= path && *trv == 'X') {
-               psrand = arc4random() % (sizeof(padchar) - 1);
-               *trv-- = padchar[psrand];
+               rand = arc4random_uniform(sizeof(padchar) - 1);
+               *trv-- = padchar[rand];
        }
        start = trv + 1;
 
+       /* save first combination of random characters */
+       memcpy(carrybuf, start, suffp - start);
+
        /*
         * check the target directory.
         */
@@ -158,14 +158,25 @@ _gettemp(char *path, int *doopen, int domkdir, int slen)
                        return (errno == ENOENT);
 
                /* If we have a collision, cycle through the space of filenames */
-               for (trv = start;;) {
-                       if (*trv == '\0' || trv == suffp)
-                               return (0);
+               for (trv = start, carryp = carrybuf;;) {
+                       /* have we tried all possible permutations? */
+                       if (trv == suffp)
+                               return (0); /* yes - exit with EEXIST */
                        pad = strchr(padchar, *trv);
-                       if (pad == NULL || *++pad == '\0')
-                               *trv++ = padchar[0];
-                       else {
-                               *trv++ = *pad;
+                       if (pad == NULL) {
+                               /* this should never happen */
+                               errno = EIO;
+                               return (0);
+                       }
+                       /* increment character */
+                       *trv = (*++pad == '\0') ? padchar[0] : *pad;
+                       /* carry to next position? */
+                       if (*trv == *carryp) {
+                               /* increment position and loop */
+                               ++trv;
+                               ++carryp;
+                       } else {
+                               /* try with new name */
                                break;
                        }
                }
index 09091a9..9c8fd59 100644 (file)
  * 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.
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libc/stdio/perror.c,v 1.3.6.1 2001/03/05 11:27:49 obrien Exp $
- * $DragonFly: src/lib/libc/stdio/perror.c,v 1.7 2005/11/20 11:07:30 swildner Exp $
- *
  * @(#)perror.c        8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdio/perror.c,v 1.9 2007/01/09 00:28:07 imp Exp $
+ * $DragonFly: src/lib/libc/stdio/perror.c,v 1.7 2005/11/20 11:07:30 swildner Exp $
  */
 
 #include "namespace.h"
 #include <sys/uio.h>
 #include <unistd.h>
 #include <errno.h>
+#include <limits.h>
 #include <stdio.h>
 #include <string.h>
 #include "un-namespace.h"
+#include "libc_private.h"
+#include "local.h"
+#include "priv_stdio.h"
 
 void
 perror(const char *s)
 {
+       char msgbuf[NL_TEXTMAX];
        struct iovec *v;
        struct iovec iov[4];
 
@@ -60,10 +60,15 @@ perror(const char *s)
                v->iov_len = 2;
                v++;
        }
-       v->iov_base = strerror(errno);
+       strerror_r(errno, msgbuf, sizeof(msgbuf));
+       v->iov_base = msgbuf;
        v->iov_len = strlen(v->iov_base);
        v++;
        v->iov_base = __DECONST(char *, "\n");
        v->iov_len = 1;
-       _writev(STDERR_FILENO, iov, (v - iov) + 1);
+       FLOCKFILE(stderr);
+       __sflush(stderr);
+       _writev(stderr->pub._fileno, iov, (v - iov) + 1);
+       stderr->pub._flags &= ~__SOFF;
+       FUNLOCKFILE(stderr);
 }
diff --git a/lib/libc/stdio/printf-pos.c b/lib/libc/stdio/printf-pos.c
new file mode 100644 (file)
index 0000000..9344661
--- /dev/null
@@ -0,0 +1,755 @@
+/*-
+ * 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.
+ * 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.
+ *
+ * @(#)vfprintf.c      8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/stdio/printf-pos.c,v 1.6 2009/03/02 04:07:58 das Exp $
+ */
+
+/*
+ * This is the code responsible for handling positional arguments
+ * (%m$ and %m$.n$) for vfprintf() and vfwprintf().
+ */
+
+#include "namespace.h"
+#include <sys/types.h>
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#include "un-namespace.h"
+#include "printflocal.h"
+
+/*
+ * Type ids for argument type table.
+ */
+enum typeid {
+       T_UNUSED, TP_SHORT, T_INT, T_U_INT, TP_INT,
+       T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG,
+       T_PTRDIFFT, TP_PTRDIFFT, T_SSIZET, T_SIZET, TP_SSIZET,
+       T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID, TP_CHAR, TP_SCHAR,
+       T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR
+};
+
+/* An expandable array of types. */
+struct typetable {
+       enum typeid *table; /* table of types */
+       enum typeid stattable[STATIC_ARG_TBL_SIZE];
+       int tablesize;          /* current size of type table */
+       int tablemax;           /* largest used index in table */
+       int nextarg;            /* 1-based argument index */
+};
+
+static int     __grow_type_table(struct typetable *);
+static void    build_arg_table (struct typetable *, va_list, union arg **);
+
+/*
+ * Initialize a struct typetable.
+ */
+static inline void
+inittypes(struct typetable *types)
+{
+       int n;
+
+       types->table = types->stattable;
+       types->tablesize = STATIC_ARG_TBL_SIZE;
+       types->tablemax = 0;
+       types->nextarg = 1;
+       for (n = 0; n < STATIC_ARG_TBL_SIZE; n++)
+               types->table[n] = T_UNUSED;
+}
+
+/*
+ * struct typetable destructor.
+ */
+static inline void
+freetypes(struct typetable *types)
+{
+
+       if (types->table != types->stattable)
+               free(types->table);
+}
+
+/*
+ * Ensure that there is space to add a new argument type to the type table.
+ * Expand the table if necessary. Returns 0 on success.
+ */
+static inline int
+_ensurespace(struct typetable *types)
+{
+
+       if (types->nextarg >= types->tablesize) {
+               if (__grow_type_table(types))
+                       return (-1);
+       }
+       if (types->nextarg > types->tablemax)
+               types->tablemax = types->nextarg;
+       return (0);
+}
+
+/*
+ * Add an argument type to the table, expanding if necessary.
+ * Returns 0 on success.
+ */
+static inline int
+addtype(struct typetable *types, enum typeid type)
+{
+
+       if (_ensurespace(types))
+               return (-1);
+       types->table[types->nextarg++] = type;
+       return (0);
+}
+
+static inline int
+addsarg(struct typetable *types, int flags)
+{
+
+       if (_ensurespace(types))
+               return (-1);
+       if (flags & INTMAXT)
+               types->table[types->nextarg++] = T_INTMAXT;
+       else if (flags & SIZET)
+               types->table[types->nextarg++] = T_SSIZET;
+       else if (flags & PTRDIFFT)
+               types->table[types->nextarg++] = T_PTRDIFFT;
+       else if (flags & LLONGINT)
+               types->table[types->nextarg++] = T_LLONG;
+       else if (flags & LONGINT)
+               types->table[types->nextarg++] = T_LONG;
+       else
+               types->table[types->nextarg++] = T_INT;
+       return (0);
+}
+
+static inline int
+adduarg(struct typetable *types, int flags)
+{
+
+       if (_ensurespace(types))
+               return (-1);
+       if (flags & INTMAXT)
+               types->table[types->nextarg++] = T_UINTMAXT;
+       else if (flags & SIZET)
+               types->table[types->nextarg++] = T_SIZET;
+       else if (flags & PTRDIFFT)
+               types->table[types->nextarg++] = T_SIZET;
+       else if (flags & LLONGINT)
+               types->table[types->nextarg++] = T_U_LLONG;
+       else if (flags & LONGINT)
+               types->table[types->nextarg++] = T_U_LONG;
+       else
+               types->table[types->nextarg++] = T_U_INT;
+       return (0);
+}
+
+/*
+ * Add * arguments to the type array.
+ */
+static inline int
+addaster(struct typetable *types, char **fmtp)
+{
+       char *cp;
+       int n2;
+
+       n2 = 0;
+       cp = *fmtp;
+       while (is_digit(*cp)) {
+               n2 = 10 * n2 + to_digit(*cp);
+               cp++;
+       }
+       if (*cp == '$') {
+               int hold = types->nextarg;
+               types->nextarg = n2;
+               if (addtype(types, T_INT))
+                       return (-1);
+               types->nextarg = hold;
+               *fmtp = ++cp;
+       } else {
+               if (addtype(types, T_INT))
+                       return (-1);
+       }
+       return (0);
+}
+
+static inline int
+addwaster(struct typetable *types, wchar_t **fmtp)
+{
+       wchar_t *cp;
+       int n2;
+
+       n2 = 0;
+       cp = *fmtp;
+       while (is_digit(*cp)) {
+               n2 = 10 * n2 + to_digit(*cp);
+               cp++;
+       }
+       if (*cp == '$') {
+               int hold = types->nextarg;
+               types->nextarg = n2;
+               if (addtype(types, T_INT))
+                       return (-1);
+               types->nextarg = hold;
+               *fmtp = ++cp;
+       } else {
+               if (addtype(types, T_INT))
+                       return (-1);
+       }
+       return (0);
+}
+
+/*
+ * Find all arguments when a positional parameter is encountered.  Returns a
+ * table, indexed by argument number, of pointers to each arguments.  The
+ * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
+ * It will be replaces with a malloc-ed one if it overflows.
+ * Returns 0 on success. On failure, returns nonzero and sets errno.
+ */
+int
+__find_arguments(const char *fmt0, va_list ap, union arg **argtable)
+{
+       char *fmt;              /* format string */
+       int ch;                 /* character from fmt */
+       int n;                  /* handy integer (short term usage) */
+       int error;
+       int flags;              /* flags as above */
+       int width;              /* width from format (%8d), or 0 */
+       struct typetable types; /* table of types */
+
+       fmt = __DECONST(char *, fmt0);
+       inittypes(&types);
+       error = 0;
+
+       /*
+        * Scan the format for conversions (`%' character).
+        */
+       for (;;) {
+               while ((ch = *fmt) != '\0' && ch != '%')
+                       fmt++;
+               if (ch == '\0')
+                       goto done;
+               fmt++;          /* skip over '%' */
+
+               flags = 0;
+               width = 0;
+
+rflag:         ch = *fmt++;
+reswitch:      switch (ch) {
+               case ' ':
+               case '#':
+                       goto rflag;
+               case '*':
+                       if ((error = addaster(&types, &fmt)))
+                               goto error;
+                       goto rflag;
+               case '-':
+               case '+':
+               case '\'':
+                       goto rflag;
+               case '.':
+                       if ((ch = *fmt++) == '*') {
+                               if ((error = addaster(&types, &fmt)))
+                                       goto error;
+                               goto rflag;
+                       }
+                       while (is_digit(ch)) {
+                               ch = *fmt++;
+                       }
+                       goto reswitch;
+               case '0':
+                       goto rflag;
+               case '1': case '2': case '3': case '4':
+               case '5': case '6': case '7': case '8': case '9':
+                       n = 0;
+                       do {
+                               n = 10 * n + to_digit(ch);
+                               ch = *fmt++;
+                       } while (is_digit(ch));
+                       if (ch == '$') {
+                               types.nextarg = n;
+                               goto rflag;
+                       }
+                       width = n;
+                       goto reswitch;
+#ifndef NO_FLOATING_POINT
+               case 'L':
+                       flags |= LONGDBL;
+                       goto rflag;
+#endif
+               case 'h':
+                       if (flags & SHORTINT) {
+                               flags &= ~SHORTINT;
+                               flags |= CHARINT;
+                       } else
+                               flags |= SHORTINT;
+                       goto rflag;
+               case 'j':
+                       flags |= INTMAXT;
+                       goto rflag;
+               case 'l':
+                       if (flags & LONGINT) {
+                               flags &= ~LONGINT;
+                               flags |= LLONGINT;
+                       } else
+                               flags |= LONGINT;
+                       goto rflag;
+               case 'q':
+                       flags |= LLONGINT;      /* not necessarily */
+                       goto rflag;
+               case 't':
+                       flags |= PTRDIFFT;
+                       goto rflag;
+               case 'z':
+                       flags |= SIZET;
+                       goto rflag;
+               case 'C':
+                       flags |= LONGINT;
+                       /*FALLTHROUGH*/
+               case 'c':
+                       error = addtype(&types,
+                                       (flags & LONGINT) ? T_WINT : T_INT);
+                       if (error)
+                               goto error;
+                       break;
+               case 'D':
+                       flags |= LONGINT;
+                       /*FALLTHROUGH*/
+               case 'd':
+               case 'i':
+                       if ((error = addsarg(&types, flags)))
+                               goto error;
+                       break;
+#ifndef NO_FLOATING_POINT
+               case 'a':
+               case 'A':
+               case 'e':
+               case 'E':
+               case 'f':
+               case 'g':
+               case 'G':
+                       error = addtype(&types,
+                           (flags & LONGDBL) ? T_LONG_DOUBLE : T_DOUBLE);
+                       if (error)
+                               goto error;
+                       break;
+#endif /* !NO_FLOATING_POINT */
+               case 'n':
+                       if (flags & INTMAXT)
+                               error = addtype(&types, TP_INTMAXT);
+                       else if (flags & PTRDIFFT)
+                               error = addtype(&types, TP_PTRDIFFT);
+                       else if (flags & SIZET)
+                               error = addtype(&types, TP_SSIZET);
+                       else if (flags & LLONGINT)
+                               error = addtype(&types, TP_LLONG);
+                       else if (flags & LONGINT)
+                               error = addtype(&types, TP_LONG);
+                       else if (flags & SHORTINT)
+                               error = addtype(&types, TP_SHORT);
+                       else if (flags & CHARINT)
+                               error = addtype(&types, TP_SCHAR);
+                       else
+                               error = addtype(&types, TP_INT);
+                       if (error)
+                               goto error;
+                       continue;       /* no output */
+               case 'O':
+                       flags |= LONGINT;
+                       /*FALLTHROUGH*/
+               case 'o':
+                       if ((error = adduarg(&types, flags)))
+                               goto error;
+                       break;
+               case 'p':
+                       if ((error = addtype(&types, TP_VOID)))
+                               goto error;
+                       break;
+               case 'S':
+                       flags |= LONGINT;
+                       /*FALLTHROUGH*/
+               case 's':
+                       error = addtype(&types,
+                                       (flags & LONGINT) ? TP_WCHAR : TP_CHAR);
+                       if (error)
+                               goto error;
+                       break;
+               case 'U':
+                       flags |= LONGINT;
+                       /*FALLTHROUGH*/
+               case 'u':
+               case 'X':
+               case 'x':
+                       if ((error = adduarg(&types, flags)))
+                               goto error;
+                       break;
+               default:        /* "%?" prints ?, unless ? is NUL */
+                       if (ch == '\0')
+                               goto done;
+                       break;
+               }
+       }
+done:
+       build_arg_table(&types, ap, argtable);
+error:
+       freetypes(&types);
+       return (error || *argtable == NULL);
+}
+
+/* wchar version of __find_arguments. */
+int
+__find_warguments(const wchar_t *fmt0, va_list ap, union arg **argtable)
+{
+       wchar_t *fmt;           /* format string */
+       wchar_t ch;             /* character from fmt */
+       int n;                  /* handy integer (short term usage) */
+       int error;
+       int flags;              /* flags as above */
+       int width;              /* width from format (%8d), or 0 */
+       struct typetable types; /* table of types */
+
+       fmt = __DECONST(wchar_t *, fmt0);
+       inittypes(&types);
+       error = 0;
+
+       /*
+        * Scan the format for conversions (`%' character).
+        */
+       for (;;) {
+               while ((ch = *fmt) != '\0' && ch != '%')
+                       fmt++;
+               if (ch == '\0')
+                       goto done;
+               fmt++;          /* skip over '%' */
+
+               flags = 0;
+               width = 0;
+
+rflag:         ch = *fmt++;
+reswitch:      switch (ch) {
+               case ' ':
+               case '#':
+                       goto rflag;
+               case '*':
+                       if ((error = addwaster(&types, &fmt)))
+                               goto error;
+                       goto rflag;
+               case '-':
+               case '+':
+               case '\'':
+                       goto rflag;
+               case '.':
+                       if ((ch = *fmt++) == '*') {
+                               if ((error = addwaster(&types, &fmt)))
+                                       goto error;
+                               goto rflag;
+                       }
+                       while (is_digit(ch)) {
+                               ch = *fmt++;
+                       }
+                       goto reswitch;
+               case '0':
+                       goto rflag;
+               case '1': case '2': case '3': case '4':
+               case '5': case '6': case '7': case '8': case '9':
+                       n = 0;
+                       do {
+                               n = 10 * n + to_digit(ch);
+                               ch = *fmt++;
+                       } while (is_digit(ch));
+                       if (ch == '$') {
+                               types.nextarg = n;
+                               goto rflag;
+                       }
+                       width = n;
+                       goto reswitch;
+#ifndef NO_FLOATING_POINT
+               case 'L':
+                       flags |= LONGDBL;
+                       goto rflag;
+#endif
+               case 'h':
+                       if (flags & SHORTINT) {
+                               flags &= ~SHORTINT;
+                               flags |= CHARINT;
+                       } else
+                               flags |= SHORTINT;
+                       goto rflag;
+               case 'j':
+                       flags |= INTMAXT;
+                       goto rflag;
+               case 'l':
+                       if (flags & LONGINT) {
+                               flags &= ~LONGINT;
+                               flags |= LLONGINT;
+                       } else
+                               flags |= LONGINT;
+                       goto rflag;
+               case 'q':
+                       flags |= LLONGINT;      /* not necessarily */
+                       goto rflag;
+               case 't':
+                       flags |= PTRDIFFT;
+                       goto rflag;
+               case 'z':
+                       flags |= SIZET;
+                       goto rflag;
+               case 'C':
+                       flags |= LONGINT;
+                       /*FALLTHROUGH*/
+               case 'c':
+                       error = addtype(&types,
+                                       (flags & LONGINT) ? T_WINT : T_INT);
+                       if (error)
+                               goto error;
+                       break;
+               case 'D':
+                       flags |= LONGINT;
+                       /*FALLTHROUGH*/
+               case 'd':
+               case 'i':
+                       if ((error = addsarg(&types, flags)))
+                               goto error;
+                       break;
+#ifndef NO_FLOATING_POINT
+               case 'a':
+               case 'A':
+               case 'e':
+               case 'E':
+               case 'f':
+               case 'g':
+               case 'G':
+                       error = addtype(&types,
+                           (flags & LONGDBL) ? T_LONG_DOUBLE : T_DOUBLE);
+                       if (error)
+                               goto error;
+                       break;
+#endif /* !NO_FLOATING_POINT */
+               case 'n':
+                       if (flags & INTMAXT)
+                               error = addtype(&types, TP_INTMAXT);
+                       else if (flags & PTRDIFFT)
+                               error = addtype(&types, TP_PTRDIFFT);
+                       else if (flags & SIZET)
+                               error = addtype(&types, TP_SSIZET);
+                       else if (flags & LLONGINT)
+                               error = addtype(&types, TP_LLONG);
+                       else if (flags & LONGINT)
+                               error = addtype(&types, TP_LONG);
+                       else if (flags & SHORTINT)
+                               error = addtype(&types, TP_SHORT);
+                       else if (flags & CHARINT)
+                               error = addtype(&types, TP_SCHAR);
+                       else
+                               error = addtype(&types, TP_INT);
+                       if (error)
+                               goto error;
+                       continue;       /* no output */
+               case 'O':
+                       flags |= LONGINT;
+                       /*FALLTHROUGH*/
+               case 'o':
+                       if ((error = adduarg(&types, flags)))
+                               goto error;
+                       break;
+               case 'p':
+                       if ((error = addtype(&types, TP_VOID)))
+                               goto error;
+                       break;
+               case 'S':
+                       flags |= LONGINT;
+                       /*FALLTHROUGH*/
+               case 's':
+                       error = addtype(&types,
+                           (flags & LONGINT) ? TP_WCHAR : TP_CHAR);
+                       if (error)
+                               goto error;
+                       break;
+               case 'U':
+                       flags |= LONGINT;
+                       /*FALLTHROUGH*/
+               case 'u':
+               case 'X':
+               case 'x':
+                       if ((error = adduarg(&types, flags)))
+                               goto error;
+                       break;
+               default:        /* "%?" prints ?, unless ? is NUL */
+                       if (ch == '\0')
+                               goto done;
+                       break;
+               }
+       }
+done:
+       build_arg_table(&types, ap, argtable);
+error:
+       freetypes(&types);
+       return (error || *argtable == NULL);
+}
+
+/*
+ * Increase the size of the type table. Returns 0 on success.
+ */
+static int
+__grow_type_table(struct typetable *types)
+{
+       enum typeid *const oldtable = types->table;
+       const int oldsize = types->tablesize;
+       enum typeid *newtable;
+       int n, newsize = oldsize * 2;
+
+       if (newsize < types->nextarg + 1)
+               newsize = types->nextarg + 1;
+       if (oldsize == STATIC_ARG_TBL_SIZE) {
+               if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL)
+                       return (-1);
+               bcopy(oldtable, newtable, oldsize * sizeof(enum typeid));
+       } else {
+               newtable = realloc(oldtable, newsize * sizeof(enum typeid));
+               if (newtable == NULL)
+                       return (-1);
+       }
+       for (n = oldsize; n < newsize; n++)
+               newtable[n] = T_UNUSED;
+
+       types->table = newtable;
+       types->tablesize = newsize;
+
+       return (0);
+}
+
+/*
+ * Build the argument table from the completed type table.
+ * On malloc failure, *argtable is set to NULL.
+ */
+static void
+build_arg_table(struct typetable *types, va_list ap, union arg **argtable)
+{
+       int n;
+
+       if (types->tablemax >= STATIC_ARG_TBL_SIZE) {
+               *argtable = (union arg *)
+                   malloc (sizeof (union arg) * (types->tablemax + 1));
+               if (*argtable == NULL)
+                       return;
+       }
+
+       (*argtable) [0].intarg = 0;
+       for (n = 1; n <= types->tablemax; n++) {
+               switch (types->table[n]) {
+                   case T_UNUSED: /* whoops! */
+                       (*argtable) [n].intarg = va_arg(ap, int);
+                       break;
+                   case TP_SCHAR:
+                       (*argtable) [n].pschararg = va_arg(ap, signed char *);
+                       break;
+                   case TP_SHORT:
+                       (*argtable) [n].pshortarg = va_arg(ap, short *);
+                       break;
+                   case T_INT:
+                       (*argtable) [n].intarg = va_arg(ap, int);
+                       break;
+                   case T_U_INT:
+                       (*argtable) [n].uintarg = va_arg(ap, unsigned int);
+                       break;
+                   case TP_INT:
+                       (*argtable) [n].pintarg = va_arg(ap, int *);
+                       break;
+                   case T_LONG:
+                       (*argtable) [n].longarg = va_arg(ap, long);
+                       break;
+                   case T_U_LONG:
+                       (*argtable) [n].ulongarg = va_arg(ap, unsigned long);
+                       break;
+                   case TP_LONG:
+                       (*argtable) [n].plongarg = va_arg(ap, long *);
+                       break;
+                   case T_LLONG:
+                       (*argtable) [n].longlongarg = va_arg(ap, long long);
+                       break;
+                   case T_U_LLONG:
+                       (*argtable) [n].ulonglongarg = va_arg(ap, unsigned long long);
+                       break;
+                   case TP_LLONG:
+                       (*argtable) [n].plonglongarg = va_arg(ap, long long *);
+                       break;
+                   case T_PTRDIFFT:
+                       (*argtable) [n].ptrdiffarg = va_arg(ap, ptrdiff_t);
+                       break;
+                   case TP_PTRDIFFT:
+                       (*argtable) [n].pptrdiffarg = va_arg(ap, ptrdiff_t *);
+                       break;
+                   case T_SIZET:
+                       (*argtable) [n].sizearg = va_arg(ap, size_t);
+                       break;
+                   case T_SSIZET:
+                       (*argtable) [n].sizearg = va_arg(ap, ssize_t);
+                       break;
+                   case TP_SSIZET:
+                       (*argtable) [n].pssizearg = va_arg(ap, ssize_t *);
+                       break;
+                   case T_INTMAXT:
+                       (*argtable) [n].intmaxarg = va_arg(ap, intmax_t);
+                       break;
+                   case T_UINTMAXT:
+                       (*argtable) [n].uintmaxarg = va_arg(ap, uintmax_t);
+                       break;
+                   case TP_INTMAXT:
+                       (*argtable) [n].pintmaxarg = va_arg(ap, intmax_t *);
+                       break;
+                   case T_DOUBLE:
+#ifndef NO_FLOATING_POINT
+                       (*argtable) [n].doublearg = va_arg(ap, double);
+#endif
+                       break;
+                   case T_LONG_DOUBLE:
+#ifndef NO_FLOATING_POINT
+                       (*argtable) [n].longdoublearg = va_arg(ap, long double);
+#endif
+                       break;
+                   case TP_CHAR:
+                       (*argtable) [n].pchararg = va_arg(ap, char *);
+                       break;
+                   case TP_VOID:
+                       (*argtable) [n].pvoidarg = va_arg(ap, void *);
+                       break;
+                   case T_WINT:
+                       (*argtable) [n].wintarg = va_arg(ap, wint_t);
+                       break;
+                   case TP_WCHAR:
+                       (*argtable) [n].pwchararg = va_arg(ap, wchar_t *);
+                       break;
+               }
+       }
+}
index 835da14..c86355f 100644 (file)
 .\" 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.
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)printf.3   8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdio/printf.3,v 1.59 2005/09/05 09:49:33 tjr Exp $
+.\" $FreeBSD: src/lib/libc/stdio/printf.3,v 1.63 2009/03/04 03:38:51 das Exp $
 .\" $DragonFly: src/lib/libc/stdio/printf.3,v 1.6 2006/08/26 10:27:55 swildner Exp $
 .\"
-.Dd August 26, 2006
+.Dd March 3, 2009
 .Dt PRINTF 3
 .Os
 .Sh NAME
 .Nm sprintf ,
 .Nm snprintf ,
 .Nm asprintf ,
+.Nm dprintf ,
 .Nm vprintf ,
 .Nm vfprintf ,
 .Nm vsprintf ,
 .Nm vsnprintf ,
-.Nm vasprintf
+.Nm vasprintf ,
+.Nm vdprintf
 .Nd formatted output conversion
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
+.Fd "#define _WITH_DPRINTF"
 .In stdio.h
 .Ft int
-.Fn printf "const char *format" ...
+.Fn printf "const char * restrict format" ...
 .Ft int
-.Fn fprintf "FILE *stream" "const char *format" ...
+.Fn fprintf "FILE * restrict stream" "const char * restrict format" ...
 .Ft int
-.Fn sprintf "char *str" "const char *format" ...
+.Fn sprintf "char * restrict str" "const char * restrict format" ...
 .Ft int
-.Fn snprintf "char *str" "size_t size" "const char *format" ...
+.Fn snprintf "char * restrict str" "size_t size" "const char * restrict format" ...
 .Ft int
 .Fn asprintf "char **ret" "const char *format" ...
+.Ft int
+.Fn dprintf "int" "const char * restrict format" ...
 .In stdarg.h
 .Ft int
-.Fn vprintf "const char *format" "va_list ap"
+.Fn vprintf "const char * restrict format" "va_list ap"
 .Ft int
-.Fn vfprintf "FILE *stream" "const char *format" "va_list ap"
+.Fn vfprintf "FILE * restrict stream" "const char * restrict format" "va_list ap"
 .Ft int
-.Fn vsprintf "char *str" "const char *format" "va_list ap"
+.Fn vsprintf "char * restrict str" "const char * restrict format" "va_list ap"
 .Ft int
-.Fn vsnprintf "char *str" "size_t size" "const char *format" "va_list ap"
+.Fn vsnprintf "char * restrict str" "size_t size" "const char * restrict format" "va_list ap"
 .Ft int
 .Fn vasprintf "char **ret" "const char *format" "va_list ap"
+.Ft int
+.Fn vdprintf "int fd" "const char * restrict format" "va_list ap"
 .Sh DESCRIPTION
 The
 .Fn printf
@@ -96,6 +99,10 @@ and
 .Fn vfprintf
 write output to the given output
 .Fa stream ;
+.Fn dprintf
+and
+.Fn vdprintf
+write output to the given file descriptor;
 .Fn sprintf ,
 .Fn snprintf ,
 .Fn vsprintf ,
@@ -220,8 +227,7 @@ conversions, this option has no effect.
 For
 .Cm o
 conversions, the precision of the number is increased to force the first
-character of the output string to a zero (except if a zero value is printed
-with an explicit precision of zero).
+character of the output string to a zero.
 For
 .Cm x
 and
@@ -234,7 +240,7 @@ for
 .Cm X
 conversions) prepended to it.
 For
-.Cm e , E , f , F , g ,
+.Cm a , A , e , E , f , F , g ,
 and
 .Cm G
 conversions, the result will always contain a decimal point, even if no
@@ -273,7 +279,7 @@ if both are given.
 .It So "\ " Sc (space)
 A blank should be left before a positive number
 produced by a signed conversion
-.Cm ( d , e , E , f , F , g , G ,
+.Cm ( a , A , d , e , E , f , F , g , G ,
 or
 .Cm i ) .
 .It Sq Cm +
@@ -282,6 +288,18 @@ number produced by a signed conversion.
 A
 .Cm +
 overrides a space if both are used.
+.It Sq Cm '
+Decimal conversions
+.Cm ( d , u ,
+or
+.Cm i )
+or the integral portion of a floating point conversion
+.Cm ( f
+or
+.Cm F )
+should be grouped and separated by thousands using
+the non-monetary separator returned by
+.Xr localeconv 3 .
 .El
 .It
 An optional decimal digit string specifying a minimum field width.
@@ -300,7 +318,7 @@ This gives the minimum number of digits to appear for
 and
 .Cm X
 conversions, the number of digits to appear after the decimal-point for
-.Cm e , E , f ,
+.Cm a , A , e , E , f ,
 and
 .Cm F
 conversions, the maximum number of significant digits for
@@ -356,12 +374,12 @@ equivalent in size to a
 .Vt size_t .
 .Pp
 The following length modifier is valid for the
-.Cm e , E , f , F , g ,
+.Cm a , A , e , E , f , F , g ,
 or
 .Cm G
 conversion:
 .Bl -column ".Sy Modifier" ".Cm a , A , e , E , f , F , g , G"
-.It Sy Modifier Ta Cm e , E , f , F , g , G
+.It Sy Modifier Ta Cm a , A , e , E , f , F , g , G
 .It Cm l No (ell) Ta Vt double
 (ignored, same behavior as without it)
 .It Cm L Ta Vt "long double"
@@ -461,7 +479,7 @@ The exponent always contains at least two digits; if the value is zero,
 the exponent is 00.
 .Pp
 For
-.Cm e , E , f , F , g ,
+.Cm a , A , e , E , f , F , g ,
 and
 .Cm G
 conversions, positive and negative infinity are represented as
@@ -513,6 +531,55 @@ is used if the exponent from its conversion is less than \-4 or greater than
 or equal to the precision.
 Trailing zeros are removed from the fractional part of the result; a
 decimal point appears only if it is followed by at least one digit.
+.It Cm aA
+The
+.Vt double
+argument is rounded and converted to hexadecimal notation in the style
+.Sm off
+.Oo \- Oc Li 0x Ar h Li \&. Ar hhhp Oo \\*[Pm] Oc Ar d ,
+.Sm on
+where the number of digits after the hexadecimal-point character
+is equal to the precision specification.
+If the precision is missing, it is taken as enough to represent
+the floating-point number exactly, and no rounding occurs.
+If the precision is zero, no hexadecimal-point character appears.
+The
+.Cm p
+is a literal character
+.Ql p ,
+and the exponent consists of a positive or negative sign
+followed by a decimal number representing an exponent of 2.
+The
+.Cm A
+conversion uses the prefix
+.Dq Li 0X
+(rather than
+.Dq Li 0x ) ,
+the letters
+.Dq Li ABCDEF
+(rather than
+.Dq Li abcdef )
+to represent the hex digits, and the letter
+.Ql P
+(rather than
+.Ql p )
+to separate the mantissa and exponent.
+.Pp
+Note that there may be multiple valid ways to represent floating-point
+numbers in this hexadecimal format.
+For example,
+.Li 0x1.92p+1 , 0x3.24p+0 , 0x6.48p-1 ,
+and
+.Li 0xc.9p-2
+are all equivalent.
+.Fx 8.0
+and later always prints finite non-zero numbers using
+.Ql 1
+as the digit before the hexadecimal point.
+Zeroes are always represented with a mantissa of 0 (preceded by a
+.Ql -
+if appropriate) and an exponent of
+.Li +0 .
 .It Cm C
 Treated as
 .Cm c
@@ -724,6 +791,57 @@ for later interpolation by
 Always use the proper secure idiom:
 .Pp
 .Dl "snprintf(buffer, sizeof(buffer), \*q%s\*q, string);"
+.Sh COMPATIBILITY
+Many application writers used the name
+.Va dprintf
+before the
+.Fn dprintf
+function was introduced in
+.St -p1003.1 ,
+so a prototype is not provided by default in order to avoid
+compatibility problems.
+Applications that wish to use the
+.Fn dprintf
+function described herein should either request a strict
+.St -p1003.1-2008
+environment by defining the macro
+.Dv _POSIX_C_SOURCE
+to the value 200809 or greater, or by defining the macro
+.Dv _WITH_DPRINTF ,
+prior to the inclusion of
+.In stdio.h .
+For compatibility with GNU libc, defining either
+.Dv _BSD_SOURCE
+or
+.Dv _GNU_SOURCE
+prior to the inclusion of
+.In stdio.h
+will also make
+.Fn dprintf
+available.
+.Pp
+The conversion formats
+.Cm \&%D , \&%O ,
+and
+.Cm %U
+are not standard and
+are provided only for backward compatibility.
+The effect of padding the
+.Cm %p
+format with zeros (either by the
+.Cm 0
+flag or by specifying a precision), and the benign effect (i.e., none)
+of the
+.Cm #
+flag on
+.Cm %n
+and
+.Cm %p
+conversions, as well as other
+nonsensical combinations such as
+.Cm %Ld ,
+are not standard; such combinations
+should be avoided.
 .Sh ERRORS
 In addition to the errors documented for the
 .Xr write 2
@@ -763,7 +881,13 @@ With the same reservation, the
 and
 .Fn vsnprintf
 functions conform to
-.St -isoC-99 .
+.St -isoC-99 ,
+while
+.Fn dprintf
+and
+.Fn vdprintf
+conform to
+.St -p1003.1-2008 .
 .Sh HISTORY
 The functions
 .Fn asprintf
@@ -781,30 +905,13 @@ from
 .An Todd C. Miller Aq Todd.Miller@courtesan.com
 for
 .Ox 2.3 .
-.Sh BUGS
-The conversion formats
-.Cm \&%D , \&%O ,
-and
-.Cm %U
-are not standard and
-are provided only for backward compatibility.
-The effect of padding the
-.Cm %p
-format with zeros (either by the
-.Cm 0
-flag or by specifying a precision), and the benign effect (i.e., none)
-of the
-.Cm #
-flag on
-.Cm %n
+The
+.Fn dprintf
 and
-.Cm %p
-conversions, as well as other
-nonsensical combinations such as
-.Cm %Ld ,
-are not standard; such combinations
-should be avoided.
-.Pp
+.Fn vdprintf
+functions were added in
+.Fx 8.0 .
+.Sh BUGS
 The
 .Nm
 family of functions do not correctly handle multibyte characters in the
index 3bd8d0c..84f834a 100644 (file)
  * 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.
@@ -34,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)printf.c        8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/printf.c,v 1.6 1999/08/28 00:01:11 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/printf.c,v 1.11 2007/01/09 00:28:07 imp Exp $
  * $DragonFly: src/lib/libc/stdio/printf.c,v 1.3 2004/06/07 20:35:41 hmp Exp $
  */
 
@@ -42,7 +38,7 @@
 #include <stdarg.h>
 
 int
-printf(char const *fmt, ...)
+printf(const char * __restrict fmt, ...)
 {
        int ret;
        va_list ap;
diff --git a/lib/libc/stdio/printfcommon.h b/lib/libc/stdio/printfcommon.h
new file mode 100644 (file)
index 0000000..c41b892
--- /dev/null
@@ -0,0 +1,301 @@
+/*-
+ * 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.
+ * 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.
+ *
+ * $FreeBSD: src/lib/libc/stdio/printfcommon.h,v 1.4 2009/01/22 08:14:28 das Exp $
+ */
+
+/*
+ * This file defines common routines used by both printf and wprintf.
+ * You must define CHAR to either char or wchar_t prior to including this.
+ */
+
+
+#ifndef NO_FLOATING_POINT
+
+#define        dtoa            __dtoa
+#define        freedtoa        __freedtoa
+
+#include <float.h>
+#include <math.h>
+#include "floatio.h"
+#include "gdtoa.h"
+
+#define        DEFPREC         6
+
+static int exponent(CHAR *, int, CHAR);
+
+#endif /* !NO_FLOATING_POINT */
+
+static CHAR    *__ujtoa(uintmax_t, CHAR *, int, int, const char *);
+static CHAR    *__ultoa(u_long, CHAR *, int, int, const char *);
+
+#define NIOV 8
+struct io_state {
+       FILE *fp;
+       struct __suio uio;      /* output information: summary */
+       struct __siov iov[NIOV];/* ... and individual io vectors */
+};
+
+static inline void
+io_init(struct io_state *iop, FILE *fp)
+{
+
+       iop->uio.uio_iov = iop->iov;
+       iop->uio.uio_resid = 0;
+       iop->uio.uio_iovcnt = 0;
+       iop->fp = fp;
+}
+
+/*
+ * WARNING: The buffer passed to io_print() is not copied immediately; it must
+ * remain valid until io_flush() is called.
+ */
+static inline int
+io_print(struct io_state *iop, const CHAR * __restrict ptr, int len)
+{
+
+       iop->iov[iop->uio.uio_iovcnt].iov_base = __DECONST(char *, ptr);
+       iop->iov[iop->uio.uio_iovcnt].iov_len = len;
+       iop->uio.uio_resid += len;
+       if (++iop->uio.uio_iovcnt >= NIOV)
+               return (__sprint(iop->fp, &iop->uio));
+       else
+               return (0);
+}
+
+/*
+ * Choose PADSIZE to trade efficiency vs. size.  If larger printf
+ * fields occur frequently, increase PADSIZE and make the initialisers
+ * below longer.
+ */
+#define        PADSIZE 16              /* pad chunk size */
+static const CHAR blanks[PADSIZE] =
+{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
+static const CHAR zeroes[PADSIZE] =
+{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
+
+/*
+ * Pad with blanks or zeroes. 'with' should point to either the blanks array
+ * or the zeroes array.
+ */
+static inline int
+io_pad(struct io_state *iop, int howmany, const CHAR * __restrict with)
+{
+       int n;
+
+       while (howmany > 0) {
+               n = (howmany >= PADSIZE) ? PADSIZE : howmany;
+               if (io_print(iop, with, n))
+                       return (-1);
+               howmany -= n;
+       }
+       return (0);
+}
+
+/*
+ * Print exactly len characters of the string spanning p to ep, truncating
+ * or padding with 'with' as necessary.
+ */
+static inline int
+io_printandpad(struct io_state *iop, const CHAR *p, const CHAR *ep,
+              int len, const CHAR * __restrict with)
+{
+       int p_len;
+
+       p_len = ep - p;
+       if (p_len > len)
+               p_len = len;
+       if (p_len > 0) {
+               if (io_print(iop, p, p_len))
+                       return (-1);
+       } else {
+               p_len = 0;
+       }
+       return (io_pad(iop, len - p_len, with));
+}
+
+static inline int
+io_flush(struct io_state *iop)
+{
+
+       return (__sprint(iop->fp, &iop->uio));
+}
+
+/*
+ * Convert an unsigned long to ASCII for printf purposes, returning
+ * a pointer to the first character of the string representation.
+ * Octal numbers can be forced to have a leading zero; hex numbers
+ * use the given digits.
+ */
+static CHAR *
+__ultoa(u_long val, CHAR *endp, int base, int octzero, const char *xdigs)
+{
+       CHAR *cp = endp;
+       long sval;
+
+       /*
+        * Handle the three cases separately, in the hope of getting
+        * better/faster code.
+        */
+       switch (base) {
+       case 10:
+               if (val < 10) { /* many numbers are 1 digit */
+                       *--cp = to_char(val);
+                       return (cp);
+               }
+               /*
+                * On many machines, unsigned arithmetic is harder than
+                * signed arithmetic, so we do at most one unsigned mod and
+                * divide; this is sufficient to reduce the range of
+                * the incoming value to where signed arithmetic works.
+                */
+               if (val > LONG_MAX) {
+                       *--cp = to_char(val % 10);
+                       sval = val / 10;
+               } else
+                       sval = val;
+               do {
+                       *--cp = to_char(sval % 10);
+                       sval /= 10;
+               } while (sval != 0);
+               break;
+
+       case 8:
+               do {
+                       *--cp = to_char(val & 7);
+                       val >>= 3;
+               } while (val);
+               if (octzero && *cp != '0')
+                       *--cp = '0';
+               break;
+
+       case 16:
+               do {
+                       *--cp = xdigs[val & 15];
+                       val >>= 4;
+               } while (val);
+               break;
+
+       default:                        /* oops */
+               abort();
+       }
+       return (cp);
+}
+
+/* Identical to __ultoa, but for intmax_t. */
+static CHAR *
+__ujtoa(uintmax_t val, CHAR *endp, int base, int octzero, const char *xdigs)
+{
+       CHAR *cp = endp;
+       intmax_t sval;
+
+       /* quick test for small values; __ultoa is typically much faster */
+       /* (perhaps instead we should run until small, then call __ultoa?) */
+       if (val <= ULONG_MAX)
+               return (__ultoa((u_long)val, endp, base, octzero, xdigs));
+       switch (base) {
+       case 10:
+               if (val < 10) {
+                       *--cp = to_char(val % 10);
+                       return (cp);
+               }
+               if (val > INTMAX_MAX) {
+                       *--cp = to_char(val % 10);
+                       sval = val / 10;
+               } else
+                       sval = val;
+               do {
+                       *--cp = to_char(sval % 10);
+                       sval /= 10;
+               } while (sval != 0);
+               break;
+
+       case 8:
+               do {
+                       *--cp = to_char(val & 7);
+                       val >>= 3;
+               } while (val);
+               if (octzero && *cp != '0')
+                       *--cp = '0';
+               break;
+
+       case 16:
+               do {
+                       *--cp = xdigs[val & 15];
+                       val >>= 4;
+               } while (val);
+               break;
+
+       default:
+               abort();
+       }
+       return (cp);
+}
+
+#ifndef NO_FLOATING_POINT
+
+static int
+exponent(CHAR *p0, int exp, CHAR fmtch)
+{
+       CHAR *p, *t;
+       CHAR expbuf[MAXEXPDIG];
+
+       p = p0;
+       *p++ = fmtch;
+       if (exp < 0) {
+               exp = -exp;
+               *p++ = '-';
+       }
+       else
+               *p++ = '+';
+       t = expbuf + MAXEXPDIG;
+       if (exp > 9) {
+               do {
+                       *--t = to_char(exp % 10);
+               } while ((exp /= 10) > 9);
+               *--t = to_char(exp);
+               for (; t < expbuf + MAXEXPDIG; *p++ = *t++);
+       }
+       else {
+               /*
+                * Exponents for decimal floating point conversions
+                * (%[eEgG]) must be at least two characters long,
+                * whereas exponents for hexadecimal conversions can
+                * be only one character long.
+                */
+               if (fmtch == 'e' || fmtch == 'E')
+                       *p++ = '0';
+               *p++ = to_char(exp);
+       }
+       return (p - p0);
+}
+
+#endif /* !NO_FLOATING_POINT */
similarity index 50%
copy from lib/libc/stdio/putchar.c
copy to lib/libc/stdio/printflocal.h
index aa84b08..ca7e05d 100644 (file)
  * 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.
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * @(#)putchar.c       8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/putchar.c,v 1.7 1999/08/28 00:01:12 peter Exp $
- * $DragonFly: src/lib/libc/stdio/putchar.c,v 1.6 2005/08/27 21:35:01 joerg Exp $
+ * $FreeBSD: src/lib/libc/stdio/printflocal.h,v 1.3 2009/03/02 04:07:58 das Exp $
  */
 
-#include "namespace.h"
-#include <stdio.h>
-#include "un-namespace.h"
-#include "libc_private.h"
-
-#undef putchar_unlocked
-
 /*
- * putchar has traditionally been a macro in <stdio.h>.  That is no
- * longer true because POSIX requires it to be thread-safe.  POSIX
- * does define putchar_unlocked() which is defined as a macro and is
- * probably what you want to use instead.
+ * Flags used during conversion.
  */
+#define        ALT             0x001           /* alternate form */
+#define        LADJUST         0x004           /* left adjustment */
+#define        LONGDBL         0x008           /* long double */
+#define        LONGINT         0x010           /* long integer */
+#define        LLONGINT        0x020           /* long long integer */
+#define        SHORTINT        0x040           /* short integer */
+#define        ZEROPAD         0x080           /* zero (as opposed to blank) pad */
+#define        FPT             0x100           /* Floating point number */
+#define        GROUPING        0x200           /* use grouping ("'" flag) */
+                                       /* C99 additional size modifiers: */
+#define        SIZET           0x400           /* size_t */
+#define        PTRDIFFT        0x800           /* ptrdiff_t */
+#define        INTMAXT         0x1000          /* intmax_t */
+#define        CHARINT         0x2000          /* print char using int format */
 
 /*
- * A subroutine version of the macros putchar and putchar_unlocked.
+ * Macros for converting digits to letters and vice versa
  */
-int
-putchar(int c)
-{
-       return(putc(c, stdout));
-}
+#define        to_digit(c)     ((c) - '0')
+#define is_digit(c)    ((unsigned)to_digit(c) <= 9)
+#define        to_char(n)      ((n) + '0')
+
+/* Size of the static argument table. */
+#define STATIC_ARG_TBL_SIZE 8
+
+union arg {
+       int     intarg;
+       u_int   uintarg;
+       long    longarg;
+       u_long  ulongarg;
+       long long longlongarg;
+       unsigned long long ulonglongarg;
+       ptrdiff_t ptrdiffarg;
+       size_t  sizearg;
+       intmax_t intmaxarg;
+       uintmax_t uintmaxarg;
+       void    *pvoidarg;
+       char    *pchararg;
+       signed char *pschararg;
+       short   *pshortarg;
+       int     *pintarg;
+       long    *plongarg;
+       long long *plonglongarg;
+       ptrdiff_t *pptrdiffarg;
+       ssize_t *pssizearg;
+       intmax_t *pintmaxarg;
+#ifndef NO_FLOATING_POINT
+       double  doublearg;
+       long double longdoublearg;
+#endif
+       wint_t  wintarg;
+       wchar_t *pwchararg;
+};
 
-int
-putchar_unlocked(int c)
-{
-       return(putc_unlocked(c, stdout));
-}
+/* Handle positional parameters. */
+int    __find_arguments(const char *, va_list, union arg **);
+int    __find_warguments(const wchar_t *, va_list, union arg **);
index 8b99a54..de4e672 100644 (file)
 
 #include "wcio.h"
 
+/*
+ * 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;
@@ -60,10 +66,10 @@ struct __FILE {
 
        /* operations */
        void    *_cookie;       /* cookie passed to io functions */
-       int     (*_close) (void *);
-       int     (*_read)  (void *, char *, int);
-       fpos_t  (*_seek)  (void *, fpos_t, int);
-       int     (*_write) (void *, const char *, int);
+       int     (*_close)(void *);
+       int     (*_read)(void *, char *, int);
+       fpos_t  (*_seek)(void *, fpos_t, int);
+       int     (*_write)(void *, const char *, int);
 
        /* separate buffer for long sequences of ungetc() */
        struct  __sbuf _ub;     /* ungetc buffer */
@@ -81,9 +87,9 @@ struct __FILE {
        fpos_t  _offset;        /* current lseek offset (see WARNING) */
 
        unsigned char   *_up;   /* saved _p when _p is doing ungetc data */
-       pthread_mutex_t fl_mutex;       /* used for MT-safety */
-       pthread_t       fl_owner;       /* current owner */
-       int             fl_count;       /* recursive lock count */
+       pthread_mutex_t _fl_mutex;      /* used for MT-safety */
+       pthread_t       _fl_owner;      /* current owner */
+       int             _fl_count;      /* recursive lock count */
 
        struct wchar_io_data _wcio;
 };
index 99e7c27..07c7be6 100644 (file)
 .\" 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.
@@ -34,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)putc.3     8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdio/putc.3,v 1.5.2.3 2001/12/14 18:33:57 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdio/putc.3,v 1.16 2007/01/09 00:28:07 imp Exp $
 .\" $DragonFly: src/lib/libc/stdio/putc.3,v 1.2 2003/06/17 04:26:46 dillon Exp $
 .\"
 .Dd March 22, 2009
@@ -76,8 +72,14 @@ to the output stream pointed to by
 .Pp
 The
 .Fn putc
-function acts essentially identically to
-.Fn fputc .
+macro acts essentially identically to
+.Fn fputc ,
+but is a macro that expands in-line.
+It may evaluate
+.Fa stream
+more than once, so arguments given to
+.Fn putc
+should not be expressions with potential side effects.
 .Pp
 The
 .Fn putchar
@@ -85,13 +87,13 @@ function
 is identical to
 .Fn putc
 with an output stream of
-.Em stdout .
+.Dv stdout .
 .Pp
 The
 .Fn putw
 function
 writes the specified
-.Em int
+.Vt int
 to the named output
 .Fa stream .
 .Pp
@@ -106,7 +108,7 @@ and
 respectively,
 except that the caller is responsible for locking the stream
 with
-.Fn flockfile
+.Xr flockfile 3
 before calling them.
 These functions may be used to avoid the overhead of locking the stream
 for each character, and to avoid output being interspersed from multiple
@@ -136,6 +138,7 @@ or if an attempt is made to write a read-only stream.
 .Xr flockfile 3 ,
 .Xr fopen 3 ,
 .Xr getc 3 ,
+.Xr putwc 3 ,
 .Xr stdio 3
 .Sh STANDARDS
 The functions
@@ -151,13 +154,13 @@ and
 .Fn putchar_unlocked
 functions conform to
 .St -p1003.1-2001 .
-A
+A function
 .Fn putw
 function appeared in
 .At v6 .
 .Sh BUGS
 The size and byte order of an
-.Em int
+.Vt int
 varies from one machine to another, and
 .Fn putw
 is not recommended for portable applications.
index 490724b..46b4ca0 100644 (file)
  * 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.
  * SUCH DAMAGE.
  *
  * @(#)putc.c  8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/putc.c,v 1.7 1999/08/28 00:01:12 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/putc.c,v 1.16 2008/05/05 16:03:52 jhb Exp $
  * $DragonFly: src/lib/libc/stdio/putc.c,v 1.7 2005/11/20 11:07:30 swildner Exp $
  */
 
 #include "namespace.h"
 #include <stdio.h>
 #include "un-namespace.h"
+#include "local.h"
 #include "libc_private.h"
 
+#undef putc
 #undef putc_unlocked
 
-/*
- * putc has traditionally been a macro in <stdio.h>.  That is no
- * longer true because POSIX requires it to be thread-safe.  POSIX
- * does define putc_unlocked() which is defined as a macro and is
- * probably what you want to use instead.
- */
 int
 putc(int c, FILE *fp)
 {
@@ -62,7 +54,8 @@ putc(int c, FILE *fp)
 }
 
 int
-putc_unlocked(int c, FILE *fp)
+putc_unlocked(int ch, FILE *fp)
 {
-       return(__sputc(c, fp));
+
+       return (__sputc(ch, fp));
 }
index aa84b08..a2ce7b0 100644 (file)
  * 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.
  * SUCH DAMAGE.
  *
  * @(#)putchar.c       8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/putchar.c,v 1.7 1999/08/28 00:01:12 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/putchar.c,v 1.16 2008/05/05 16:03:52 jhb Exp $
  * $DragonFly: src/lib/libc/stdio/putchar.c,v 1.6 2005/08/27 21:35:01 joerg Exp $
  */
 
 #include "namespace.h"
 #include <stdio.h>
 #include "un-namespace.h"
+#include "local.h"
 #include "libc_private.h"
 
+#undef putchar
 #undef putchar_unlocked
 
 /*
- * putchar has traditionally been a macro in <stdio.h>.  That is no
- * longer true because POSIX requires it to be thread-safe.  POSIX
- * does define putchar_unlocked() which is defined as a macro and is
- * probably what you want to use instead.
- */
-
-/*
- * A subroutine version of the macros putchar and putchar_unlocked.
+ * A subroutine version of the macro putchar
  */
 int
 putchar(int c)
 {
-       return(putc(c, stdout));
+       int retval;
+       FILE *so = stdout;
+
+       FLOCKFILE(so);
+       retval = __sputc(c, so);
+       FUNLOCKFILE(so);
+       return (retval);
 }
 
 int
-putchar_unlocked(int c)
+putchar_unlocked(int ch)
 {
-       return(putc_unlocked(c, stdout));
+
+       return (__sputc(ch, stdout));
 }
index dc93ae8..383db88 100644 (file)
  * 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.
  * SUCH DAMAGE.
  *
  * @(#)puts.c  8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/puts.c,v 1.7 1999/08/28 00:01:12 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/puts.c,v 1.11 2007/01/09 00:28:07 imp Exp $
  * $DragonFly: src/lib/libc/stdio/puts.c,v 1.5 2005/07/23 20:23:06 joerg Exp $
  */
 
 #include "namespace.h"
-#include <sys/types.h>
 #include <stdio.h>
 #include <string.h>
 #include "un-namespace.h"
 #include "priv_stdio.h"
 #include "libc_private.h"
+#include "local.h"
 
 /*
  * Write the given string to stdout, appending a newline.
  */
 int
-puts(char const *s)
+puts(const char *s)
 {
        int retval;
        size_t c = strlen(s);
@@ -65,6 +61,7 @@ puts(char const *s)
        uio.uio_iov = &iov[0];
        uio.uio_iovcnt = 2;
        FLOCKFILE(stdout);
+       ORIENT(stdout, -1);
        retval = __sfvwrite(stdout, &uio) ? EOF : '\n';
        FUNLOCKFILE(stdout);
        return (retval);
index 9d4c29d..6ae63d3 100644 (file)
  * 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.
@@ -34,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * @(#)putw.c  8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/lib/libc/stdio/putw.c,v 1.7 1999/08/28 00:01:13 peter Exp $
+ * $FreeBSD: src/lib/libc/stdio/putw.c,v 1.10 2007/01/09 00:28:07 imp Exp $
  * $DragonFly: src/lib/libc/stdio/putw.c,v 1.5 2005/07/23 20:23:06 joerg Exp $
  */
 
index 94e9e6f..94b2d6c 100644 (file)
@@ -1,5 +1,4 @@
-.\"    $NetBSD: putwc.3,v 1.8 2004/01/24 16:59:30 wiz Exp $
-.\"    $DragonFly: src/lib/libc/stdio/putwc.3,v 1.1 2005/07/25 00:37:41 joerg Exp $
+.\"    $NetBSD: putwc.3,v 1.2 2002/02/07 07:00:26 ross Exp $
 .\"
 .\" Copyright (c) 1990, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -16,7 +15,7 @@
 .\" 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. Neither the name of the University nor the names of 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.
 .\"
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)putc.3     8.1 (Berkeley) 6/4/93
+.\" $FreeBSD: src/lib/libc/stdio/putwc.3,v 1.8 2007/01/09 00:28:07 imp Exp $
+.\" $DragonFly: src/lib/libc/stdio/putwc.3,v 1.1 2005/07/25 00:37:41 joerg Exp $
 .\"
-.Dd October 20, 2001
+.Dd March 3, 2004
 .Dt PUTWC 3
 .Os
 .Sh NAME
 .Nm fputwc ,
 .Nm putwc ,
-.Nm putwchar ,
-.Nd output a wide-character to a stream
+.Nm putwchar
+.Nd output a wide character to a stream
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
 The
 .Fn fputwc
 function
-writes the wide-character
+writes the wide character
 .Fa wc
 to the output stream pointed to by
 .Fa stream .
 .Pp
+The
 .Fn putwc
+function
 acts essentially identically to
-.Fn fputwc ,
-but is a macro that expands in-line.
-It may evaluate
-.Fa stream
-more than once, so arguments given to
-.Fn putwc
-should not be expressions with potential side effects.
+.Fn fputwc .
 .Pp
+The
 .Fn putwchar
+function
 is identical to
 .Fn putwc
 with an output stream of
-.Em stdout .
+.Dv stdout .
 .Sh RETURN VALUES
-The functions
+The
 .Fn fputwc ,
 .Fn putwc ,
 and
 .Fn putwchar
-return the wide-character written.
+functions
+return the wide character written.
 If an error occurs, the value
 .Dv WEOF
 is returned.
@@ -91,12 +91,14 @@ is returned.
 .Xr ferror 3 ,
 .Xr fopen 3 ,
 .Xr getwc 3 ,
+.Xr putc 3 ,
 .Xr stdio 3
 .Sh STANDARDS
-The functions
+The
 .Fn fputwc ,
 .Fn putwc ,
 and
-.Fn putwchar ,
+.Fn putwchar
+functions
 conform to
 .St -isoC-99 .
index 06e262c..6c0aebf 100644 (file)
@@ -1,8 +1,5 @@
-/* $NetBSD: putwc.c,v 1.4 2005/06/12 05:21:27 lukem Exp $ */
-/* $DragonFly: src/lib/libc/stdio/putwc.c,v 1.1 2005/07/25 00:37:41 joerg Exp $ */
-
 /*-
- * Copyright (c)2001 Citrus Project,
+ * Copyright (c) 2002 Tim J. Robbins.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Citrus$
+ * $FreeBSD: src/lib/libc/stdio/putwc.c,v 1.3 2004/05/25 10:42:52 tjr Exp $
+ * $DragonFly: src/lib/libc/stdio/putwc.c,v 1.1 2005/07/25 00:37:41 joerg Exp $
  */
 
+#include "namespace.h"
 #include <stdio.h>
 #include <wchar.h>
+#include "un-namespace.h"
+#include "libc_private.h"
+#include "local.h"
 
-/*
- * A subroutine version of the macro putwc.
- */
 #undef putwc
 
+/*
+ * Synonym for fputwc(). The only difference is that putwc(), if it is a
+ * macro, may evaluate `fp' more than once.
+ */
 wint_t
 putwc(wchar_t wc, FILE *fp)
 {
 
-       return fputwc(wc, fp);
+       return (fputwc(wc, fp));
 }
index 6f2f2d4..038a14e 100644 (file)
@@ -1,8 +1,5 @@
-/* $NetBSD: putwchar.c,v 1.4 2005/06/12 05:21:27 lukem Exp $ */
-/* $DragonFly: src/lib/libc/stdio/putwchar.c,v 1.1 2005/07/25 00:37:41 joerg Exp $ */
-
 /*-
- * Copyright (c)2001 Citrus Project,
+ * Copyright (c) 2002 Tim J. Robbins.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Citrus$
+ * $FreeBSD: src/lib/libc/stdio/putwchar.c,v 1.3 2004/05/25 10:42:52 tjr Exp $
+ * $DragonFly: src/lib/libc/stdio/putwchar.c,v 1.1 2005/07/25 00:37:41 joerg Exp $
  */
 
+#include "namespace.h"
 #include <stdio.h>
 #include <wchar.h>
+#include "un-namespace.h"
+#include "libc_private.h"
+#include "local.h"
 
-/*
- * A subroutine version of the macro putwchar.
- */
 #undef putwchar
 
+/*
+ * Synonym for fputwc(wc, stdout).
+ */
 wint_t
 putwchar(wchar_t wc)
 {
 
-       return fputwc(wc, stdout);
+       return (fputwc(wc, stdout));
 }