add and "f" flag to fopen that makes sure we are opening a plain file,

so that there is no chance to block.
This commit is contained in:
christos 2000-01-15 01:11:45 +00:00
parent b41faac27c
commit fc1a83184b
3 changed files with 51 additions and 14 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: flags.c,v 1.11 1999/09/20 04:39:27 lukem Exp $ */ /* $NetBSD: flags.c,v 1.12 2000/01/15 01:11:45 christos Exp $ */
/*- /*-
* Copyright (c) 1990, 1993 * Copyright (c) 1990, 1993
@ -41,7 +41,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)flags.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)flags.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: flags.c,v 1.11 1999/09/20 04:39:27 lukem Exp $"); __RCSID("$NetBSD: flags.c,v 1.12 2000/01/15 01:11:45 christos Exp $");
#endif #endif
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
@ -91,11 +91,25 @@ __sflags(mode, optr)
return (0); return (0);
} }
/* [rwa]\+ or [rwa]b\+ means read and write */ /*
if (*mode == '+' || (*mode == 'b' && mode[1] == '+')) { * [rwa]\+ or [rwa]b\+ means read and write
ret = __SRW; * f means open only plain files.
m = O_RDWR; */
} for (; *mode; mode++)
switch (*mode) {
case '+':
ret = __SRW;
m = O_RDWR;
break;
case 'f':
o |= O_NONBLOCK;
break;
case 'b':
break;
default: /* We could produce a warning here */
break;
}
*optr = m | o; *optr = m | o;
return (ret); return (ret);
} }

View File

@ -1,4 +1,4 @@
.\" $NetBSD: fopen.3,v 1.9 1999/01/12 15:27:28 kleink Exp $ .\" $NetBSD: fopen.3,v 1.10 2000/01/15 01:11:45 christos Exp $
.\" .\"
.\" Copyright (c) 1990, 1991, 1993 .\" Copyright (c) 1990, 1991, 1993
.\" The Regents of the University of California. All rights reserved. .\" The Regents of the University of California. All rights reserved.
@ -87,12 +87,18 @@ The file is created if it does not exist.
.Pp .Pp
The The
.Fa mode .Fa mode
string can also include the letter ``b'' either as a third character or string can also include the letter ``b'' either as a last character or
as a character between the characters in any of the two-character strings as a character between the characters in any of the two-character strings
described above. described above.
This is strictly for compatibility with This is strictly for compatibility with
.St -ansiC .St -ansiC
and has no effect; the ``b'' is ignored. and has no effect; the ``b'' is ignored.
In addition the letter ``f'' in the mode string restricts fopen to plain
files; if the file opened is not a plain file,
.Fn fopen
will fail. This is a non
.St -ansiC
extension.
.Pp .Pp
Any created files will have mode Any created files will have mode
.Pf \\*q Dv S_IRUSR .Pf \\*q Dv S_IRUSR
@ -189,6 +195,9 @@ provided to
or or
.Fn freopen .Fn freopen
was invalid. was invalid.
.It Bq Er EFTYPE
The file is not a plain file and the character ``f'' is specified
in the mode.
.El .El
.Pp .Pp
The The

View File

@ -1,4 +1,4 @@
/* $NetBSD: fopen.c,v 1.8 1999/09/20 04:39:27 lukem Exp $ */ /* $NetBSD: fopen.c,v 1.9 2000/01/15 01:11:45 christos Exp $ */
/*- /*-
* Copyright (c) 1990, 1993 * Copyright (c) 1990, 1993
@ -41,7 +41,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)fopen.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)fopen.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: fopen.c,v 1.8 1999/09/20 04:39:27 lukem Exp $"); __RCSID("$NetBSD: fopen.c,v 1.9 2000/01/15 01:11:45 christos Exp $");
#endif #endif
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
@ -49,6 +49,7 @@ __RCSID("$NetBSD: fopen.c,v 1.8 1999/09/20 04:39:27 lukem Exp $");
#include <sys/stat.h> #include <sys/stat.h>
#include <assert.h> #include <assert.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#include "local.h" #include "local.h"
@ -67,9 +68,19 @@ fopen(file, mode)
return (NULL); return (NULL);
if ((fp = __sfp()) == NULL) if ((fp = __sfp()) == NULL)
return (NULL); return (NULL);
if ((f = open(file, oflags, DEFFILEMODE)) < 0) { if ((f = open(file, oflags, DEFFILEMODE)) < 0)
fp->_flags = 0; /* release */ goto release;
return (NULL); if (oflags & O_NONBLOCK) {
struct stat st;
if (fstat(f, &st) == -1) {
close(f);
goto release;
}
if (!S_ISREG(st.st_mode)) {
errno = EFTYPE;
close(f);
goto release;
}
} }
fp->_file = f; fp->_file = f;
fp->_flags = flags; fp->_flags = flags;
@ -90,4 +101,7 @@ fopen(file, mode)
if (oflags & O_APPEND) if (oflags & O_APPEND)
(void) __sseek((void *)fp, (fpos_t)0, SEEK_END); (void) __sseek((void *)fp, (fpos_t)0, SEEK_END);
return (fp); return (fp);
release:
fp->_flags = 0; /* release */
return (NULL);
} }