diff options
Diffstat (limited to 'libio')
41 files changed, 641 insertions, 82 deletions
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 */ |