| From: US6RMC::"[email protected]" "Frank Pfosi" 14-FEB-1997 16:39:48.75
To: mroa::mgreenfield
CC:
Subj:
/* Run this program with the file name you want to open, for example
a.out foo, I compiled this using the command line: cc <file.c>
This works on SunOS, HPUX, IREX, IBM.
*/
#include <stdio.h>
main (argc, argv )
char **argv;
int argc;
{
FILE *pxFile;
char pbPtr[50];
int fd;
fd = creat ( argv[1], 0666 );
pxFile = fdopen ( fd, "w" );
if ( ! pxFile )
perror ("Failed on mode w");
else
printf ( "Successfully opened %d using mode %s\n", fd, "w" );
fd = creat ( argv[1], 0666 );
pxFile = fdopen ( fd, "r+" );
if ( ! pxFile )
perror ("Failed on mode r+");
else
printf ( "Successfully opened %d using mode %s\n", fd, "w" );
}
% ====== Internet headers and postmarks (see DECWRL::GATEWAY.DOC) ======
% Received: from mail13.digital.com by us6rmc.mro.dec.com (5.65/rmc-17Jan97) id AA16755; Fri, 14 Feb 97 16:30:15 -0500
% Received: from jonah.chrysalis.com by mail13.digital.com (8.7.5/UNX 1.5/1.0/WV) id QAA02356; Fri, 14 Feb 1997 16:22:10 -0500 (EST)
% Received: from yoyodyne (yoyodyne.chrysalis.com [199.172.48.18]) by jonah.chrysalis.com (8.7.2/8.7.2) with ESMTP id QAA13875 for <[email protected]>; Fri, 14 Feb 1997 16:19:39 -0500 (EST)
% From: Frank Pfosi <[email protected]>
% Received: (from fpfosi@localhost) by yoyodyne (SMI-8.6/8.7.2) id QAA20361 for [email protected]; Fri, 14 Feb 1997 16:19:39 -0500
% Date: Fri, 14 Feb 1997 16:19:39 -0500
% Message-Id: <199702142119.QAA20361@yoyodyne>
% To: mroa::mgreenfield
|
| From: MROA::MGREENFIELD 17-FEB-1997 14:14:15.22
To: DECWRL::"[email protected]"
CC: FLUID::SAYLOR,FLUID::CLEMC,MGREENFIELD
Subj: response on your question regarding fdopen
Frank;
I discussed your issue and reproducer with a few of my
collegues and here is what we came up with:
o the mixing of the creat(2) and fdopen(3) system services
from IEEE P1003.1 was left slightly ambigous in the standard.
The >>intention<< of the standard was that the type argument to
fdopen(3) is used to inform the C standard I/O library how the file
descriptor was ``open-ed'' by UNIX. Since the C Standard I/O library
is defined by ISO/IEC 9899, ``Information technology - Programming
languages - C'', and the UNIX I/O definition is defined by the POSIX
standard (IEEE P1003.1-1990 aka ISO/IEC 9945-1:1990; the basic issue is
how the two are mixed together. And this mixing becomes of the crux of
the difficultly you are running into.
Some things that you might consider.
o The main problem is that you have created a new file with
the older creat(2) system service. In fact, P1003.1
defines the call:
creat (path, mode);
to be equivilent to:
open (path, O_WRONLY | O_CREAT | O_TRUNC, mode);
[See page 91, lines 288-290 of IEEE P1003.1-1990, section 5.3.2.2]
Note that creat(2) sets the mode to be write only (O_WRONLY).
o You then are trying to use fdopen(3) subsequently to
change the file mode to be read/write while you are setting up
the C standard I/O libraries buffering system.
At issue is that changing the mode between open(2)/creat(2)
and the call to fdopen(3) is not a well defined operation.
In fact, discussions here are fairly certain that the POSIX
standard is messed up and should be more precise in stating
you can not change it. One of our folks that worked on
setting both standards (he is an old type UNIX/C hacker) is
certain it was not an intended side effect - although
clearly, certain implementations allow it.
So the issue for you is how to make portable code, that follows
the standards as intended and should work on 100% of the systems
you encounter. So we played around with your code and and had some
success once we realized that the file fdopen(3)'ed for reading was
just creat(2)'ed, making it an empty file. When we changed the creat(2)
call to open(2) and used the proper arguments, your reproducer appears
to work as intended.
Therefore:
1. We recommend that you use open(2) system service directly
instead of older creat(2). Remember, in the POSIX rational
sections, creat(2) is depreciated and not recommended for
use in new code. Plus using open(2) will give you much
finer control of actual behavior the operating system will
garrentee after the file has been open(2)'ed for you.
Note: the POSIX designers defined open(2) and creat(2)
such that a sed script could be used to perform
such a global replacement .
2. Then ensure that the modes arguments to fdopen(3) agree
with the mode argument used by the open(2) system
service when the file was originally opened by the system.
To make you feel, better, when we reviewed the v4.0 man pages for
fdopen(3) we note that is exact problem is discussed. The ambigity
in the standard has been considered before:
> RESTRICTIONS
>
> Since a file newly created by creat() is write_only, an fdopen()
> call using the r+ parameter fails when following a creat() call.
> A solution to this problem is to create the file using a call
> that adheres to the following format:
>
> open(path, O_RDWR | O_CREAT, 0666);
>
The open questions we have not yet answered are:
o Why does this program run on other POSIX systems you have
and not Digital Unix?
o Is Digital interpreting the POSIX standard in a manner
others have either missed or chosen to allow the unusual
behavior because its existing practice (a ``defacto
standard'')
The standard too loose in this area, it should either formally
define that it is ``undefined'' as what changing the modes between
the calls mean (which means that if as a programmer you bet on
one behavior, your code is not portable) or it should define what
the behavior of the system should be: (allowed or defined error)
-- and thus the programmer can code one way or the other.
The key is that as programmers, the standard is no help. Digital UNIX
is 100% correct, as are the other implementations. This is why
we offer our recommendations to you. If you recode to the above, the
standard will give you full guidence as to what to expect. We know
this is work for you, and we do wish it was not so.
regards,
Mike
|
| From: US6RMC::"[email protected]" "Frank Pfosi" 17-FEB-1997 15:39:10.73
To: mroa::mgreenfield
CC:
Subj: Re: response on your question regarding fdopen
Thank you for your response. I came to the same conclusion, and have already
made the changes that you suggested, and every thing seems to work perfectly.
My initial intention was to open a stream that could be used either for
reading OR writing not both at the same time. The function was used in this way
so originally I did not know if the intended use of the open was for reading or
writing. My initial interpretation of fdopen allowed my to us it as an open
for reading or writing as long as any open file was not used for both. I changed
all calls to the function to specify the mode, and every thing now works on
all platforms
Thanks again for your speedy response
Frank Pfosi
% ====== Internet headers and postmarks (see DECWRL::GATEWAY.DOC) ======
|
| From: SMTP%"[email protected]" 17-FEB-1997 15:52:26.96
To: mgreenfield
CC:
Subj: Are you still running the POSIX Work?
------- Blind-Carbon-Copy
To: [email protected]
Subject: Are you still running the POSIX Work?
Really-From: Clement T. Cole
Organization: Technical Director, SPE; Digital Equipment Corp; 508-467-3614
X-Face: 3}V1_dLw'G]SyK"z1**jB);1uPOBSQWhKMARA<6*R$*<u1&P{fm(pEEZ49+O[V*=^q58cyL
-nya7k\\oP0HKdt0n0<g<w[Zvw_vmN1<vS"JVRzq1&xn]&qOhOf{s3P$G=o5opE5&-O,DR)HMwI<Zu
R!!iw~v&)#~/vp0Ni*\^MmNCD/5Y9|;z``%mqXMz];RLz+(,&(2Z1Rf8MQc?<:Y9S~Ee
Reply-To: [email protected]
Date: Mon, 17 Feb 97 15:51:25 -0500
From: clemc
X-Mts: smtp
We just ran into an ambigity in the POSIX standard and how
it relates to the C standard (in behavoir of fdopen). It turns
out Digital UNIX is implemented one way and other UNIXs another.
After reading and rereading, the standard IMHO is mucked up.
It needs to either formally:
- state that the behavior is undefined (and God help the
programmer who relies on the behavior) -- which is the
easiest way out, but I think wrong.
- or define what the behavior is:
i.e. that this is allow or dis-allowed.
[frankly, I think in this case it should be an
error - which is what DUNIX does. But.. their
may be case to allow it, since other UNIX do allow it].
Having it fuzzy is bad, because System Vendors can claim conformance
in any case, and applicaton programmers have no guidence one
way or the other.
I'll send you the details if you want. But I want to formally
send this one in for .1 to consider in the next draft/update.
Clem
------- End of Blind-Carbon-Copy
================== RFC 822 Headers ==================
|
| From: FLUID::saylor "Gerrit Saylor 14-Feb-1997 1749" 14-FEB-1997 17:49:42.42
To: mgreenfield@dec:.mro.mroa
CC: [email protected]
Subj:
Mike,
I played around with this and had some success once I realized
that the file fdopen()'ed for reading was just created, making
it an empty file. I chnaged the creat() call to open() and everything
worked.
I then reviewed the v4.0 man pages for fdopen:
RESTRICTIONS
Since a file newly created by creat() is write_only, an fdopen() call using
the r+ parameter fails when following a creat() call. A solution to this
problem is to create the file using a call that adheres to the following
format:
open(path, O_RDWR | O_CREAT, 0666);
Note that this doesn't show up in v3.2 pages, and a customer wouldn't see this.
I hope this clears things up,
Gerrit
\
|