From: terry@cs.weber.edu (A Wizard of Earth C)
Newsgroups: comp.unix.bsd
Subject: Re: getdtablesize
Date: 30 Sep 92 16:47:45 GMT
Article-I.D.: fcom.1992Sep30.164745.13200
Organization: Weber State University  (Ogden, UT)

In article <1992Sep29.142535.21001@nntp.hut.fi> alo@kampi.hut.fi (Antti Louko) writes:
>In article <Bv7Dz7.C2o@BitBlocks.com> bvs@BitBlocks.com (Bakul Shah) writes:
>>tlukka@vipunen.hut.fi (Tuomas Lukka) writes:
>>>for(i=getdtablesize(); --i>2; close(i));
>>>and getdtablesize returned something like 2000000000 and this
>>>naturally would take a while to run... 
>
>>Another culprit is popen(). It attempts to allocate an array to hold
>>getdtablesize() number of descriptors and fails under zsh.
>
>>Now I don't think what zsh is doing is wrong.  The problem is in
>>the use of getdtablesize() in popen() and the code above.  What is
>>needed is a system call that returns the highest *open* file
>>descriptor number.
>
>Actually, an even better solution is to have a system call
>
>getdescriptors(firstfd,dtable,dtablesize)
>
>int	firstfd;
>int	dtable[];
>int	*dtablesize;
>
>On entry *dtablesize tells how big dtable is. On return, kernel fills
>dtable with at most *dtablesize open file descriptors which are >=
>firstfd.

Obviously, the value you are seeing for getdtablesize() is wrong... are
you sure it is either undeclared or declared as an external int?  I get
64 ...of course, my kernel is patched to all get out, but I don't believe
any of them effected the open files tables.

I tried declaring the function extern short, int, and double, but always
got 64.

I really don't understand what a "getdescriptors()" call would buy you,
besides not having to accumulate the "nfds" parameter to select().  You
can't "save" and "restore" descriptor tables from user space anyway, and
you should know what descriptors you have opened in your own program.

The only possible failure mode in "popen()" that I see is clearly
commented as "/* parent; assume fdopen can't fail...  */"; for this
to be true, the section of code that reads:

        if (*type == 'r') {
                iop = fdopen(pdes[0], type);
                (void) close(pdes[1]);
        } else {
                iop = fdopen(pdes[1], type);
                (void) close(pdes[0]);
        }

Should probably read:

        if (*type == 'r') {
                (void) close(pdes[1]);
                iop = fdopen(pdes[0], type);
        } else {
                (void) close(pdes[0]);
                iop = fdopen(pdes[1], type);
        }

Just to be clean about things.


The only other potential problem is the use of vfork(), since the dup2()
call may still effect the parent (the make memory leak problem), and
*will* eat some memory from the parent for the childs environment.  This
could eventaully cause a crash, but it would probably take a *lot* of
pipes over a *long* period of time.


					Terry Lambert
					terry@icarus.weber.edu
					terry_lambert@novell.com
---
Any opinions in this posting are my own and not those of my present
or previous employers.
-- 
-------------------------------------------------------------------------------
                                        "I have an 8 user poetic license" - me
 Get the 386bsd FAQ from agate.berkeley.edu:/pub/386BSD/386bsd-0.1/unofficial
-------------------------------------------------------------------------------