[comp.unix.wizards] ultrix 2.0 _iob storage

jon@jim.odr.oz (Jon Wells) (10/05/88)

G'day,

Just wondering how _iob in declared in real unix systems 
(ones that dec hasn't got at).

I found a piece of code in Kyoto Common Lisp which does....

    ..
nfiles = getdtablesize();
for ( p = &_iob[3]; p < _iob[nfiles]; p++ )
	fclose(p);
    ..

Eg. charges though _iob trying to close any stream that's open
 (apart from stdin/stdout/stderr).

You can't do this with ultrix (2.0) as _iob is only 3 slots long, all
other struct _iobuf's are allocated dynamically so &_iob[3]....
just points off into the weeds.

Is the above code deemed to be a reasonable way of doing this?

Ultrix provides a function called _fwalk() which, given a pointer to a
function, will call that function for every open stream passing it the
FILE *.

It's totally undocumented, I grep'd through every manual entry looking
for it (I found it by tracing exit(), it's name looked interresting in
nm's output).

Is _fwalk() standard on other genders of unix???
Does every one else store all the _iobuf's in _iob as one array?
Is this another dec knows best????
Or is there a much better way of closing everything but stdin etc.????

jon
-- 

jon@jim.odr.oz (Jon Wells) (10/24/88)

[attempt two, sorry if you've seen this before, I may have messed
up the posting, anyway, I didn't get any response and I'd like to know]

G'day,

Just wondering how _iob in declared in real unix systems 
(ones that dec hasn't got at).

I found a piece of code the other day.....

    ..
#ifdef BSD
nfiles = getdtablesize();
#else
nfiles = NFILES;
#endif
    ..
for ( p = &_iob[3]; p < _iob[nfiles]; p++ )
	fclose(p);
    ..

Eg. charges though _iob trying to close any stream that's open
 (apart from stdin/stdout/stderr), ignoring any errors from fclose().

You can't do this with ultrix (2.0) as _iob is only 3 slots long, all
other struct _iobuf's are allocated dynamically so &_iob[3]....
just points off into the weeds.

Is the above code deemed to be a reasonable way of doing this?

Ultrix provides a function called _fwalk() which, given a pointer to a
function, will call that function for every open stream passing it the
FILE *.

It's totally undocumented, I grep'd through every manual entry looking
for it (I found it by tracing exit(), it's name looked interresting in
nm's output).

Is _fwalk() standard on other genders of unix???
Does everyone else store all the _iobuf's in _iob as one array?
Is this another dec knows best????
Or is there a much better way of closing everything but stdin etc.????

jon
-- 


-- 

gwyn@smoke.BRL.MIL (Doug Gwyn ) (10/28/88)

In article <575@jim.odr.oz> jon@jim.odr.oz (Jon Wells) writes:
>#ifdef BSD
>nfiles = getdtablesize();
>#else
>nfiles = NFILES;
>#endif
>for ( p = &_iob[3]; p < _iob[nfiles]; p++ )
>	fclose(p);
>Is the above code deemed to be a reasonable way of doing this?

No, of course not.  One wonders what the code REALLY needed to do,
since this attempted drastic action would seldom be called for.

>Is _fwalk() standard on other genders of unix???

No _-prefixed identifier other than _exit is standard.

>Does everyone else store all the _iobuf's in _iob as one array?

No.  Many recent implementations dynamically allocate all but the
first three FILE structures.

>Or is there a much better way of closing everything but stdin etc.????

If an implementation conforms to the (proposed) ANSI C standard,
which most won't do for some time to come, then you can use
fflush((FILE*)NULL) to force buffered output to be sent to the
system.  Normally you only worry about this right before a fork,
and since most forks do no stdio before performing an exec, all
they need to do in this regard after the fork is to close the
extra file descriptors (not even trying to worry about stdio
streams).

If a process has any business closing stdio streams, it should
keep track of the handles (FILE *) for each open stream and use
them for this purpose.

Closing the standard streams can be a problem in some cases,
since for example it could remove all access to the controlling
terminal.

chris@mimsy.UUCP (Chris Torek) (10/28/88)

In article <575@jim.odr.oz> jon@jim.odr.oz (Jon Wells) writes:
>[attempt two, sorry if you've seen this before, I may have messed
>up the posting, anyway, I didn't get any response and I'd like to know]

(I saw a response, but anyway...:)

>[found code that reads]
>for ( p = &_iob[3]; p < _iob[nfiles]; p++ )
>	fclose(p);

>You can't do this with ultrix (2.0) as _iob is only 3 slots long, all
>other struct _iobuf's are allocated dynamically so &_iob[3]....
>just points off into the weeds.

The same is true in 4.3BSD, except that NSTATIC _iob's exist.  NSTATIC
happens to be 20.

>Is the above code deemed to be a reasonable way of doing this?

No.

>Ultrix provides a function called _fwalk() ....

Also found in 4.3BSD.  (Guess which group invented it. :-) )

>Is _fwalk() standard on other genders of unix???

No.

>Or is there a much better way of closing everything but stdin etc.????

No.  What you can do in the presence of a dpANS-conformant system is this:

	(void) fflush((FILE *)NULL);
	for (fd = 3; fd < nfiles; fd++)
		(void) close(fd);

which leaves the FILEs open but closes the underlying descriptors, after
pushing any pending output.  If you are about to exec()---this is the
only reasonable use for the above---it will work.  But nobody handles
fflush(NULL) yet.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

guy@auspex.UUCP (Guy Harris) (10/28/88)

>You can't do this with ultrix (2.0) as _iob is only 3 slots long, all
>other struct _iobuf's are allocated dynamically so &_iob[3]....
>just points off into the weeds.
>
>Is the above code deemed to be a reasonable way of doing this?

It's definitely not *portable*.  Whether it's reasonable is another
matter.  If you really truly desperately need to do it, it might be
reasonable.... 

>Is _fwalk() standard on other genders of unix???

It's probably present on systems that have picked up a large chunk of
their standard I/O from 4.3BSD (SunOS 3.2 and later has it).

>Does everyone else store all the _iobuf's in _iob as one array?

Systems with UNIX-derived standard I/O libraries, and that haven't
picked up the dynamically-growing _iob stuff from 4.3BSD, probably don't
have "_fwalk()" and probably have all the "_iobuf"s in "_iob" as one
array.

Systems with UNIX-derived standard I/O libraries that *have* picked up
the dynamically-growing "_iob" stuff from 4.3BSD, probably have
"_fwalk()" and probably do *not* store *all* their "_iobuf"s in "_iob"
as one array.  However, they probably have more like 20 of them in
"_iob"; as I remember it, one of the 4.3BSD beta versions had only
"stdin", "stdout", and "stderr" static, with all of the others
dynamically allocated, and it was upped to 20 in the final 4.3BSD
version.

>Is this another dec knows best????

Hard to say.  Some of the idea is Berkeley's; I don't know if DEC has
only 3 there because they're still using the beta code or because they
picked up the final code and decided the beta code had the right idea
there.

>Or is there a much better way of closing everything but stdin etc.????

Unfortunately, I don't know of one.  I vaguely remember there were
discussions either in the ANSI C or POSIX committees about having a way
of closing *everything*, but I don't think there was any way to iterate
over all FILEs and call a function on each one.