[net.unix-wizards] fdopen

Satz%sri-tsc@sri-unix.UUCP (06/15/83)

From:  Greg Satz <Satz@sri-tsc>


With all of the explainations flying around, I still haven't figured
out why you would ever want to do the fdopen(open(... sequence in lieu
of a plain fopen(...

The bug fix that was mailed out previously that split them into two
different operations would, in my opinion, almost always be preferred
in this type of situation. But why is it necessary to do an open and an
fdopen?

berry@fortune.UUCP (06/22/83)

#R:sri-arpa:-217100:fortune:11600021:000:80
fortune!berry    Jun 21 19:15:00 1983

	One needs the file descriptor to do the ioctl calls
that turn echo on and off.

edhall%rand-unix@sri-unix.UUCP (06/24/83)

You can always use the fileno() macro to get the file descriptor.
As near as I can tell, the re-open is to set read/write access,
as fopen() can only provide read-only or write-only opens.

		-Ed

johnl@ima.UUCP (06/25/83)

#R:sri-arpa:-217100:ima:20400008:000:880
ima!johnl    Jun 24 14:58:00 1983

As far as I can tell, there are a few situations where you might want to
do an fdopen() call on an open file descriptor.

	1.  When you want to open a pipe, and popen() isn't quite right.

	2.  When, due to some local convention, you have a file passed
	    already open on, say, fd 3 and you want to use that file.

	3.  When you want to open a tty file for read and write, and use
	    separate stdio FILEs for reading and writing (to avoid the
	    flushing and other funniness when you open something "r+".)

	4.  When, under Sys III at least, you want to use open flags such
	    as NOWAIT, you have to do the open yourself and then fdopen.

You don't need fdopen just to do an ioctl() or fstat() call, since the
macro "fileno(iop)" gets you the file number of an open FILE.

John Levine, decvax!yale-co!jrl, ucbvax!cbosgd!ima!johnl,
{research|allegra|floyd|amd70}!ima!johnl

jmc@root44.UUCP (07/07/83)

But you can get the file descriptor with 'fileno'!!!!

	John M Collins
	Root Computers Ltd
		...!vax135!ukc!root44!jmc

hartwell%shasta@sri-unix.UUCP (11/06/83)

From:  Steve Hartwell <hartwell@shasta>

I have a daemon that calls a routine (repeatedly), passing a file descriptor
open on a file.  The routine does an lseek(fd, 0L, 0) and then calls
fdopen() on it, because it would like to use stdio to read the file via getc().

The problem is that after <N> calls to the routine, fdopen() returns NULL
because it runs out of FILE pointers (there is a static array of them in
stdio).  I don't want to use fclose(), that would close the file descriptor.

Anyone know a way to release a FILE pointer without closing the file itself?
Poking into the structure is not a solution I would like to consider.

This is for a 4.1BSD system.

Thanks,
    Steve Hartwell, Stanford

gwyn%brl-vld@sri-unix.UUCP (11/06/83)

From:      Doug Gwyn (VLD/VMB) <gwyn@brl-vld>

There is no direct way to free a FILE pointer without closing the file
descriptor.  However, if you dup() (or fcntl()) the descriptor first,
then the "close" will amount to a no-op insofar as its effects on the
inode attached to the file descriptor are concerned.  You can fclose()
the stream, dup() the duplicate fd back to its original value, then
close out the duplicate file descriptor and proceed to fdopen() as
before.

greep%su-dsn@sri-unix.UUCP (11/06/83)

You can do a dup() on the file descriptor first, then the close() done
by fclose() won't really caused the file to be closed.  Of course you'll
have to keep track of the new file descriptor returned by dup().

However, (at least in 4.1bsd) _NFILE in stdio.h is set to 20, the same
value is the number of open files per process the kernel lets you have
(defined in NOFILE in /usr/sys/h/param.h), so if you're running out of
stdio buffers, you'll probably run out of file descriptors pretty soon.

phil.rice%rand-relay@sri-unix.UUCP (11/07/83)

From:  William LeFebvre <phil.rice@rand-relay>

   "The problem is that after <N> calls to the routine, fdopen() returns NULL
    because it runs out of FILE pointers (there is a static array of them in
    stdio).  I don't want to use fclose(), that would close the file
    descriptor.
    
    Anyone know a way to release a FILE pointer without closing the file
    itself?  Poking into the structure is not a solution I would like to
    consider."

Rather than doing the fdopen on the original file descriptor (with
fdopen(fd, ...)), you could do a fdopen(dup(fd), ...).  Then you can
call fclose() and not worry about the original file descriptor getting
closed.  Offhand, I think that this is the only way, short of mucking
around in _iob[], that you can do what you want to do.  The major
drawback to this scheme, of course, is that you can run out of file
descriptors (instead of FILE *'s) if you do this alot.

                                William LeFebvre
                                ARPANet: phil.rice@Rand-Relay
                                CSNet:   phil@rice
                                USENet:  ...!lbl-csam!rice!phil

bob%ucla-locus@sri-unix.UUCP (11/07/83)

From:            Bob English <bob@ucla-locus>

If you don't intend to close the file, why pass a different FILE
structure each time you call the routine?  Why not set up one
and use it every time?

--bob--

keesan@bbncca.ARPA (Morris Keesan) (11/08/83)

---------------------------------
It seems to me inefficient to keep doing the fdopen() in the called subroutine.
Why not just have the upper level daemon do a fdopen() ONCE, or have it do a
fopen() instead of open(), and then call the subroutine repeatedly with the
stream pointer?  The subroutine would then just have to do fseek(stream,0L,0)
and start using getc(), instead of using lseek() and then mucking around with
fdopen() and dup() and file descriptors.
					    Morris M. Keesan
					    decvax!bbncca!keesan
					    ihnp4!wjh12!bbncca!keesan

colonel@sunybcs.UUCP (George Sicherman) (11/11/83)

he whole idea is unsound.  stdio buffers ahead, so you
cannot just abandon the stream and start another one.
If you cannot find a way to use a single FILE pointer,
you are better off read-ing char by char (to end-of-line?)
and sscanf-ing.