From 7c713e287e50dc338779ed1a6c6ac701720a3a41 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 9 May 1996 00:37:21 +0000 Subject: Wed May 8 20:04:29 1996 Roland McGrath * Rules (subdir_install): Depend on $(common-objpfx)sor-$(subdir). [! libc.so-version]: Clear static-only-routines. ($(common-objpfx)sor-$(subdir)): New target. [static-only-routines]: New static pattern rule for these .so's. * Makerules [libc.so-version] ($(slibdir)/libc.so): Target removed. [libc.so-version] ($(libdir)/libc.so, $(common-objpfx)libc-syms.so): New targets replace it. (install) [libc.so-version]: Depend on $(libdir)/libc.so instead of $(slibdir)/libc.so. * io/Makefile (static-only-routines): New variable. * configure.in: Check for tools objdump and objcopy, and for awk. * config.make.in (OBJDUMP, OBJCOPY, AWK): New variables. Thu May 9 01:24:00 1996 Ulrich Drepper * locale/programs/config.h: Remove definition of wint_t. * locale/programs/ld-collate.c: Include instead of . * manual/time.texi: Add some more description for %U and %W format of strftime. Describe new format %V of strftime. * resolv/gethnamaddr.c: Prevent warning by preventing variable definition. * stdio-common/_itoa.c: Ditto. Tue May 7 23:43:07 1996 Ulrich Drepper * libio/clearerr.c, libio/feof.c, libio/ferror.c, libio/fgetc.c, libio/fileno.c, libio/fputc.c, libio/freopen.c, libio/fseek.c, libio/genops.c, libio/getc.c, libio/getchar.c, libio/iofclose.c, libio/iofflush.c, libio/iofgetpos.c, libio/iofgets.c, libio/iofputs.c, libio/iofread.c, libio/iofsetpos.c, libio/ioftell.c, libio/iofwrite.c, libio/iogetdelim.c, libio/iogets.c, libio/ioputs.c, libio/iosetbuffer.c, libio/iosetvbuf.c, libio/ioungetc.c, libio/iovsprintf.c, libio/libio.h, libio/putc.c, libio/putchar.c, libio/rewind.c, libio/stdio.h, stdio-common/printf_fp.c, stdio-common/vfprintf.c, stdio-common/vfscanf.c: Prepare for reentrent libio. * libio/clearerr_u.c, libio/feof_u.c, libio/ferror_u.c, libio/fputc_u.c, libio/getc_u.c, libio/getchar_u.c, libio/iofflush_u.c, libio/putc_u.c, libio/putchar_u.c: New files. Used in reentrent libio. * misc/getusershell.c: Prevent warnings. --- ChangeLog | 50 ++++++++++++++++++++++++++ Makerules | 22 ++++++++++-- Rules | 28 ++++++++++++++- config.make.in | 3 ++ configure.in | 5 ++- io/Makefile | 5 +++ libio/clearerr.c | 32 ++++++++++++++--- libio/clearerr_u.c | 30 ++++++++++++++++ libio/feof.c | 21 ++++++++--- libio/feof_u.c | 33 +++++++++++++++++ libio/ferror.c | 14 ++++++-- libio/ferror_u.c | 33 +++++++++++++++++ libio/fgetc.c | 6 +++- libio/fileno.c | 11 +++++- libio/fputc.c | 8 +++-- libio/fputc_u.c | 39 ++++++++++++++++++++ libio/freopen.c | 8 +++-- libio/fseek.c | 6 +++- libio/genops.c | 7 ++++ libio/getc.c | 19 +++++++--- libio/getc_u.c | 38 ++++++++++++++++++++ libio/getchar.c | 14 ++++++-- libio/getchar_u.c | 36 +++++++++++++++++++ libio/iofclose.c | 2 ++ libio/iofflush.c | 10 +++++- libio/iofflush_u.c | 41 +++++++++++++++++++++ libio/iofgetpos.c | 2 ++ libio/iofgets.c | 13 +++++-- libio/iofputs.c | 13 ++++--- libio/iofread.c | 2 ++ libio/iofsetpos.c | 9 +++-- libio/ioftell.c | 2 ++ libio/iofwrite.c | 2 ++ libio/iogetdelim.c | 30 ++++++++++++---- libio/iogets.c | 6 +++- libio/ioputs.c | 16 +++++---- libio/iosetbuffer.c | 6 +++- libio/iosetvbuf.c | 23 +++++++++--- libio/ioungetc.c | 8 +++-- libio/iovsprintf.c | 2 +- libio/libio.h | 38 ++++++++++++-------- libio/putc.c | 19 +++++++--- libio/putc_u.c | 31 ++++++++++++++++ libio/putchar.c | 14 ++++++-- libio/putchar_u.c | 30 ++++++++++++++++ libio/rewind.c | 2 ++ libio/stdio.h | 47 +++++++++++++++++++++--- locale/programs/config.h | 3 -- locale/programs/ld-collate.c | 4 +-- manual/time.texi | 13 +++++-- misc/getusershell.c | 20 +++++------ resolv/gethnamaddr.c | 5 ++- stdio-common/_itoa.c | 6 ++-- stdio-common/printf_fp.c | 2 +- stdio-common/vfprintf.c | 38 +++++++++++++++----- stdio-common/vfscanf.c | 85 +++++++++++++++++++++++++++++--------------- 56 files changed, 866 insertions(+), 146 deletions(-) create mode 100644 libio/clearerr_u.c create mode 100644 libio/feof_u.c create mode 100644 libio/ferror_u.c create mode 100644 libio/fputc_u.c create mode 100644 libio/getc_u.c create mode 100644 libio/getchar_u.c create mode 100644 libio/iofflush_u.c create mode 100644 libio/putc_u.c create mode 100644 libio/putchar_u.c diff --git a/ChangeLog b/ChangeLog index 2e42e869e6..1609c71eed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,53 @@ +Wed May 8 20:04:29 1996 Roland McGrath + + * Rules (subdir_install): Depend on $(common-objpfx)sor-$(subdir). + [! libc.so-version]: Clear static-only-routines. + ($(common-objpfx)sor-$(subdir)): New target. + [static-only-routines]: New static pattern rule for these .so's. + * Makerules [libc.so-version] ($(slibdir)/libc.so): Target removed. + [libc.so-version] ($(libdir)/libc.so, $(common-objpfx)libc-syms.so): + New targets replace it. + (install) [libc.so-version]: Depend on $(libdir)/libc.so instead of + $(slibdir)/libc.so. + * io/Makefile (static-only-routines): New variable. + * configure.in: Check for tools objdump and objcopy, and for awk. + * config.make.in (OBJDUMP, OBJCOPY, AWK): New variables. + +Thu May 9 01:24:00 1996 Ulrich Drepper + + * locale/programs/config.h: Remove definition of wint_t. + + * locale/programs/ld-collate.c: Include instead of + . + + * manual/time.texi: Add some more description for %U and %W + format of strftime. Describe new format %V of strftime. + + * resolv/gethnamaddr.c: Prevent warning by preventing variable + definition. + * stdio-common/_itoa.c: Ditto. + +Tue May 7 23:43:07 1996 Ulrich Drepper + + * libio/clearerr.c, libio/feof.c, libio/ferror.c, libio/fgetc.c, + libio/fileno.c, libio/fputc.c, libio/freopen.c, libio/fseek.c, + libio/genops.c, libio/getc.c, libio/getchar.c, libio/iofclose.c, + libio/iofflush.c, libio/iofgetpos.c, libio/iofgets.c, + libio/iofputs.c, libio/iofread.c, libio/iofsetpos.c, + libio/ioftell.c, libio/iofwrite.c, libio/iogetdelim.c, + libio/iogets.c, libio/ioputs.c, libio/iosetbuffer.c, + libio/iosetvbuf.c, libio/ioungetc.c, libio/iovsprintf.c, + libio/libio.h, libio/putc.c, libio/putchar.c, libio/rewind.c, + libio/stdio.h, stdio-common/printf_fp.c, stdio-common/vfprintf.c, + stdio-common/vfscanf.c: Prepare for reentrent libio. + + * libio/clearerr_u.c, libio/feof_u.c, libio/ferror_u.c, + libio/fputc_u.c, libio/getc_u.c, libio/getchar_u.c, + libio/iofflush_u.c, libio/putc_u.c, libio/putchar_u.c: New files. + Used in reentrent libio. + + * misc/getusershell.c: Prevent warnings. + Wed May 8 12:08:35 1996 Roland McGrath * Makerules (install-lib.so rules): Undouble $s in target and dep diff --git a/Makerules b/Makerules index d206a6edca..6305ad753b 100644 --- a/Makerules +++ b/Makerules @@ -550,7 +550,6 @@ install-lib := $(filter-out %.so %_pic.a,$(install-lib)) ifeq (yes,$(build-shared)) install-lib-nosubdir: $(install-lib.so:%=$(libdir)/%) -install: $(slibdir)/libc.so # Find which .so's have versions. versioned := $(foreach so,$(install-lib.so),\ @@ -567,12 +566,29 @@ ifdef libc.so-version # libc.so -> libc.so.N (e.g. libc.so.6) # libc.so.6 -> libc-VERSION.so (e.g. libc-1.10.so) -$(slibdir)/libc.so: $(slibdir)/libc.so$(libc.so-version) - $(make-link) $(slibdir)/libc.so$(libc.so-version): $(slibdir)/libc-$(version).so $(make-link) $(slibdir)/libc-$(version).so: $(common-objpfx)libc.so; $(do-install-program) + +# What we install as libc.so for programs to link against is in fact an +# archive. It contains the various $(static-only-routines) objects, and +# the special object libc-syms.so that contains just the dynamic symbol +# table of the shared libc object. +install: $(libdir)/libc.so +$(libdir)/libc.so: $(common-objpfx)libc-syms.so subdir_install + $(AR) crvs $@ $< `cat $(addprefix $(common-objpfx)sor-,$(subdirs))` + +# Extract from the shared object file just the dynamic symbol table +# needed to link against the shared library. +$(common-objpfx)libc-syms.so: $(common-objpfx)libc.so + AWK='$(AWK)' OBJCOPY='$(OBJCOPY)' OBJDUMP='$(OBJDUMP)' \ + ./extract-dynsym $< $@ +ifndef subdir +generated += libc-syms.so +endif + else +install: $(slibdir)/libc.so $(slibdir)/libc.so: $(common-objpfx)libc.so; $(do-install-program) endif diff --git a/Rules b/Rules index 8d9d0a4695..9a7a505a30 100644 --- a/Rules +++ b/Rules @@ -122,7 +122,33 @@ subdir_echo-distinfo: # our portions of the library because the parent make will install it later # (likewise the stubs file). .PHONY: subdir_install -subdir_install: install-no-libc.a lib-noranlib stubs +subdir_install: install-no-libc.a lib-noranlib stubs \ + $(common-objpfx)sor-$(subdir) + +ifdef objpfx +sor-objpfx = $(objpfx:../%=%) +else +sor-objpfx = $(subdir) +endif + +ifndef libc.so-version +# Undefine this because it can't work when we libc.so is unversioned. +static-only-routines = +endif + +# This communicates to the parent during install the set of routines that +# need to be put into the special libc.so archive. +$(common-objpfx)sor-$(subdir): Makefile + echo $(static-only-routines:%=$(sor-objpfx)%.o) > $@T + mv -f $@T $@ + +ifdef static-only-routines +# These routines are to be omitted from the shared library object, +# so we replace the PIC objects for them with the dummy object file. +$(static-only-routines:%=$(objpfx)%.so): %.so: $(common-objpfx) dummy.so + rm -f $@ + ln $< $@ +endif .PHONY: subdir_TAGS subdir_dist subdir_TAGS: TAGS diff --git a/config.make.in b/config.make.in index 644e5edde5..a443050902 100644 --- a/config.make.in +++ b/config.make.in @@ -33,6 +33,9 @@ CC = @CC@ AR = @AR@ RANLIB = @RANLIB@ AS = $(CC) -c +OBJDUMP = @OBJDUMP@ +OBJCOPY = @OBJCOPY@ +AWK = @AWK@ # Installation tools. INSTALL = @INSTALL@ diff --git a/configure.in b/configure.in index ed288db410..d37e4d1c5b 100644 --- a/configure.in +++ b/configure.in @@ -301,9 +301,12 @@ AC_PROG_LN_S AC_CHECK_PROGS(MSGFMT, msgfmt gmsgfmt, :) AC_CHECK_TOOL(CC, gcc) +AC_PROG_CPP AC_CHECK_TOOL(AR, ar) AC_CHECK_TOOL(RANLIB, ranlib, :) -AC_PROG_CPP +AC_CHECK_TOOL(OBJDUMP, objdump) +AC_CHECK_TOOL(OBJCOPY, objcopy) +AC_PROG_AWK AC_CACHE_CHECK(for signed size_t type, libc_cv_signed_size_t, [dnl echo '#include diff --git a/io/Makefile b/io/Makefile index 691ac03041..ce8708c7ba 100644 --- a/io/Makefile +++ b/io/Makefile @@ -45,6 +45,11 @@ routines := \ unlink rmdir \ ftw fts poll +# These routines will be omitted from the libc shared object. +# Instead the static object files will be included in a special archive +# linked against when the shared library will be used. +static-only-routines = stat fstat lstat mknod + others := pwd tests := test-utime diff --git a/libio/clearerr.c b/libio/clearerr.c index ee9780bdaf..669a9b0d74 100644 --- a/libio/clearerr.c +++ b/libio/clearerr.c @@ -1,10 +1,34 @@ +/* Copyright (C) 1995, 1996 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + #include "libioP.h" #include "stdio.h" void -clearerr(fp) - FILE* fp; +clearerr (fp) + FILE *fp; { - CHECK_FILE(fp, /*nothing*/); - _IO_clearerr(fp); + CHECK_FILE (fp, /*nothing*/); + flockfile (fp); + _IO_clearerr (fp); + funlockfile (fp); } + +#ifdef _IO_MTSAFE_IO +weak_alias (clearerr, clearerr_locked) +#endif diff --git a/libio/clearerr_u.c b/libio/clearerr_u.c new file mode 100644 index 0000000000..83ed65d8b1 --- /dev/null +++ b/libio/clearerr_u.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1995, 1996 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "libioP.h" +#include "stdio.h" + +void +__clearerr_unlocked (fp) + FILE *fp; +{ + CHECK_FILE (fp, /*nothing*/); + _IO_clearerr (fp); +} + +weak_alias (clearerr_unlocked, __clearerr_unlocked) diff --git a/libio/feof.c b/libio/feof.c index bd30c175f3..9fb0008afb 100644 --- a/libio/feof.c +++ b/libio/feof.c @@ -1,5 +1,4 @@ -/* -Copyright (C) 1993 Free Software Foundation +/* Copyright (C) 1993, 1996 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the @@ -26,9 +25,21 @@ the executable file might be covered by the GNU General Public License. */ #include "stdio.h" int -feof(fp) +feof (fp) _IO_FILE* fp; { - CHECK_FILE(fp, EOF); - return _IO_feof(fp); + int result; + CHECK_FILE (fp, EOF); + _IO_flockfile (fp); + result = _IO_feof_unlocked (fp); + _IO_funlockfile (fp); + return result; } + +#ifdef _IO_MTSAFE_IO +/* The feof implementation for libio does not require locking because + it only accesses once a single variable and this is already atomic + (at least at thread level). */ + +weak_alias (feof, feof_locked) +#endif diff --git a/libio/feof_u.c b/libio/feof_u.c new file mode 100644 index 0000000000..5ce5583613 --- /dev/null +++ b/libio/feof_u.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1993, 1996 Free Software Foundation, Inc. + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +#include "libioP.h" +#include "stdio.h" + +int +feof_unlocked (fp) + _IO_FILE* fp; +{ + CHECK_FILE (fp, EOF); + return _IO_feof_unlocked (fp); +} diff --git a/libio/ferror.c b/libio/ferror.c index d0159818e8..32fd6d0dd9 100644 --- a/libio/ferror.c +++ b/libio/ferror.c @@ -1,5 +1,4 @@ -/* -Copyright (C) 1993, 1995 Free Software Foundation +/* Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the @@ -29,6 +28,15 @@ int ferror (fp) _IO_FILE* fp; { + int result; CHECK_FILE (fp, EOF); - return _IO_ferror (fp); + _IO_flockfile (fp); + result = _IO_ferror_unlocked (fp); + _IO_funlockfile (fp); + return result; } + +#ifdef _IO_MTSAFE_IO + +weak_alias (ferror, ferror_locked) +#endif diff --git a/libio/ferror_u.c b/libio/ferror_u.c new file mode 100644 index 0000000000..bee668d6d9 --- /dev/null +++ b/libio/ferror_u.c @@ -0,0 +1,33 @@ +/* Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +#include "libioP.h" +#include "stdio.h" + +int +ferror_unlocked (fp) + _IO_FILE* fp; +{ + CHECK_FILE (fp, EOF); + return _IO_ferror_unlocked (fp); +} diff --git a/libio/fgetc.c b/libio/fgetc.c index 19c0a589d9..2aaea05cfe 100644 --- a/libio/fgetc.c +++ b/libio/fgetc.c @@ -29,6 +29,10 @@ int fgetc (fp) FILE *fp; { + int result; CHECK_FILE (fp, EOF); - return _IO_getc (fp); + flockfile (fp); + result = _IO_getc_unlocked (fp); + funlockfile (fp); + return result; } diff --git a/libio/fileno.c b/libio/fileno.c index fbea4d4995..2dc67149c8 100644 --- a/libio/fileno.c +++ b/libio/fileno.c @@ -1,5 +1,5 @@ /* -Copyright (C) 1993, 1995 Free Software Foundation +Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the @@ -36,3 +36,12 @@ fileno (fp) return _IO_fileno (fp); } + +#ifdef _IO_MTSAFE_IO +/* The fileno implementation for libio does not require locking because + it only accesses once a single variable and this is already atomic + (at least at thread level). */ + +weak_alias (fileno_unlocked, fileno) +weak_alias (fileno_locked, fileno) +#endif diff --git a/libio/fputc.c b/libio/fputc.c index 2339139f72..339861119f 100644 --- a/libio/fputc.c +++ b/libio/fputc.c @@ -1,5 +1,5 @@ /* -Copyright (C) 1993 Free Software Foundation +Copyright (C) 1993, 1996 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the @@ -30,6 +30,10 @@ fputc (c, fp) int c; _IO_FILE *fp; { + int result; CHECK_FILE (fp, EOF); - return _IO_putc (c, fp); + _IO_flockfile (fp); + result = _IO_putc_unlocked (c, fp); + _IO_funlockfile (fp); + return result; } diff --git a/libio/fputc_u.c b/libio/fputc_u.c new file mode 100644 index 0000000000..211e206605 --- /dev/null +++ b/libio/fputc_u.c @@ -0,0 +1,39 @@ +/* +Copyright (C) 1993, 1996 Free Software Foundation, Inc. + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +#include "libioP.h" +#include "stdio.h" + +#undef fputc_unlocked + +int +__fputc_unlocked (c, fp) + int c; + _IO_FILE *fp; +{ + CHECK_FILE (fp, EOF); + return _IO_putc_unlocked (c, fp); +} + +weak_alias (fputc_unlocked, __fputc_unlocked) diff --git a/libio/freopen.c b/libio/freopen.c index 22fa13a697..829af31dc1 100644 --- a/libio/freopen.c +++ b/libio/freopen.c @@ -1,5 +1,5 @@ /* -Copyright (C) 1993, 1995 Free Software Foundation +Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the @@ -31,8 +31,12 @@ freopen (filename, mode, fp) const char* mode; FILE* fp; { + FILE *result; CHECK_FILE (fp, NULL); if (!(fp->_flags & _IO_IS_FILEBUF)) return NULL; - return _IO_freopen (filename, mode, fp); + flockfile (fp); + result = _IO_freopen (filename, mode, fp); + funlockfile (fp); + return result; } diff --git a/libio/fseek.c b/libio/fseek.c index 3afc4283e6..5255e9defe 100644 --- a/libio/fseek.c +++ b/libio/fseek.c @@ -31,6 +31,10 @@ fseek (fp, offset, whence) long int offset; int whence; { + int result; CHECK_FILE (fp, -1); - return _IO_fseek (fp, offset, whence); + flockfile (fp); + result = _IO_fseek (fp, offset, whence); + funlockfile (fp); + return result; } diff --git a/libio/genops.c b/libio/genops.c index 23a6fdeaea..e5bff7afed 100644 --- a/libio/genops.c +++ b/libio/genops.c @@ -465,6 +465,9 @@ DEFUN(_IO_init, (fp, flags), fp->_IO_save_end = NULL; fp->_markers = NULL; fp->_cur_column = 0; +#ifdef _IO_MTSAFE_IO + _IO_mutex_init (fp->_lock); +#endif } int @@ -497,6 +500,10 @@ DEFUN(_IO_default_finish, (fp), fp->_IO_save_base = NULL; } +#ifdef _IO_MTSAFE_IO + _IO_mutex_destroy (fp->_lock); +#endif + _IO_un_link(fp); } diff --git a/libio/getc.c b/libio/getc.c index 844bca4750..89abc0dac0 100644 --- a/libio/getc.c +++ b/libio/getc.c @@ -1,5 +1,5 @@ /* -Copyright (C) 1993, 1995 Free Software Foundation +Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the @@ -28,8 +28,19 @@ the executable file might be covered by the GNU General Public License. */ #undef getc int -getc (stream) - FILE *stream; +getc (fp) + FILE *fp; { - return _IO_getc (stream); + int result; + CHECK_FILE (fp, EOF); + _IO_flockfile (fp); + result = _IO_getc_unlocked (fp); + _IO_funlockfile (fp); + return result; } + +#ifdef _IO_MTSAFE_IO +# undef getc_locked + +weak_alias (getc_locked, getc) +#endif diff --git a/libio/getc_u.c b/libio/getc_u.c new file mode 100644 index 0000000000..e6491bb944 --- /dev/null +++ b/libio/getc_u.c @@ -0,0 +1,38 @@ +/* +Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +#include "libioP.h" +#include "stdio.h" + +#undef getc_unlocked + +int +__getc_unlocked (fp) + FILE *fp; +{ + CHECK_FILE (fp, EOF); + return _IO_getc_unlocked (fp); +} + +weak_alias (getc_unlocked, __getc_unlocked) diff --git a/libio/getchar.c b/libio/getchar.c index 875bceb83d..fa5c11f731 100644 --- a/libio/getchar.c +++ b/libio/getchar.c @@ -1,5 +1,5 @@ /* -Copyright (C) 1993 Free Software Foundation +Copyright (C) 1993, 1996 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the @@ -30,5 +30,15 @@ the executable file might be covered by the GNU General Public License. */ int getchar () { - return _IO_getc (stdin); + int result; + _IO_flockfile (stdin); + result = _IO_getc_unlocked (stdin); + _IO_funlockfile (stdin); + return result; } + +#ifdef _IO_MTSAFE_IO +# undef getchar_locked + +weak_alias (getchar_locked, getchar) +#endif diff --git a/libio/getchar_u.c b/libio/getchar_u.c new file mode 100644 index 0000000000..40cfbf6625 --- /dev/null +++ b/libio/getchar_u.c @@ -0,0 +1,36 @@ +/* +Copyright (C) 1993, 1996 Free Software Foundation, Inc. + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +#include "libioP.h" +#include "stdio.h" + +#undef getchar_unlocked + +int +__getchar_unlocked () +{ + return _IO_getc_unlocked (stdin); +} + +weak_alias (getchar_unlocked, __getchar_unlocked) diff --git a/libio/iofclose.c b/libio/iofclose.c index c797d86fd8..e5cae966fd 100644 --- a/libio/iofclose.c +++ b/libio/iofclose.c @@ -35,6 +35,7 @@ _IO_fclose (fp) CHECK_FILE(fp, EOF); + _IO_flockfile (fp); if (fp->_IO_file_flags & _IO_IS_FILEBUF) status = _IO_file_close_it (fp); else @@ -45,6 +46,7 @@ _IO_fclose (fp) fp->_IO_file_flags = 0; free(fp); } + _IO_funlockfile (fp); return status; } diff --git a/libio/iofflush.c b/libio/iofflush.c index 1f549505c5..6fe2d5262d 100644 --- a/libio/iofflush.c +++ b/libio/iofflush.c @@ -32,9 +32,17 @@ _IO_fflush (fp) return _IO_flush_all (); else { + int result; + _IO_flockfile (fp); CHECK_FILE (fp, EOF); - return _IO_SYNC (fp) ? EOF : 0; + result = _IO_SYNC (fp) ? EOF : 0; + _IO_funlockfile (fp); + return result; } } weak_alias (_IO_fflush, fflush) + +#ifdef _IO_MTSAFE_IO +weak_alias (_IO_fflush, fflush_locked) +#endif diff --git a/libio/iofflush_u.c b/libio/iofflush_u.c new file mode 100644 index 0000000000..b7a91952b4 --- /dev/null +++ b/libio/iofflush_u.c @@ -0,0 +1,41 @@ +/* +Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + +This file is part of the GNU IO Library. This library is free +software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +#include "libioP.h" + +int +_IO_fflush_unlocked (fp) + register _IO_FILE *fp; +{ + if (fp == NULL) + return _IO_flush_all (); + else + { + CHECK_FILE (fp, EOF); + return _IO_SYNC (fp) ? EOF : 0; + } +} + +weak_alias (_IO_fflush_unlocked, fflush_unlocked) + diff --git a/libio/iofgetpos.c b/libio/iofgetpos.c index bc2215fc01..50014765f9 100644 --- a/libio/iofgetpos.c +++ b/libio/iofgetpos.c @@ -33,7 +33,9 @@ _IO_fgetpos (fp, posp) { _IO_fpos_t pos; CHECK_FILE (fp, EOF); + _IO_flockfile (fp); pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0); + _IO_funlockfile (fp); if (pos == _IO_pos_BAD) { #ifdef EIO diff --git a/libio/iofgets.c b/libio/iofgets.c index a9f161dce8..88d4bd518e 100644 --- a/libio/iofgets.c +++ b/libio/iofgets.c @@ -31,14 +31,21 @@ _IO_fgets (buf, n, fp) _IO_FILE* fp; { _IO_size_t count; + char *result; CHECK_FILE (fp, NULL); if (n <= 0) return NULL; + _IO_flockfile (fp); count = _IO_getline (fp, buf, n - 1, '\n', 1); if (count == 0 || (fp->_IO_file_flags & _IO_ERR_SEEN)) - return NULL; - buf[count] = 0; - return buf; + result = NULL; + else + { + buf[count] = '\0'; + result = buf; + } + _IO_funlockfile (fp); + return result; } weak_alias (_IO_fgets, fgets) diff --git a/libio/iofputs.c b/libio/iofputs.c index 62bc981e1d..3359515ac8 100644 --- a/libio/iofputs.c +++ b/libio/iofputs.c @@ -1,5 +1,5 @@ /* -Copyright (C) 1993 Free Software Foundation +Copyright (C) 1993, 1996 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the @@ -31,10 +31,15 @@ _IO_fputs (str, fp) _IO_FILE *fp; { _IO_size_t len = strlen (str); + int result; CHECK_FILE (fp, EOF); - if (_IO_sputn( fp, str, len) != len) - return EOF; - return 1; + _IO_flockfile (fp); + if (_IO_sputn (fp, str, len) != len) + result = EOF; + else + result = 1; + _IO_funlockfile (fp); + return result; } weak_alias (_IO_fputs, fputs) diff --git a/libio/iofread.c b/libio/iofread.c index babe2c54cc..bad94ca17b 100644 --- a/libio/iofread.c +++ b/libio/iofread.c @@ -36,7 +36,9 @@ _IO_fread (buf, size, count, fp) CHECK_FILE (fp, 0); if (bytes_requested == 0) return 0; + _IO_flockfile (fp); bytes_read = _IO_sgetn (fp, (char *) buf, bytes_requested); + _IO_funlockfile (fp); return bytes_requested == bytes_read ? count : bytes_read / size; } weak_alias (_IO_fread, fread) diff --git a/libio/iofsetpos.c b/libio/iofsetpos.c index 72db3b1fa0..c8897522d6 100644 --- a/libio/iofsetpos.c +++ b/libio/iofsetpos.c @@ -30,7 +30,9 @@ _IO_fsetpos (fp, posp) _IO_FILE* fp; const _IO_fpos_t *posp; { + int result; CHECK_FILE (fp, EOF); + _IO_flockfile (fp); if (_IO_seekpos (fp, *posp, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD) { /*ANSI explicily requires setting errno to a positive value on failure.*/ @@ -38,9 +40,12 @@ _IO_fsetpos (fp, posp) if (errno == 0) errno = EIO; #endif - return EOF; + result = EOF; } - return 0; + else + result = 0; + _IO_funlockfile (fp); + return result; } weak_alias (_IO_fsetpos, fsetpos) diff --git a/libio/ioftell.c b/libio/ioftell.c index 8af2ce7f1f..d49f8c3553 100644 --- a/libio/ioftell.c +++ b/libio/ioftell.c @@ -32,7 +32,9 @@ _IO_ftell (fp) { _IO_pos_t pos; CHECK_FILE (fp, -1L); + _IO_flockfile (fp); pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0); + _IO_funlockfile (fp); if (pos == _IO_pos_BAD) { #ifdef EIO diff --git a/libio/iofwrite.c b/libio/iofwrite.c index b8f02f2dd0..0bbeef2646 100644 --- a/libio/iofwrite.c +++ b/libio/iofwrite.c @@ -36,7 +36,9 @@ _IO_fwrite (buf, size, count, fp) CHECK_FILE (fp, 0); if (request == 0) return 0; + _IO_flockfile (fp); written = _IO_sputn (fp, (const char *) buf, request); + _IO_funlockfile (fp); /* Many traditional implementations return 0 if size==0 && count > 0, but ANSI seems to require us to return count in this case. */ if (written == request) diff --git a/libio/iogetdelim.c b/libio/iogetdelim.c index ecb360b1f5..1d14551615 100644 --- a/libio/iogetdelim.c +++ b/libio/iogetdelim.c @@ -42,6 +42,7 @@ _IO_getdelim (lineptr, n, delimiter, fp) int delimiter; _IO_FILE *fp; { + int result; register _IO_ssize_t cur_len = 0; _IO_ssize_t len; @@ -53,22 +54,32 @@ _IO_getdelim (lineptr, n, delimiter, fp) return -1; } CHECK_FILE (fp, -1); - if (_IO_ferror (fp)) - return -1; + _IO_flockfile (fp); + if (_IO_ferror_unlocked (fp)) + { + result = -1; + goto unlock_return; + } if (*lineptr == NULL || *n == 0) { *n = 120; *lineptr = (char *) malloc (*n); if (*lineptr == NULL) - return -1; + { + result = -1; + goto unlock_return; + } } len = fp->_IO_read_end - fp->_IO_read_ptr; if (len <= 0) { if (__underflow (fp) == EOF) - return -1; + { + result = -1; + goto unlock_return; + } len = fp->_IO_read_end - fp->_IO_read_ptr; } @@ -88,7 +99,10 @@ _IO_getdelim (lineptr, n, delimiter, fp) *n = needed; *lineptr = (char *) realloc (*lineptr, needed); if (*lineptr == NULL) - return -1; + { + result = -1; + goto unlock_return; + } } memcpy (*lineptr + cur_len, (void *) fp->_IO_read_ptr, len); fp->_IO_read_ptr += len; @@ -98,7 +112,11 @@ _IO_getdelim (lineptr, n, delimiter, fp) len = fp->_IO_read_end - fp->_IO_read_ptr; } (*lineptr)[cur_len] = '\0'; - return cur_len; + result = cur_len; + +unlock_return: + _IO_funlockfile (fp); + return result; } weak_alias (_IO_getdelim, __getdelim) diff --git a/libio/iogets.c b/libio/iogets.c index 419342fb12..352e80244b 100644 --- a/libio/iogets.c +++ b/libio/iogets.c @@ -30,7 +30,10 @@ _IO_gets (buf) char* buf; { _IO_size_t count; - int ch = _IO_getc (_IO_stdin); + int ch; + + _IO_flockfile (_IO_stdin); + ch = _IO_getc_unlocked (_IO_stdin); if (ch == EOF) return NULL; if (ch == '\n') @@ -42,6 +45,7 @@ _IO_gets (buf) if (_IO_stdin->_IO_file_flags & _IO_ERR_SEEN) return NULL; } + _IO_funlockfile (_IO_stdin); buf[count] = 0; return buf; } diff --git a/libio/ioputs.c b/libio/ioputs.c index 129da1d821..6c52f7521c 100644 --- a/libio/ioputs.c +++ b/libio/ioputs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993 Free Software Foundation +/* Copyright (C) 1993, 1996 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the @@ -28,11 +28,15 @@ int _IO_puts (str) const char *str; { + int result; _IO_size_t len = strlen (str); - if (_IO_sputn (_IO_stdout, str, len) != len) - return EOF; - if (_IO_putc ('\n', _IO_stdout) == EOF) - return EOF; - return len+1; + _IO_flockfile (fp); + if (_IO_sputn (_IO_stdout, str, len) == len + && _IO_putc_unlocked ('\n', _IO_stdout) != EOF) + result = len + 1; + else + result = EOF; + _IO_funlockfile (fp); + return result; } weak_alias (_IO_puts, puts) diff --git a/libio/iosetbuffer.c b/libio/iosetbuffer.c index 0ad38111d6..d3fc7e5917 100644 --- a/libio/iosetbuffer.c +++ b/libio/iosetbuffer.c @@ -1,5 +1,5 @@ /* -Copyright (C) 1993 Free Software Foundation +Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the @@ -31,8 +31,12 @@ _IO_setbuffer (fp, buf, size) _IO_size_t size; { CHECK_FILE (fp, ); + _IO_flockfile (fp); fp->_flags &= ~_IO_LINE_BUF; if (!buf) size = 0; (void) _IO_SETBUF (fp, buf, size); + _IO_funlockfile (fp); } + +weak_alias (_IO_setbuffer, setbuffer) diff --git a/libio/iosetvbuf.c b/libio/iosetvbuf.c index 396ef2fb14..6d4bcff2bc 100644 --- a/libio/iosetvbuf.c +++ b/libio/iosetvbuf.c @@ -35,7 +35,9 @@ _IO_setvbuf (fp, buf, mode, size) int mode; _IO_size_t size; { + int result; CHECK_FILE (fp, EOF); + _IO_flockfile (fp); switch (mode) { case _IOFBF: @@ -58,25 +60,36 @@ _IO_setvbuf (fp, buf, mode, size) A possibly cleaner alternative would be to add an extra flag, but then flags are a finite resource. */ if (_IO_DOALLOCATE (fp) < 0) - return EOF; + { + result = EOF; + goto unlock_return; + } fp->_IO_file_flags &= ~_IO_LINE_BUF; } - return 0; + result = 0; + goto unlock_return; } break; case _IOLBF: fp->_IO_file_flags |= _IO_LINE_BUF; if (buf == NULL) - return 0; + { + result = 0; + goto unlock_return; + } break; case _IONBF: buf = NULL; size = 0; break; default: - return EOF; + result = EOF; + goto unlock_return; } - return _IO_SETBUF (fp, buf, size) == NULL ? EOF : 0; + result = _IO_SETBUF (fp, buf, size) == NULL ? EOF : 0; +unlock_return: + _IO_funlockfile (fp); + return result; } weak_alias (_IO_setvbuf, setvbuf) diff --git a/libio/ioungetc.c b/libio/ioungetc.c index 1a6988ef16..c1237b5f9b 100644 --- a/libio/ioungetc.c +++ b/libio/ioungetc.c @@ -1,5 +1,5 @@ /* -Copyright (C) 1993 Free Software Foundation +Copyright (C) 1993, 1996 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the @@ -29,10 +29,14 @@ _IO_ungetc (c, fp) int c; _IO_FILE *fp; { + int result; CHECK_FILE (fp, EOF); if (c == EOF) return EOF; - return _IO_sputbackc (fp, (unsigned char) c); + _IO_flockfile (fp); + result = _IO_sputbackc (fp, (unsigned char) c); + _IO_funlockfile (fp); + return result; } weak_alias (_IO_ungetc, ungetc) diff --git a/libio/iovsprintf.c b/libio/iovsprintf.c index 182c4ff306..2c5d77503d 100644 --- a/libio/iovsprintf.c +++ b/libio/iovsprintf.c @@ -37,7 +37,7 @@ _IO_vsprintf (string, format, args) _IO_JUMPS ((_IO_FILE *) &sf) = &_IO_str_jumps; _IO_str_init_static ((_IO_FILE *) &sf, string, -1, string); ret = _IO_vfprintf ((_IO_FILE *) &sf, format, args); - _IO_putc('\0', (_IO_FILE *) &sf); + _IO_putc_unlocked ('\0', (_IO_FILE *) &sf); return ret; } diff --git a/libio/libio.h b/libio/libio.h index 405036dfb6..fce8a77bf7 100644 --- a/libio/libio.h +++ b/libio/libio.h @@ -148,15 +148,13 @@ typedef struct int (*close) __P ((struct _IO_FILE *)); } _IO_cookie_io_functions_t; +/* Handle lock. */ +#ifdef _IO_MTSAFE_IO +typedef pthread_mutex_t _IO_lock_t; +#else +typedef void _IO_lock_t; +#endif -/* The reentrant version of the libio implementation needs a semaphore for - each _IO_FILE struture. Because we don't know how the semaphore - will be implemented we try to be very general. */ -struct _IO_lock_t { - void *ptr; - short int field1; - short int field2; -}; /* A streammarker remembers a position in a buffer. */ @@ -217,7 +215,7 @@ struct _IO_FILE { /* char* _save_gptr; char* _save_egptr; */ - struct _IO_lock_t _IO_lock; + _IO_lock_t *_lock; }; #ifndef __cplusplus @@ -238,26 +236,38 @@ extern int __underflow __P((_IO_FILE*)); extern int __uflow __P((_IO_FILE*)); extern int __overflow __P((_IO_FILE*, int)); -#define _IO_getc(_fp) \ +#define _IO_getc_unlocked(_fp) \ ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end ? __uflow(_fp) \ : *(unsigned char*)(_fp)->_IO_read_ptr++) -#define _IO_peekc(_fp) \ +#define _IO_peekc_unlocked(_fp) \ ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end \ && __underflow(_fp) == EOF ? EOF \ : *(unsigned char*)(_fp)->_IO_read_ptr) -#define _IO_putc(_ch, _fp) \ +#define _IO_putc_unlocked(_ch, _fp) \ (((_fp)->_IO_write_ptr >= (_fp)->_IO_write_end) \ ? __overflow(_fp, (unsigned char)(_ch)) \ : (unsigned char)(*(_fp)->_IO_write_ptr++ = (_ch))) -#define _IO_feof(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0) -#define _IO_ferror(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0) +#define _IO_feof_unlocked(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0) +#define _IO_ferror_unlocked(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0) /* This one is for Emacs. */ #define _IO_PENDING_OUTPUT_COUNT(_fp) \ ((_fp)->_IO_write_ptr - (_fp)->_IO_write_base) +extern int _IO_getc_locked __P ((_IO_FILE *)); +extern int _IO_putc_locked __P ((int, _IO_FILE *)); + +extern void _IO_flockfile __P ((_IO_FILE *)); +extern void _IO_funlockfile __P ((_IO_FILE *)); + +#if !defined(_REENTRANT) && !defined(_THREAD_SAFE) +# define _IO_flockfile(FILE) /**/ +# define _IO_funlockfile(FILE) /**/ +#endif /* _REENTRANT || _THREAD_SAFE */ + + extern int _IO_vfscanf __P((_IO_FILE*, const char*, _IO_va_list, int*)); extern int _IO_vfprintf __P((_IO_FILE*, const char*, _IO_va_list)); extern _IO_ssize_t _IO_padn __P((_IO_FILE *, int, _IO_ssize_t)); diff --git a/libio/putc.c b/libio/putc.c index 675fe5eedf..23595ab7b5 100644 --- a/libio/putc.c +++ b/libio/putc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -22,9 +22,20 @@ Cambridge, MA 02139, USA. */ #undef putc int -putc (c, stream) +putc (c, fp) int c; - _IO_FILE *stream; + _IO_FILE *fp; { - return _IO_putc (c, stream); + int result; + CHECK_FILE (fp, EOF); + _IO_flockfile (fp); + result = _IO_putc_unlocked (c, fp); + _IO_funlockfile (fp); + return result; } + +#ifdef _IO_MTSAFE_IO +# undef putc_locked + +weak_alias (putc_locked, putc) +#endif diff --git a/libio/putc_u.c b/libio/putc_u.c new file mode 100644 index 0000000000..18bbd491d8 --- /dev/null +++ b/libio/putc_u.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991, 1995, 1996 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "libioP.h" +#include "stdio.h" + +#undef putc_unlocked + +int +putc_unlocked (c, fp) + int c; + _IO_FILE *fp; +{ + CHECK_FILE (fp, EOF); + return _IO_putc_unlocked (c, fp); +} diff --git a/libio/putchar.c b/libio/putchar.c index bf10da9468..d4d52f60d2 100644 --- a/libio/putchar.c +++ b/libio/putchar.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -25,5 +25,15 @@ int putchar (c) int c; { - return _IO_putc (c, stdout); + int result; + _IO_flockfile (_IO_stdout); + result = _IO_putc_unlocked (c, _IO_stdout); + _IO_funlockfile (_IO_stdout); + return result; } + +#ifdef _IO_MTSAFE_IO +# undef putchar_locked + +weak_alias (putchar_locked, putchar) +#endif diff --git a/libio/putchar_u.c b/libio/putchar_u.c new file mode 100644 index 0000000000..d29652aadc --- /dev/null +++ b/libio/putchar_u.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991, 1995, 1996 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include "libioP.h" +#include "stdio.h" + +#undef putchar_unlocked + +int +putchar_unlocked (c) + int c; +{ + CHECK_FILE (fp, EOF); + return _IO_putc_unlocked (c, fp); +} diff --git a/libio/rewind.c b/libio/rewind.c index dfb02cc3f2..2f57e0de83 100644 --- a/libio/rewind.c +++ b/libio/rewind.c @@ -29,5 +29,7 @@ rewind (fp) _IO_FILE* fp; { CHECK_FILE (fp, ); + _IO_flockfile (fp); _IO_rewind (fp); + _IO_funlockfile (fp); } diff --git a/libio/stdio.h b/libio/stdio.h index e68b6ceeff..bd271ce1fb 100644 --- a/libio/stdio.h +++ b/libio/stdio.h @@ -161,6 +161,7 @@ extern int pclose __P ((FILE*)); #ifdef __USE_GNU extern _IO_ssize_t getdelim __P ((char **, size_t *, int, FILE*)); extern _IO_ssize_t getline __P ((char **, size_t *, FILE *)); +extern _IO_ssize_t __getline __P ((char **, size_t *, FILE *)); extern int snprintf __P ((char *, size_t, __const char *, ...)); extern int __snprintf __P ((char *, size_t, __const char *, ...)); @@ -178,11 +179,6 @@ extern FILE *open_memstream __P ((char **__bufloc, size_t *__sizeloc)); extern int __underflow __P ((struct _IO_FILE*)); extern int __overflow __P ((struct _IO_FILE*, int)); -#define getc(fp) _IO_getc (fp) -#define putc(c, fp) _IO_putc (c, fp) -#define putchar(c) putc (c, stdout) -#define getchar() getc (stdin) - #ifdef __USE_BSD extern int sys_nerr; extern const char *const sys_errlist[]; @@ -192,8 +188,49 @@ extern int _sys_nerr; extern const char *const _sys_errlist[]; #endif +/* Handle locking of streams. */ +#if defined(_REENTRANT) || defined(_THREAD_SAFE) +extern void clearerr_unlocked __P ((FILE *)); +extern void fileno_unlocked __P ((FILE *)); +extern void flockfile __P ((FILE *)); +extern void funlockfile __P ((FILE *)); +extern int fclose_unlocked __P ((FILE *)); +extern int fflush_unlocked __P ((FILE *)); +extern size_t fread_unlocked __P ((void *, size_t, size_t, FILE *)); +extern size_t fwrite_unlocked __P ((const void *, size_t, size_t, FILE *)); + +# define getc_unlocked(fp) _IO_getc_unlocked (fp) +# define getc_locked(fp) _IO_fgetc (fp) +# define getchar_unlocked() getc_unlocked (stdin) +# define getchar_locked() getc_locked (stdin) +# define getc(fp) getc_locked (fp) + +# define putc_unlocked(c, fp) _IO_putc_unlocked (c, fp) +# define putc_locked(c, fp) _IO_putc_locked (c, fp) +# define putchar_unlocked(c) putc_unlocked (c, stdout) +# define putchar_locked(c) putc_locked (c, stdout) +# define putc(c, fp) putc_locked (c, fp) + +# define feof_unlocked(fp) _IO_feof_unlocked (fp) +# define ferror_unlocked(fp) _IO_ferror_unlocked (fp) + +#else +# define getc(fp) _IO_getc_unlocked (fp) +# define putc(c, fp) _IO_putc_unlocked (c, fp) + +#endif /* _REENTRANT || _THREAD_SAFE */ + +#define flockfile(FILE) _IO_flockfile (FILE) +#define funlockfile(FILE) _IO_funlockfile (FILE) + +#define putchar(c) putc (c, stdout) +#define getchar() getc (stdin) + + #ifdef __cplusplus } #endif + + #endif /* !_STDIO_H */ diff --git a/locale/programs/config.h b/locale/programs/config.h index 6c67813f93..96d9281ce3 100644 --- a/locale/programs/config.h +++ b/locale/programs/config.h @@ -23,9 +23,6 @@ #define HAVE_VPRINTF 1 -typedef int wint_t; - - #include_next #endif diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c index 6643ae85c8..629df90ced 100644 --- a/locale/programs/ld-collate.c +++ b/locale/programs/ld-collate.c @@ -28,7 +28,7 @@ Boston, MA 02111-1307, USA. */ #include #include #include -#include +#include #include "localeinfo.h" #include "locales.h" @@ -36,7 +36,7 @@ Boston, MA 02111-1307, USA. */ #include "stringtrans.h" /* Uncomment the following line in the production version. */ -/* define NDEBUG 1 */ +/* #define NDEBUG 1 */ #include diff --git a/manual/time.texi b/manual/time.texi index eae3011e4c..c8ca7e8118 100644 --- a/manual/time.texi +++ b/manual/time.texi @@ -672,11 +672,20 @@ The second as a decimal number. @item %U The week number of the current year as a decimal number, starting with -the first Sunday as the first day of the first week. +the first Sunday as the first day of the first week. All days preceding +the first Sunday in the year are considered to be in week @code{0}. + +@item %V +The week number of the current year as a decimal number, starting with +the first Monday as the first day of the first week. If the week +containing January 1 has four or more days in the new year it is +considered to be week @code{1}. Otherwise it is week @code{53} of the +previous year. This is standardized in @w{ISO 8601:1988}. @item %W The week number of the current year as a decimal number, starting with -the first Monday as the first day of the first week. +the first Monday as the first day of the first week. All days preceding +the first Monday in the year are considered to be in week @code{0}. @item %w The day of the week as a decimal number, Sunday being @code{0}. diff --git a/misc/getusershell.c b/misc/getusershell.c index 6782c3efe9..3816e1e784 100644 --- a/misc/getusershell.c +++ b/misc/getusershell.c @@ -49,9 +49,9 @@ static char sccsid[] = "@(#)getusershell.c 8.1 (Berkeley) 6/4/93"; * /etc/shells. */ -static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL }; -static char **curshell, **shells, *strings; -static char **initshells __P((void)); +static const char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL }; +static const char **curshell, **shells, *strings; +static const char **initshells __P((void)); /* * Get a list of shells from _PATH_SHELLS, if it exists. @@ -59,14 +59,14 @@ static char **initshells __P((void)); char * getusershell() { - char *ret; + const char *ret; if (curshell == NULL) curshell = initshells(); ret = *curshell; if (ret != NULL) curshell++; - return (ret); + return (char *) ret; /* Cast away `const' for history reasons. */ } void @@ -89,7 +89,7 @@ setusershell() curshell = initshells(); } -static char ** +static const char ** initshells() { register char **sp, *cp; @@ -97,10 +97,10 @@ initshells() struct stat statb; if (shells != NULL) - free(shells); + free((char *) shells); shells = NULL; if (strings != NULL) - free(strings); + free((char *) strings); strings = NULL; if ((fp = fopen(_PATH_SHELLS, "r")) == NULL) return (okshells); @@ -119,8 +119,8 @@ initshells() strings = NULL; return (okshells); } - sp = shells; - cp = strings; + sp = (char *) shells; + cp = (char *) strings; while (fgets(cp, statb.st_size - (cp - strings), fp) != NULL) { while (*cp != '#' && *cp != '/' && *cp != '\0') cp++; diff --git a/resolv/gethnamaddr.c b/resolv/gethnamaddr.c index 87b4db1a6f..41be4fc10d 100644 --- a/resolv/gethnamaddr.c +++ b/resolv/gethnamaddr.c @@ -397,9 +397,12 @@ struct hostent * gethostbyname(name) const char *name; { + /* Moved #if line to here because declararing HP would lead to a + warining. --drepper@gnu */ +#if defined(AF_INET6) && defined(RES_TRY_INET6) struct hostent *hp; -#if defined(AF_INET6) && defined(RES_TRY_INET6) +/* #if defined(AF_INET6) && defined(RES_TRY_INET6) */ if (_res.options & RES_TRY_INET6) { hp = gethostbyname2(name, AF_INET6); if (hp) diff --git a/stdio-common/_itoa.c b/stdio-common/_itoa.c index f85b15b030..9d77b39005 100644 --- a/stdio-common/_itoa.c +++ b/stdio-common/_itoa.c @@ -260,9 +260,11 @@ _itoa (value, buflim, base, upper_case) Optimize for frequent cases of 32 bit numbers. */ if ((mp_limb_t) (value >> 32) >= 1) { +#if UDIV_TIME > 2 * UMUL_TIME || UDIV_NEEDS_NORMALIZATION int big_normalization_steps = brec->big.normalization_steps; - mp_limb_t big_base_norm = brec->big.base << big_normalization_steps; - + mp_limb_t big_base_norm + = brec->big.base << big_normalization_steps; +#endif if ((mp_limb_t) (value >> 32) >= brec->big.base) { mp_limb_t x1hi, x1lo, r; diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c index 237deb99a5..9e14b67509 100644 --- a/stdio-common/printf_fp.c +++ b/stdio-common/printf_fp.c @@ -54,7 +54,7 @@ Cambridge, MA 02139, USA. */ /* We use this file GNU C library and GNU I/O library. So make names equal. */ # undef putc -# define putc(c, f) _IO_putc (c, f) +# define putc(c, f) _IO_putc_unlocked (c, f) # define size_t _IO_size_t # define FILE _IO_FILE #else /* ! USE_IN_LIBIO */ diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c index 9b24574558..cde7496585 100644 --- a/stdio-common/vfprintf.c +++ b/stdio-common/vfprintf.c @@ -62,14 +62,14 @@ ssize_t __printf_pad __P ((FILE *, char pad, size_t n)); # define ISDIGIT(Ch) iswdigit (Ch) # ifdef USE_IN_LIBIO -# define PUT(F, S, N) _IO_sputn (F, S, N) -# define PAD(Padchar) \ +# define PUT(F, S, N) _IO_sputn (F, S, N) +# define PAD(Padchar) \ if (width > 0) \ done += _IO_wpadn (s, Padchar, width) # else # define PUTC(C, F) wputc (C, F) ssize_t __wprintf_pad __P ((FILE *, wchar_t pad, size_t n)); -# define PAD(Padchar) \ +# define PAD(Padchar) \ if (width > 0) \ { if (__wprintf_pad (s, Padchar, width) == -1) \ return -1; else done += width; } @@ -83,7 +83,7 @@ ssize_t __wprintf_pad __P ((FILE *, wchar_t pad, size_t n)); #ifdef USE_IN_LIBIO /* This code is for use in libio. */ # include -# define PUTC(C, F) _IO_putc (C, F) +# define PUTC(C, F) _IO_putc_unlocked (C, F) # define vfprintf _IO_vfprintf # define size_t _IO_size_t # define FILE _IO_FILE @@ -102,6 +102,8 @@ ssize_t __wprintf_pad __P ((FILE *, wchar_t pad, size_t n)); } \ } while (0) # define UNBUFFERED_P(S) ((S)->_IO_file_flags & _IO_UNBUFFERED) +# define flockfile(S) _IO_flockfile (S) +# define fUNlockfile(S) _IO_funlockfile (S) #else /* ! USE_IN_LIBIO */ /* This code is for use in the GNU C library. */ # include @@ -801,13 +803,19 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) /* Find the first format specifier. */ f = lead_str_end = find_spec (format, &mbstate); + /* Lock stream. */ + flockfile (s); + /* Write the literal text before the first format. */ outstring ((const UCHAR_T *) format, lead_str_end - (const UCHAR_T *) format); /* If we only have to print a simple string, return now. */ if (*f == L_('\0')) - return done; + { + funlockfile (s); + return done; + } /* Process whole format string. */ do @@ -972,8 +980,11 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) LABEL (form_unknown): if (spec == L_('\0')) - /* The format string ended before the specifier is complete. */ - return -1; + { + /* The format string ended before the specifier is complete. */ + funlockfile (s); + return -1; + } /* If we are in the fast loop force entering the complicated one. */ @@ -988,6 +999,9 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) } while (*f != L_('\0')); + /* Unlock stream. */ + funlockfile (s); + /* We processed the whole format without any positional parameters. */ return done; @@ -1230,7 +1244,10 @@ do_positional: /* If an error occured we don't have information about # of chars. */ if (function_done < 0) - return -1; + { + funlockfile (s); + return -1; + } done += function_done; } @@ -1244,6 +1261,9 @@ do_positional: } } + /* Unlock the stream. */ + funlockfile (s); + return done; } @@ -1378,7 +1398,7 @@ _IO_helper_overflow (_IO_FILE *s, int c) _IO_size_t written = _IO_sputn (target, s->_IO_write_base, used); s->_IO_write_ptr -= written; } - return _IO_putc (c, s); + return PUTC (c, s); } static const struct _IO_jump_t _IO_helper_jumps = diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c index bc7acd60de..4b4dd119ca 100644 --- a/stdio-common/vfscanf.c +++ b/stdio-common/vfscanf.c @@ -54,38 +54,59 @@ Cambridge, MA 02139, USA. */ # define va_list _IO_va_list # define ungetc(c, s) _IO_ungetc (c, s) -# define inchar() ((c = _IO_getc (s)), (void) ++read_in, c) -# define conv_error() return ((void) (errp != NULL && (*errp |= 2)), \ - (void) (c == EOF || _IO_ungetc (c, s)), done) - -# define input_error() return ((void) (errp != NULL && (*errp |= 1)), \ - done == 0 ? EOF : done) -# define memory_error() return ((void) (errno = ENOMEM), EOF) -# define ARGCHECK(s, format) \ - do \ - { \ - /* Check file argument for consistence. */ \ - CHECK_FILE (s, -1); \ - if (s->_flags & _IO_NO_READS || format == NULL) \ - { \ - MAYBE_SET_EINVAL; \ - return -1; \ - } \ +# define inchar() ((c = _IO_getc_unlocked (s)), (void) ++read_in, c) +# define conv_error() do { \ + if (errp != NULL) *errp |= 2; \ + if (c != EOF) _IO_ungetc (c, s); \ + _IO_funlockfile (s); \ + return done; \ + } while (0) +# define input_error() do { \ + _IO_funlockfile (s); \ + if (errp != NULL) *errp |= 1; \ + return done ?: EOF; \ + } while (0) +# define memory_error() do { \ + _IO_funlockfile (s); \ + errno = ENOMEM; \ + return EOF; \ + } while (0) +# define ARGCHECK(s, format) \ + do \ + { \ + /* Check file argument for consistence. */ \ + CHECK_FILE (s, EOF); \ + if (s->_flags & _IO_NO_READS || format == NULL) \ + { \ + MAYBE_SET_EINVAL; \ + return EOF; \ + } \ } while (0) #else # define inchar() ((c = getc (s)), (void) ++read_in, c) -# define conv_error() return ((void) ungetc (c, s), done) -# define input_error() return (done == 0 ? EOF : done) -# define memory_error() return ((void) (errno = ENOMEM), EOF) -# define ARGCHECK(s, format) \ - do \ - { \ - /* Check file argument for consistence. */ \ - if (!__validfp (s) || !s->__mode.__read || format == NULL) \ - { \ - errno = EINVAL; \ - return -1; \ - } \ +# define conv_error() do { \ + funlockfile (s); \ + ungetc (c, s); \ + return done; \ + } while (0) +# define input_error() do { \ + funlockfile (s); \ + return done ?: EOF; \ + } while (0) +# define memory_error() do { \ + funlockfile (s); \ + errno = ENOMEM; \ + return EOF; \ + } while (0) +# define ARGCHECK(s, format) \ + do \ + { \ + /* Check file argument for consistence. */ \ + if (!__validfp (s) || !s->__mode.__read || format == NULL) \ + { \ + errno = EINVAL; \ + return EOF; \ + } \ } while (0) #endif @@ -173,6 +194,9 @@ __vfscanf (FILE *s, const char *format, va_list argptr) strlen (_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP))) <= 0) thousands = (wchar_t) *_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP); + /* Lock the stream. */ + flockfile (s); + c = inchar (); /* Run through the format string. */ @@ -781,6 +805,9 @@ __vfscanf (FILE *s, const char *format, va_list argptr) while (isspace (c)) (void) inchar (); + /* Unlock stream. */ + funlockfile (s); + return ((void) (c == EOF || ungetc (c, s)), done); } -- cgit 1.4.1