hae@mbf.UUCP (Hae Hirdler) (12/01/89)
The man page on the fdopen states that "the type of the stream must agree with the mode of the open file." But, when a file is open()'ed ( fd= open (filename, oflag) ), and fdopen()'ed for a stream ( fptr= fdopen (fd, mode) ), it allows this open file to be opened for any type of a stream regardless of the type of oflag already open()'ed. For example, fd= open(filename, O_RDONLY); fptr= fdopen(filename, "w") will return a NON_NULL fptr value instead of NULL. The semantics of the man page on the fdopen seems to indicate that this should not be allowed. (return NULL) Is this a known bug? or what? - Hae Hirdler
gwyn@smoke.BRL.MIL (Doug Gwyn) (12/02/89)
In article <713@mbf.UUCP> hae@mbf.UUCP (Hae Hirdler) writes:
-The man page on the fdopen states that "the type of the stream must
-agree with the mode of the open file."
I believe by "mode" they mean "file access permissions".
-For example, fd= open(filename, O_RDONLY); fptr= fdopen(filename, "w")
-will return a NON_NULL fptr value instead of NULL.
O_RDONLY has nothing to do with the file. It is just a parameter to open().
cpcahil@virtech.uucp (Conor P. Cahill) (12/02/89)
In article <11723@smoke.BRL.MIL>, gwyn@smoke.BRL.MIL (Doug Gwyn) writes: > In article <713@mbf.UUCP> hae@mbf.UUCP (Hae Hirdler) writes: > -The man page on the fdopen states that "the type of the stream must > -agree with the mode of the open file." > > I believe by "mode" they mean "file access permissions". Why would it have to do with the file permissions? The only thing fdopen does is associate a file pointer with a file descriptor. Besides, if you open a file with O_RDONLY and then fdopen it with "w", the buffer flushes will fail because the "status flags" for the file descriptor do not allow write. This is even the case when the access permissions do permit write. I think the problem is caused by the fact that older unixs did not have an ability to obtain the current status flags for a file descriptor. Therefore the fdopen() had no way to determine whether or not the fd mode and the fdopen mode matched. Both System V and BSD (at least 4.3, not sure about prior) provide the F_GETFL functionality in fcntl() which can be used to determine the flags used to open the file (like O_RDONLY...). fdopen() should be modified to check this and return NULL if appropriate. > -For example, fd= open(filename, O_RDONLY); fptr= fdopen(filename, "w") > -will return a NON_NULL fptr value instead of NULL. > > O_RDONLY has nothing to do with the file. It is just a parameter to open(). It has everything to do with accessing data in the file via the file descriptor. Since fdopen uses the file descriptor (not the file name as is displayed above) it will also have an effect on the correct usage of the file pointer returned by fdopen(). As an example, the following code will return an error at either the fprintf or the fclose() (usually the fclose since that is where the buffer is flushed). #include <stdio.h> #include <fcntl.h> main() { int fd,status; FILE * fp; if( (fd=open("test",O_RDONLY)) == -1) exit(1); if( (fp=fdopen(fd,"w")) == NULL) exit(2); printf("cnt = %d\n", fprintf(fp,"this is a test\n")); printf("fclose returned %d\n", fclose(fp)); exit(0); } -- +-----------------------------------------------------------------------+ | Conor P. Cahill uunet!virtech!cpcahil 703-430-9247 ! | Virtual Technologies Inc., P. O. Box 876, Sterling, VA 22170 | +-----------------------------------------------------------------------+
peter@ficc.uu.net (Peter da Silva) (12/03/89)
Doug Gwyn isn't often wrong, but... In article <11723@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: > In article <713@mbf.UUCP> hae@mbf.UUCP (Hae Hirdler) writes: > -The man page on the fdopen states that "the type of the stream must > -agree with the mode of the open file." > I believe by "mode" they mean "file access permissions". No, they mean the second argument to open(). But I don't believe it's possible to determine what the mode of a file descriptor is by examining it, so: > -For example, fd= open(filename, O_RDONLY); fptr= fdopen(filename, "w") > -will return a NON_NULL fptr value instead of NULL. Yes, but writes to the file may fail. There's no safe way of checking this from fdopen. I suppose a write(fd, "", 0) will work as a check. I don't know what this might do on some files (tape drives, for example). I said may, not will, because if the file descriptor refers to a terminal you can write to it even if it's opened O_RDONLY. > O_RDONLY has nothing to do with the file. It is just a parameter to open(). Yes, a parameter that determines the mode of the file descriptor. When you try to write to a file opened O_RDONLY you will get an error EBADF. The manual is correct, you should make the modes agree. The code doesn't check, so you won't get an error, but don't do it anyway. -- `-_-' Peter da Silva. +1 713 274 5180. <peter@ficc.uu.net>. 'U` Also <peter@ficc.lonestar.org> or <peter@sugar.lonestar.org>. "The basic notion underlying USENET is the flame." -- Chuq Von Rospach, chuq@Apple.COM
cpcahil@virtech.uucp (Conor P. Cahill) (12/03/89)
In article <7190@ficc.uu.net>, peter@ficc.uu.net (Peter da Silva) writes: > Doug Gwyn isn't often wrong, but... > > In article <11723@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: > > In article <713@mbf.UUCP> hae@mbf.UUCP (Hae Hirdler) writes: > > -The man page on the fdopen states that "the type of the stream must > > -agree with the mode of the open file." > > > I believe by "mode" they mean "file access permissions". > > No, they mean the second argument to open(). But I don't believe it's > possible to determine what the mode of a file descriptor is by examining > it, so: Yes it is. fcntl(fd,F_GETFL) returns the status flags of an open file descriptor. > > -For example, fd= open(filename, O_RDONLY); fptr= fdopen(filename, "w") > > -will return a NON_NULL fptr value instead of NULL. > > Yes, but writes to the file may fail. There's no safe way of checking this > from fdopen. I suppose a write(fd, "", 0) will work as a check. I don't > know what this might do on some files (tape drives, for example). > > I said may, not will, because if the file descriptor refers to a terminal > you can write to it even if it's opened O_RDONLY. This is not true on System V and I would expect it to not be true on any unix system because the access mode for a file descriptor is checked before any call to a device driver read/write routines. What you may be confusing it with is the ability to do a fdopen(0,"w"); to get another file pointer to stdin, but this file descriptor is really opened for read and write, so the fdopen() for a subset of the capabilities will succeed (and work). > The manual is correct, you should make the modes agree. The code doesn't > check, so you won't get an error, but don't do it anyway. The code can, and should, check. These capabilities have existed since System V.2 and at least 4.3BSD (not sure about prior BSD releases. -- +-----------------------------------------------------------------------+ | Conor P. Cahill uunet!virtech!cpcahil 703-430-9247 ! | Virtual Technologies Inc., P. O. Box 876, Sterling, VA 22170 | +-----------------------------------------------------------------------+
gwyn@smoke.BRL.MIL (Doug Gwyn) (12/05/89)
In article <7190@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes: >Doug Gwyn isn't often wrong, but... But I did make a mistake this time. Sorry. (That's what I get for posting when under the influence of a bad cold.)
guy@auspex.auspex.com (Guy Harris) (12/07/89)
>The man page on the fdopen states that "the type of the stream must >agree with the mode of the open file." But, when a file is open()'ed >( fd= open (filename, oflag) ), and fdopen()'ed for a stream >( fptr= fdopen (fd, mode) ), it allows this open file to be opened for >any type of a stream regardless of the type of oflag already open()'ed. >For example, fd= open(filename, O_RDONLY); fptr= fdopen(filename, "w") >will return a NON_NULL fptr value instead of NULL. A non-null but useless "fptr" value. "Must" can either be read as "'fdopen()' will reject your request if the type of the stream does not agree with the mode of the open file" or "if the type of the stream does not agree with the mode of the open file, the resulting stream won't be usable." It doesn't explicitly say that it does those checks, so an implementation that doesn't perform them is valid. Prior to the appearance of the "fcntl()" call in System III it would, in fact, have been impossible to perform those checks without potential risk to the file; the only way to find out if a file descriptor is open for reading was to try and read it, and the only way to find out if a file descriptor is open for writing was to try and write to it.... I suspect they either didn't even consider the possibility of adding those checks once "fcntl" allowed you to see the file descriptor flags, or they considered it unnecessary to do so, since presumably a programmer is smart enough not to ask the system to make a standard I/O stream open for writing out of a file descriptor open for reading.... (If the "fdopen()" is buried inside a routine that can be handed an arbitrary file descriptor and/or an arbitrary open mode, the argument is merely applied to calls to that routine rather than calls to "fdopen()".) >The semantics of the man page on the fdopen seems to indicate that >this should not be allowed. (return NULL) Nope. It doesn't say so explicitly; it doesn't, in fact, indicate what the possible failure modes of "f*open()" are.
hae@mbf.UUCP (Hae Hirdler) (12/07/89)
In article <1989Dec3.130758.27151@virtech.uucp>, cpcahil@virtech.uucp (Conor P. Cahill) writes: >>In article <7190@ficc.uu.net>, peter@ficc.uu.net (Peter da Silva) writes: >>... >>The manual is correct, you should make the modes agree. The code doesn't >>check, so you won't get an error, but don't do it anyway. > >The code can, and should, check. These capabilities have existed since >System V.2 and at least 4.3BSD (not sure about prior BSD releases. I agree with both of the responses. We could say that 'the manual is correct' in the sense that it plants a bomb if the mode of fdopen() doesn't match with the oflag of the open()'ed file, and it will explore when fclose() or fflush() is called. But, I think that the man page is misleading in the sense that, if no error is received after fdopen(), it may let you assume that everything is ok so far. This will only make a debugging harder. I don't see what we are gaining here with this sneaky attack. To fully support the man page statement, I think the fdopen() code should be modified to include the error checking on the mode. (Specially, now the tools are available - fcntl(fd, F_GETFL), as Conor P. Cahill points out.) - hae hirdler