* libc/sys/linux/sys/stdio.h: New file.
* libc/include/stdio.h: Add declarations for flockfile,
ftrylockfile, and funlockfile. Include <sys/stdio.h>.
* libc/stdio/clearerr.c: Add file locking.
* libc/stdio/fclose.c: Likewise.
* libc/stdio/feof.c: Likewise.
* libc/stdio/ferror.c: Likewise.
* libc/stdio/fflush.c: Likewise.
* libc/stdio/fgetc.c: Likewise.
* libc/stdio/fgetpos.c: Likewise.
* libc/stdio/fgets.c: Likewise.
* libc/stdio/fileno.c: Likewise.
* libc/stdio/fputc.c: Likewise.
* libc/stdio/fputs.c: Likewise.
* libc/stdio/fread.c: Likewise.
* libc/stdio/freopen.c: Likewise.
* libc/stdio/fseek.c: Likewise.
* libc/stdio/ftell.c: Likewise.
* libc/stdio/fwrite.c: Likewise.
* libc/stdio/getc.c: Likewise.
* libc/stdio/putc.c: Likewise.
* libc/stdio/setvbuf.c: Likewise.
* libc/stdio/ungetc.c: Likewise.
* libc/stdio/vfprintf.c: Likewise.
+2002-05-07 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * libc/include/sys/stdio.h: New file.
+ * libc/sys/linux/sys/stdio.h: New file.
+ * libc/include/stdio.h: Add declarations for flockfile,
+ ftrylockfile, and funlockfile. Include <sys/stdio.h>.
+ * libc/stdio/clearerr.c: Add file locking.
+ * libc/stdio/fclose.c: Likewise.
+ * libc/stdio/feof.c: Likewise.
+ * libc/stdio/ferror.c: Likewise.
+ * libc/stdio/fflush.c: Likewise.
+ * libc/stdio/fgetc.c: Likewise.
+ * libc/stdio/fgetpos.c: Likewise.
+ * libc/stdio/fgets.c: Likewise.
+ * libc/stdio/fileno.c: Likewise.
+ * libc/stdio/fputc.c: Likewise.
+ * libc/stdio/fputs.c: Likewise.
+ * libc/stdio/fread.c: Likewise.
+ * libc/stdio/freopen.c: Likewise.
+ * libc/stdio/fseek.c: Likewise.
+ * libc/stdio/ftell.c: Likewise.
+ * libc/stdio/fwrite.c: Likewise.
+ * libc/stdio/getc.c: Likewise.
+ * libc/stdio/putc.c: Likewise.
+ * libc/stdio/setvbuf.c: Likewise.
+ * libc/stdio/ungetc.c: Likewise.
+ * libc/stdio/vfprintf.c: Likewise.
+
2002-05-06 Jeff Johnston <jjohnstn@redhat.com>
* libc/include/stdlib.h (a64l, l64a, _l64a_r): Added prototypes.
#include <sys/reent.h>
+#include <sys/stdio.h>
+
typedef _fpos_t fpos_t;
typedef struct __sFILE FILE;
int _EXFUN(putw, (int, FILE *));
void _EXFUN(setbuffer, (FILE *, char *, int));
int _EXFUN(setlinebuf, (FILE *));
+void _EXFUN(flockfile, (FILE *));
+int _EXFUN(ftrylockfile, (FILE *));
+void _EXFUN(funlockfile, (FILE *));
#endif
/*
--- /dev/null
+#ifndef _NEWLIB_STDIO_H
+#define _NEWLIB_STDIO_H
+
+/* Internal locking macros, used to protect stdio functions. In the
+ general case, expand to nothing. */
+#if !defined(_flockfile)
+# define _flockfile(fp)
+#endif
+
+#if !defined(_funlockfile)
+# define _funlockfile(fp)
+#endif
+
+#endif /* _NEWLIB_STDIO_H */
_DEFUN (clearerr, (fp),
FILE * fp)
{
+ _flockfile(fp);
__sclearerr (fp);
+ _funlockfile(fp);
}
if (fp == NULL)
return (0); /* on NULL */
+ _flockfile(fp);
+
CHECK_INIT (fp);
if (fp->_flags == 0) /* not open! */
- return (0);
+ {
+ _funlockfile(fp);
+ return (0);
+ }
r = fp->_flags & __SWR ? fflush (fp) : 0;
if (fp->_close != NULL && (*fp->_close) (fp->_cookie) < 0)
r = EOF;
if (HASLB (fp))
FREELB (fp);
fp->_flags = 0; /* release this FILE for reuse */
+ _funlockfile(fp);
return (r);
}
_DEFUN (feof, (fp),
FILE * fp)
{
- return __sfeof (fp);
+ int result;
+ _flockfile(fp);
+ result = __sfeof (fp);
+ _funlockfile(fp);
+ return result;
}
_DEFUN (ferror, (fp),
FILE * fp)
{
- return __sferror (fp);
+ int result;
+ _flockfile(fp);
+ result = __sferror (fp);
+ _funlockfile(fp);
+ return result;
}
if (fp == NULL)
return _fwalk (_REENT, fflush);
+ _flockfile(fp);
+
CHECK_INIT (fp);
t = fp->_flags;
if ((t & __SWR) == 0 || (p = fp->_bf._base) == NULL)
- return 0;
+ {
+ _funlockfile(fp);
+ return 0;
+ }
n = fp->_p - p; /* write this much */
/*
t = (*fp->_write) (fp->_cookie, (char *) p, n);
if (t <= 0)
{
- fp->_flags |= __SERR;
- return EOF;
+ fp->_flags |= __SERR;
+ _funlockfile(fp);
+ return EOF;
}
p += t;
n -= t;
}
+ _funlockfile(fp);
return 0;
}
_DEFUN (fgetc, (fp),
FILE * fp)
{
- return __sgetc (fp);
+ int result;
+ _flockfile(fp);
+ result = __sgetc (fp);
+ _funlockfile(fp);
+ return result;
}
FILE * fp _AND
fpos_t * pos)
{
+ _flockfile(fp);
*pos = ftell (fp);
if (*pos != -1)
- return 0;
+ {
+ _funlockfile(fp);
+ return 0;
+ }
+ _funlockfile(fp);
return 1;
}
s = buf;
+ _flockfile(fp);
#ifdef __SCLE
if (fp->_flags & __SCLE)
{
break;
}
if (c == EOF && s == buf)
- return NULL;
+ {
+ _funlockfile(fp);
+ return NULL;
+ }
*s = 0;
+ _funlockfile(fp);
return buf;
}
#endif
{
/* EOF: stop with partial or no line */
if (s == buf)
- return 0;
+ {
+ _funlockfile(fp);
+ return 0;
+ }
break;
}
len = fp->_r;
fp->_p = t;
(void) memcpy ((_PTR) s, (_PTR) p, len);
s[len] = 0;
+ _funlockfile(fp);
return (buf);
}
fp->_r -= len;
}
while ((n -= len) != 0);
*s = 0;
+ _funlockfile(fp);
return buf;
}
_DEFUN (fileno, (f),
FILE * f)
{
+ int result;
+ _flockfile(f);
CHECK_INIT (f);
- return __sfileno (f);
+ result = __sfileno (f);
+ _funlockfile(f);
+ return result;
}
int ch _AND
FILE * file)
{
- return putc (ch, file);
+ int result;
+ _flockfile(file);
+ result = putc (ch, file);
+ _funlockfile(file);
+ return result;
}
char _CONST * s _AND
FILE * fp)
{
+ int result;
struct __suio uio;
struct __siov iov;
iov.iov_len = uio.uio_resid = strlen (s);
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
- return __sfvwrite (fp, &uio);
+ _flockfile(fp);
+ result = __sfvwrite (fp, &uio);
+ _funlockfile(fp);
+ return result;
}
if ((resid = count * size) == 0)
return 0;
+
+ _flockfile(fp);
if (fp->_r < 0)
fp->_r = 0;
total = resid;
/* no more input: return partial result */
#ifdef __SCLE
if (fp->_flags & __SCLE)
- return crlf(fp, buf, total-resid, 1) / size;
+ {
+ _funlockfile(fp);
+ return crlf(fp, buf, total-resid, 1) / size;
+ }
#endif
+ _funlockfile(fp);
return (total - resid) / size;
}
}
fp->_p += resid;
#ifdef __SCLE
if (fp->_flags & __SCLE)
- return crlf(fp, buf, total, 0) / size;
+ {
+ _funlockfile(fp);
+ return crlf(fp, buf, total, 0) / size;
+ }
#endif
+ _funlockfile(fp);
return count;
}
int flags, oflags, e;
struct _reent *ptr;
+ _flockfile(fp);
+
CHECK_INIT (fp);
ptr = fp->_data;
if ((flags = __sflags (ptr, mode, &oflags)) == 0)
{
(void) fclose (fp);
+ _funlockfile(fp);
return NULL;
}
{ /* did not get it after all */
fp->_flags = 0; /* set it free */
ptr->_errno = e; /* restore in case _close clobbered */
+ _funlockfile(fp);
return NULL;
}
fp->_flags |= __SCLE;
#endif
+ _funlockfile(fp);
return fp;
}
struct stat st;
int havepos;
+ _flockfile(fp);
+
/* Make sure stdio is set up. */
CHECK_INIT (fp);
if ((seekfn = fp->_seek) == NULL)
{
ptr->_errno = ESPIPE; /* ??? */
+ _funlockfile(fp);
return EOF;
}
{
curoff = (*seekfn) (fp->_cookie, (fpos_t) 0, SEEK_CUR);
if (curoff == -1L)
+ _funlockfile(fp);
return EOF;
}
if (fp->_flags & __SRD)
default:
ptr->_errno = EINVAL;
+ _funlockfile(fp);
return (EOF);
}
if (HASUB (fp))
FREEUB (fp);
fp->_flags &= ~__SEOF;
+ _funlockfile(fp);
return 0;
}
fp->_p += n;
fp->_r -= n;
}
+ _funlockfile(fp);
return 0;
/*
dumb:
if (fflush (fp) || (*seekfn) (fp->_cookie, offset, whence) == POS_ERR)
- return EOF;
+ {
+ _funlockfile(fp);
+ return EOF;
+ }
/* success: clear EOF indicator and discard ungetc() data */
if (HASUB (fp))
FREEUB (fp);
fp->_r = 0;
/* fp->_w = 0; *//* unnecessary (I think...) */
fp->_flags &= ~__SEOF;
+ _funlockfile(fp);
return 0;
}
{
fpos_t pos;
+ _flockfile(fp);
+
/* Ensure stdio is set up. */
CHECK_INIT (fp);
if (fp->_seek == NULL)
{
fp->_data->_errno = ESPIPE;
+ _funlockfile(fp);
return -1L;
}
{
pos = (*fp->_seek) (fp->_cookie, (fpos_t) 0, SEEK_CUR);
if (pos == -1L)
- return pos;
+ {
+ _funlockfile(fp);
+ return pos;
+ }
}
if (fp->_flags & __SRD)
{
pos += fp->_p - fp->_bf._base;
}
+ _funlockfile(fp);
return pos;
}
* generally slow and since this occurs whenever size==0.
*/
+ _flockfile(fp);
if (__sfvwrite (fp, &uio) == 0)
- return count;
+ {
+ _funlockfile(fp);
+ return count;
+ }
+ _funlockfile(fp);
return (n - uio.uio_resid) / size;
}
getc (fp)
register FILE *fp;
{
+ int result;
+ _flockfile(fp);
/* CHECK_INIT is called (eventually) by __srefill. */
-
- return __sgetc (fp);
+ result = __sgetc (fp);
+ _funlockfile(fp);
+ return result;
}
int c;
register FILE *fp;
{
+ int result;
+ _flockfile(fp);
/* CHECK_INIT is (eventually) called by __swbuf. */
-
- return __sputc (c, fp);
+ result = __sputc (c, fp);
+ _funlockfile(fp);
+ return result;
}
register size_t size)
{
int ret = 0;
+
+ _flockfile(fp);
+
CHECK_INIT (fp);
/*
*/
if ((mode != _IOFBF && mode != _IOLBF && mode != _IONBF) || (int)(_POINTER_INT) size < 0)
- return (EOF);
+ {
+ _funlockfile(fp);
+ return (EOF);
+ }
/*
* Write current buffer, if any; drop read count, if any.
size = BUFSIZ;
}
if (buf == NULL)
- {
- /* Can't allocate it, let's try another approach */
+ {
+ /* Can't allocate it, let's try another approach */
nbf:
- fp->_flags |= __SNBF;
- fp->_w = 0;
- fp->_bf._base = fp->_p = fp->_nbuf;
- fp->_bf._size = 1;
- return (ret);
- }
+ fp->_flags |= __SNBF;
+ fp->_w = 0;
+ fp->_bf._base = fp->_p = fp->_nbuf;
+ fp->_bf._size = 1;
+ _funlockfile(fp);
+ return (ret);
+ }
fp->_flags |= __SMBF;
}
/*
if (fp->_flags & __SWR)
fp->_w = fp->_flags & (__SLBF | __SNBF) ? 0 : size;
+ _funlockfile(fp);
return 0;
}
if (c == EOF)
return (EOF);
+ _flockfile(fp);
+
/* Ensure stdio has been initialized.
??? Might be able to remove this as some other stdio routine should
have already been called to get the char we are un-getting. */
* Otherwise, flush any current write stuff.
*/
if ((fp->_flags & __SRW) == 0)
- return EOF;
+ {
+ _funlockfile(fp);
+ return EOF;
+ }
if (fp->_flags & __SWR)
{
if (fflush (fp))
- return EOF;
+ {
+ _funlockfile(fp);
+ return EOF;
+ }
fp->_flags &= ~__SWR;
fp->_w = 0;
fp->_lbfsize = 0;
if (HASUB (fp))
{
if (fp->_r >= fp->_ub._size && __submore (fp))
- return EOF;
+ {
+ _funlockfile(fp);
+ return EOF;
+ }
*--fp->_p = c;
fp->_r++;
+ _funlockfile(fp);
return c;
}
{
fp->_p--;
fp->_r++;
+ _funlockfile(fp);
return c;
}
fp->_ubuf[sizeof (fp->_ubuf) - 1] = c;
fp->_p = &fp->_ubuf[sizeof (fp->_ubuf) - 1];
fp->_r = 1;
+ _funlockfile(fp);
return c;
}
_CONST char *fmt0 _AND
va_list ap)
{
+ int result;
+ _flockfile(fp);
CHECK_INIT (fp);
- return _VFPRINTF_R (fp->_data, fp, fmt0, ap);
+ result = _VFPRINTF_R (fp->_data, fp, fmt0, ap);
+ _funlockfile(fp);
+ return result;
}
int
--- /dev/null
+#ifndef _NEWLIB_STDIO_H
+#define _NEWLIB_STDIO_H
+
+/* Internal locking macros, used to protect stdio functions. In the
+ linux case, expand to flockfile, and funlockfile, both defined in
+ LinuxThreads. */
+#if !defined(__SINGLE_THREAD__)
+# if !defined(_flockfile)
+# define _flockfile(fp) /* FIXME: Uncomment when LinuxThreads is in: flockfile(fp) */
+# endif
+# if !defined(_funlockfile)
+# define _funlockfile(fp) /* FIXME: Uncomment when LinuxThreads is in: funlockfile(fp) */
+# endif
+#endif /* __SINGLE_THREAD__ */
+
+#endif /* _NEWLIB_STDIO_H */