[mod.std.unix] limits

std-unix@ut-sally.UUCP (Moderator, John Quarterman) (11/15/85)

From seismo!philabs!flkvax!trwrb!desint!geoff (Geoff Kuenning)
Date: Thu, 14 Nov 85 23:47:29 GMT

I support the idea of making the limits available at run-time, but
let's not copy Berkeley's naming (getdlimit or whatever it is).  There
should be just *one* call that gets all the limits into a struct;
Berkeley compatability can be achieved with "wrapper" routines.

UniSoft has already done 90% of the work of this call by moving
everything that used to be in param.h into a structure named 'v'.  This
was done so that binary customers could patch NPROC et al easily, but a
system call that returned the contents of 'v' would be trivial to add.
Maybe we could get AT&T to buy the changes (they're extensive) from UniSoft.

[ 3B20 System V Release 2 has this, so maybe they did.
Personally, I don't like it.  -mod ] 
-- 

	Geoff Kuenning
	{hplabs,ihnp4}!trwrb!desint!geoff

Volume-Number: Volume 3, Number 18

std-unix@ut-sally.UUCP (Moderator, John Quarterman) (11/16/85)

Date:     Fri, 15 Nov 85 11:10:55 EST
From: Dan Franklin <dan@BBN-PROPHET.ARPA>

> ... There
> should be just *one* call that gets all the limits into a struct;
> Berkeley compatability can be achieved with "wrapper" routines.

I agree that there should be one system call, but not this one.  This one means
that if a manufacturer wants to add a limit in a later version of the system
(either in response to a change to the standard, or to enhance his system) it's
once again necessary to recompile everything that might use the system call, in
order to be able to return the larger structure.  You can solve this problem by
defining the system call to take a pointer and a length, rather than just a
pointer; then the only time recompilation is necessary is if a limit is deleted
(and you want to reclaim the structure element).  But why should it be
necessary at all?

Instead of one system call which returns *everything*, there should be one
system call which takes a numeric index "naming" the limit to be returned.  An
index of 0 would return the total number of limits. Limits.h would give the
indices.

Letting the system call "know" what limit you're actually interested in also
permits (in theory) programs to be monitored (in the kernel) to see what limits
they are requesting, so that you can know ahead of time what programs would
benefit from changing what parameters.

	Dan

Volume-Number: Volume 3, Number 21

std-unix@ut-sally.UUCP (Moderator, John Quarterman) (11/20/85)

[ One thing to remember in this discussion is that standards committees
are loath to attempt to standardize and innovate at the same time.
In this particular posting (as in any others), note that parenthetical
remarks in square brackets are those of the moderator only if they end
with -mod ]

Date: Tue, 19 Nov 85 10:00:44 cst
From: allegra!jpl

> Date: Sat, 16 Nov 85 15:11:46 est
> From: seismo!hadron!jsdy (Joseph S. D. Yao)
> 
> Reading in limits on a per-machine basis is a good idea.
> However, the idea of reading in a struct or using a numerical
> ID for limits both constrain expandability.  I also have
> problems with reading directly from limits.h.  Let's do it
> from a file like /etc/limits.

Let's kick it around a little first.  I agree with your decision to
keep this out of the kernel, but I'll amplify to avoid misunderstandings.

1)  I want a general mechanism that applies to all include
    files, not just limits.h.

2)  The kernel is a lousy place to store the limits.h information.
    It is preposterous to have a separate system call for each
    value.  If you return a structure that includes all the values,
    you trash existing binaries whenever you make the returned
    structure larger by adding another value.  If you use an index
    to return a single value, you can only port to systems that
    agree with you on the index values.

3)  It is unworkable.  If I want to run my code on a kernel where
    the maintainers (wisely) refused to clutter up their system,
    not only can I not port my binaries, I can't even port my
    source code.

KEEP THIS AT USER LEVEL WHERE IT BELONGS! AND WHERE WE CAN CONTROL IT!!!
[Pardon me, I seem to be getting carried away in a moderated newsgroup.]
[ Now that you mention it....  -mod ]

My major gripe with Joseph's solution is point 1) above [although his
program can be made to serve for other include files] together with a
hard-earned awareness that duplicating information from limit.s in a
file like /etc/limits WITHOUT ENFORCING THE CONSISTENCY OF THAT
INFORMATION is a sure recipe for disaster.  So let's try to address the
problems with reading directly from limits.h.  To keep the discussion
concrete, I have a first-cut at such a program at the end of this
diatribe.  Type lines like
    <stdio.h> _NFILE NULL frobaz
at it, and it will tell you what the values of _NFILE, NULL and frobaz
are according to include file <stdio.h>.  If you actually run the
program, you will recognize one problem.  It's slow.  I claim this is
a non-problem: look up your values once, and then run nice and fast.
If you READ the program (unencumbered as it is by comments), you will
discover more serious problems.

1)  The program uses ``cc -E'' and ``sed'' to extract the information.
    I can't glibly laugh this one off.  If you don't have cc (the sed
    part could be built into the program) on the target machine, you
    can't look up the values.  I see this as by far the most serious
    problem, even though all the machines I use have cc.

2)  It relies on unpromised characteristics of the C preprocessor.
    The value to be looked up gets sandwiched between ``=== '' and
    `` ===\n'', and sed expects to find the value on a line of this
    form.  The preprocessor is free to tamper with the format of
    the line, although, on all the machines I have tried it on, it
    leaves the format alone.  This is not such a big deal.  In a
    practical implementation, the action of sed should probably be
    replaced by more robust [and efficient] code in the lookup
    routine.  Another alternative would be to generate a real
    C program, compile it and execute it to generate the results.
    This would eliminate any peculiarities of the preprocessor,
    but it would mean that the include file be syntactically
    complete.  For example, you couldn't have any undefined externs,
    or undeclared types.  [I have railed elsewhere on the value of
    of making all #include files idempotent, and then always including
    everything you need.  I'll spare you a playback.]

3)  It only applies to #defined constants.  Another non-problem.
    Variables should be initialized using #defined constants anyway,
    so there should be a #defined constant around to use.

4)  The runtime environment is lacking all sorts of -D and -I
    arguments and the working directory that may make a difference
    at compile time.  Two answers: if they REALLY make a difference,
    neither a kernel-based nor a fixed table-based solution will do
    any better.  In fact, it would be real nice if this information
    were available in symbolic form at compile time, so one could
    drop the information in the object code, as one does with SCCS
    or RCS information.  It would often be invaluable to be able to
    snuffle through a binary and determine what compile-time options
    were used to produce it.  If that were possible (I won't hold my
    breath), the lookup routine could more nearly duplicate what
    happened at compile time, and address the gripe about the lack
    of #if's.

Enough from me for now.  The promised code follows.

John P. Linderman  Better Living through Portability  allegra!jpl

#include <stdio.h>

static char **
mkvect(file, lines)
    char *file;
    int lines;
{
    FILE *iop;
    char **pp, *p;
    char *malloc();
    char **retval = (char **) NULL;
    int c;
    int chars = 0;
    int vects = 1;

    if ((lines > 0) && ((iop = fopen(file, "r")) != NULL)) {
	while ((c = getc(iop)) != EOF) {
	    chars++;
	    if (c == '\n') vects++;
	}
	if ((ferror(iop) == 0) && (lines == vects)) {
	    retval = (char **) malloc((vects * sizeof(char *)) + chars);
	    if (retval != (char **) NULL) {
		(void) clearerr(iop);
		(void) rewind(iop);
		p = (char *)(retval + vects);
		pp = retval;
		*pp++ = p;
		do {
		    if ((c = getc(iop)) == EOF) {
			(void) free((char *) retval);
			retval = (char **) NULL;
			break;
		    }
		    if (c == '\n') {
			*p++ = '\0';
			*pp++ = p;
		    } else *p++ = c;
		} while (--chars);
		if (c != EOF) *--pp = (char *) NULL;
	    }
	}
	(void) fclose(iop);
    }
    return (retval);
}


char **
rtlook(inc, val)
    char *inc;
    char **val;
{
#define NAMEZ 12
    static char tmplate[NAMEZ] = "/tmp/XXXXXX";
    char ifile[NAMEZ];
    char ofile[NAMEZ];
    char commnd[512];
    char *strcpy(), *mktemp();
    char **retval = (char **) NULL;
    int n = 1;
    FILE *iop, *popen();

    (void) strcpy(ifile, tmplate);
    (void) mktemp(ifile);
    if ((iop = fopen(ifile, "w")) != NULL) {
	(void) strcpy(ofile, tmplate);
	(void) mktemp(ofile);
	(void) fprintf(iop, "#include %s\n", inc);
	for (; (*val != NULL) && (**val != '\0'); n++, val++) {
	    (void) fprintf(iop, "\n#ifdef %s\n", *val);
	    (void) fprintf(iop, "=== %s ===\n", *val);
	    (void) fprintf(iop, "#else\n");
	    (void) fprintf(iop, "===  ===\n");
	    (void) fprintf(iop, "#endif\n");
	}
	if ((fflush(iop) != EOF) && !ferror(iop) &&
	    (fclose(iop) != EOF)) {
	    (void) sprintf(commnd,
		    "cc -E %s | sed -n '/^=== \\(.*\\) ===$/s//\\1/p' > %s",
		    ifile, ofile);
	    (void) system(commnd);
	    retval = mkvect(ofile, n);
	    (void) unlink(ofile);
	}
 	(void) unlink(ifile);
    }
    return (retval);
}


#include <ctype.h>

main()
{
    char line[512];
    char *p, **qq, **pp, *q[300];
    int n;

    while (gets(line) != NULL) {
	for (p = line, pp = q; *p;) {
	    while (isspace(*p)) *p++ = '\0';
	    if (*p) {
		*pp++ = p;
		do p++; while(*p && !isspace(*p));
	    }
	}
	*pp = NULL;
	if (pp != q) {
	    if ((qq = rtlook(q[0], q+1)) == NULL) {
		(void) printf("lookup failed\n");
	    } else {
		n = 0;
		for (pp = q+1; (*pp != (char *) NULL) && **pp; pp++, n++) {
		    (void) printf("%s => %s\n", *pp, qq[n]);
		}
		(void) free((char *) qq);
	    }
	}
    }
}

Volume-Number: Volume 3, Number 27

std-unix@ut-sally.UUCP (Moderator, John Quarterman) (11/20/85)

Date: Mon, 18 Nov 85 13:28:03 cst
From: ihnp4!uiucdcs!ccvaxa!preece@SEISMO.CSS.GOV (Scott Preece)

> From: Dan Franklin <dan@BBN-PROPHET.ARPA>
> Instead of one system call which returns *everything*, there should be
> one system call which takes a numeric index "naming" the limit to be
> returned.  An index of 0 would return the total number of limits.
> Limits.h would give the indices.
----------
I'd get rid of the numeric constants part of that, too.  Use a call
like getenv, supplying a name as an Ascii string.

But does this mean we would have to malloc space for anything that
was sized to a system limit (i.e., one could no longer say
	char buf[PATH_MAX]
but would have to do:
	char *buf;
	long bufsize;
	...
	bufsize = getlimit("PATH_MAX");
	if (bufsize >= 0)
		buf = (char *)malloc(bufsize);
	else
		perror("bufalloc:");
at run time?

Nobody ever said programming had to be easy, but this could
get old pretty quickly...

[ If the limits are taken from <limits.h>, presumably a program could,
if the programmer so chose, #include that file and size arrays at
compile time.  -mod ]

__
scott preece
gould/csd urbana
ihnp4!uiucdcs!ccvaxa!preece

Volume-Number: Volume 3, Number 28

std-unix@ut-sally.UUCP (Moderator, John Quarterman) (11/21/85)

Date: Sun, 17 Nov 85 16:28:42 PST
From: seismo!sun!gorodish!guy (Guy Harris)

> I support the idea of making the limits available at run-time, but
> let's not copy Berkeley's naming (getdlimit or whatever it is).  There
> should be just *one* call that gets all the limits into a struct;
> Berkeley compatability can be achieved with "wrapper" routines.

I wanted to make sure nobody introduced a routine to get the size of
the descriptor table with the same semantics as 4.2BSD's, but with a
different name.

> UniSoft has already done 90% of the work of this call by moving
> everything that used to be in param.h into a structure named 'v'.  This
> was done so that binary customers could patch NPROC et al easily, but a
> system call that returned the contents of 'v' would be trivial to add.
> Maybe we could get AT&T to buy the changes (they're extensive) from UniSoft.

You've got it backwards here.  The PWB/UNIX group at AT&T invented
the "v" structure; a lot of PWB/UNIX stuff, including the "v"
structure, made it into UNIX/TS 1.0 and subsequent releases from the
USG/USDL including S3 and S5.  UniSoft already bought that code from
AT&T, so there's no need to get AT&T to buy it back.

Volume-Number: Volume 3, Number 31

std-unix@ut-sally.UUCP (Moderator, John Quarterman) (11/21/85)

Date: Wed, 20 Nov 85 13:47:00 est
From: seismo!cbpavo.cbosgd.ATT.UUCP!mark (Mark Horton)

After looking at the cc -E / sed approach to reading limits.h, I
wanted to pass along a couple of other ideas.  (There are lots of
UNIX systems out there that don't have C compilers on line, in
particular, both Xenix and the AT&T 3B2 come without them until
you add them in, and they take up enough cash and disk space that
I'll bet many non-hackers won't install them.)

One idea is to do what netnews does to figure out the system name.
I'll enclose the code at the end (the code is public domain)
but basically it opens /usr/include/whoami.h and looks for a line
	#define sysname "whatever"
and extracts the "whatever".  It uses scanf, but hard code could be
written to make this a bit faster and more robust.  It does depend
on the full path name /usr/include/file.h, and it does expect the
#define to be in a reasonably standard format, but these aren't
overly cumbersome restrictions, are they?  (Dare we assume that
/usr/include will be there on all systems, even those without
compilers?)

Another idea is a bit more complex, but solves the "two copies of
the information" problem while still keeping a non-C file like
the proposed /etc/limits.  The idea is to keep a single copy in
/etc/limits, and use the obvious subroutine to get the values for
user code (which then has to malloc things.)  But the kernel has
to know these numbers too, and it's not exactly reasonable for the
kernel to go opening up a user file.  Perhaps a user program can be
written that will read the file, and download it into the kernel
with some kind of (system dependent) magic, such as poking in /dev/kmem,
or a special ioctl, or whatever.  Then the kernel can malloc the
appropriate data structures for the appropriate sizes.

This second idea has a chicken-and-egg problem, in that the data
structures better be allocated EARLY, and the obvious place to do
the downloading is /etc/rc, which is awfully late for such things.
One possibility is for /etc/init to do this before it does much of
anything else, although this is still probably too late (after all,
it has to open the file, and this means the file table has to exist.
Also, it's a process, so the process table must exist.)  One possibility
for handling this is for the kernel to have a very small set of minimal
tables to use until the real numbers come in, at which time it swings
a new pointer to the new tables.  (This is getting pretty ugly, isn't it?)

A third possibility is for the kernel to use the limits.h file, but
for /etc/rc to run a program that reads the values, translates them
into an easily parsed format (possibly binary), and puts these values
into /etc/limits.  Then the hard work is done only once per boot.
This might make it hard to write programs like fsck that run single
user, however.

	Mark

#define HDRFILE "/usr/include/whoami.h"

uname(uptr)
struct utsname *uptr;
{
        char buf[BUFSIZ];
        FILE *fd;
         
        fd = fopen(HDRFILE, "r");
        if (fd == NULL) {
                fprintf(stderr, "Cannot open %s\n", HDRFILE);
                exit(1);
        }
         
        for (;;) {      /* each line in the file */
                if (fgets(buf, sizeof buf, fd) == NULL) {
                        fprintf(stderr, "no sysname in %s\n", HDRFILE);
                        fclose(fd);
                        exit(2);
                }
                if (sscanf(buf, "#define sysname \"%[^\"]\"", uptr->nodename) == 1) {
                        fclose(fd);
                        return;
                }
        }
}

Volume-Number: Volume 3, Number 32

std-unix@ut-sally.UUCP (Moderator, John Quarterman) (11/22/85)

Date: Fri, 22 Nov 85 04:15:24 est
From: seismo!hadron!jsdy (Joseph S. D. Yao)

One person suggested that having separate <limits.h> and
/etc/limits files might lead to inconsistency.  True.  But
it was a deliberate (and, i apologise, unspoken) design
decision that reading limits.h implied knowing too much
about the machine -- such as how long are longs, what byte
order are ints vs longs vs ... (not to mention floats,
which I completely ignore below, and which I shouldn't!),
and so forth.  Reading a separate file gives me the freedom
to read an n-ary list of ints, formatted God Alone knows
how, which I can convert at my leisure to whatever I want.

Nevertheless, we aim to please, and I made the minor mods
to limits.c to make limits2.c, designed to read a single
int or long int from a define line.  As I said, I completely
ignored floats, which in a working program is unforgivable.
But the person who wants to read in floats may send me
(readable!) code to do so PORTABLY.

The following is a compressed context diff.

*** limits.c	Sat Nov 16 15:08:15 1985
--- limits2.c	Fri Nov 22 00:00:00 1985
***************
*** 66,73
  **	void endlimits()
! **	static int getnum(str)
  **
  ** Declared:
! **	static char limfile[] = "/etc/limits"
! **	static char *curlimfile = limfile
! **	static FILE *limf = (FILE *) NULL
  **
--- 66,75 -----
  **	void endlimits()
! **	static int getnum(str, buf, n)
! **	static int getnbits()
  **
  ** Declared:
! **	static char defn[]	= "#define"
! **	static char limfile[]	= "/etc/limits"
! **	static char *curlimfile	= limfile
! **	static FILE *limf	= (FILE *) NULL
  **
***************
*** 136,138
  #define NL	'\n'
! #define COMMENT	'#'
  #define COMMA	','
--- 138,141 -----
  #define NL	'\n'
! #define COMM1	'/'
! #define COMM2	'*'
  #define COMMA	','
***************
*** 141,145
  
! static char limfile[] = "/etc/limits";
! static char *curlimfile = limfile;
  
! static FILE *limf = (FILE *) NULL;
  
--- 144,158 -----
  
+ #ifdef	EBUG
+ #define WDPLG	2
+ #  else
+ #define WDPLG	(sizeof(long int)/sizeof(int))
+ #endif	EBUG
+ 
+ typedef char byte;	/* Very small signed value */
+ 
+ static char defn[]	= "#define";
! static char limfile[]	= "/etc/limits";
! static char *curlimfile	= limfile;
  
! static FILE *limf	= (FILE *) NULL;
  
***************
*** 200,201
  	register int n;
  	bool been_here;
--- 212,214 -----
  	register int n;
+ 	register int defnlen = strlen(defn);
  	bool been_here;
***************
*** 204,205
  	off_t current;
  	extern char *index();
--- 213,219 -----
  	off_t current;
+ 	int getnum();
  	extern char *index();
***************
*** 225,240
  			if (new_line &&
! 			    /* and not a comment line */
! 			    *cp != COMMENT &&
! 			    /* and not a continuation line */
! 			    !isspace(*cp) &&
! 			    /* and the limit name is first */
! 			    strneq(cp, name, n) &&
! 			    /* followed by white space */
! 			    isspace(cp[n]))
! 				break;	/* go handle it. */
  
  			/* Check whether a NL terminated the read. */
--- 243,259 -----
  			if (new_line &&
! 			    /* and starts with "#define" */
! 			    strneq(cp, defn, defnlen)) {
  
+ 				/* Skip over defn */
+ 				cp += defnlen;
+ 				while (isspace(*cp))
+ 					++cp;
+ 
+ 				/* If the limit name is first */
+ 				if (strneq(cp, name, n) &&
+ 				    /* followed by white space */
+ 				    isspace(cp[n]))
+ 					break;	/* go handle it. */
+ 			}
+ 
  			/* Check whether a NL terminated the read. */
***************
*** 269,334
  	cp += n + 1;
- 	n = 0;
- 	/* Check whether a NL terminated the read. */
- 	new_line = (index(cp, NL) != (char *) NULL);
  
  	/*
! 	** Our value may be preceded by whitespace, and is ended
! 	** by a comma or whitespace or comment or EOL.
  	*/
  	for ever {
! 		/* Skip any initial white space. */
! 		while (isspace(*cp))
  			++cp;
! 
! 		/* Check whether line is done. */
! 		if (*cp == COMMENT || *cp == NUL) {
! 			/* Save current position */
! 			current = ftell(limf);
! 			/* Get new line. */
! 			cp = fgets(inbuf, sizeof(inbuf), limf);
! 			/* If EOF, do it over again at loc 0. */
! 			if (cp == (char *) NULL) {
! 				(void) fseek(limf, (off_t) 0L, 0);
! 				current = (off_t) 0L;
! 				cp = fgets(inbuf, sizeof(inbuf), limf);
! 				/* There has to be data here. */
! 				if (cp == (char *) NULL) {
! 					/* "never happen" */
! 					break;
! 				}
! 			}
! 
! 			/*
! 			** If new line is start of line but no white
! 			** space, go back to start of line and return.
! 			*/
! 			if (!new_line || !isspace(*cp)) {
! 				(void) fseek(limf, current, 0);
! 				break;
! 			}
! 
! 			/* Check whether a NL terminated the read. */
! 			new_line = (index(cp, NL) != (char *) NULL);
! 
! 			continue;
! 		}
! 
! 		/* If it can fit, store the present value. */
! 		if (n < length)
! 			buf[n] = getnum(cp);
! 
! 		/* Count another value. */
! 		++n;
! 
! 		/*
! 		** We want to break but not skip on space, COMMENT, and
! 		** NUL.  We want to skip and break on COMMA.  We want
! 		** just to skip over everything else.
! 		*/
! 		while (!isspace(*cp) && *cp != COMMENT && *cp != NUL &&
! 		       *cp++ != COMMA);
  	}
  
! 	/* Return the number of values found. */
! 	return(n);
  }
--- 288,312 -----
  	cp += n + 1;
  
  	/*
! 	** Our value may be preceded by whitespace, or a comment.
  	*/
  	for ever {
! 		if (isspace(*cp))
  			++cp;
! 		  else if (*cp == COMM1 && cp[1] == COMM2) {
! 			cp += 2;
! 			while (*cp != NUL) {
! 				if (*cp++ != COMM2)
! 					continue;
! 				if (*cp == COMM1) {
! 					++cp;
! 					break;
! 				}
! 			}
! 		} else
! 			break;
  	}
  
! 	/* Return the size (number of ints) of values found. */
! 	return(getnum(cp, buf, length));
  }
***************
*** 351,361
  ** used because it doesn't allow different bases, and for the
! ** sake of consistency.
  */
! static int getnum(str)
!   register char *str;
  {
  	register int base = 10;
! 	register int i = 0, digit;
! 	register int sign = 1;
  
  	while (isspace(*str) || *str == PLUS || *str == MINUS) {
--- 329,351 -----
  ** used because it doesn't allow different bases, and for the
! ** sake of consistency.  Postfix 'L' or 'l' indicates long.
! **
! ** As long as we're reading in only one (variably sized) value,
! ** we'll also take on the task of storing it.
  */
! static int getnum(str, buf, n)
!   register char *str;		/* String containing number */
!   int *buf;			/* Address of int storage array */
!   int n;			/* Length of storage array */
  {
  	register int base = 10;
! 	register int j, digit;
! 	register long int i = 0;
! 	byte sign = 1;
! 	bool is_long = FALSE; 
! 	static int nbits = 0;
  
+ 	/* If no room to store, don't bother. */
+ 	if (n <= 0)
+ 		return(0);
+ 
  	while (isspace(*str) || *str == PLUS || *str == MINUS) {
***************
*** 430,432
  			break;
  
  		  default:	break;
--- 420,427 -----
  			break;
  
+ 		  case 'L':	/* Not a digit -- "long" indicator. */
+ 		  case 'l':
+ 			is_long = TRUE;
+ 			break;
+ 
  		  default:	break;
***************
*** 442,445
  	if (sign < 0)
! 		return(-i);
! 	return(i);
  }
--- 433,470 -----
  	if (sign < 0)
! 		i = -i;
! 
! 	buf[0] = i;
! 
! 	if (!is_long)		/* Value wasn't really long. */
! 		return(1);
! 
! 	if (nbits == 0)		/* Figure out #bits/int */
! 		nbits = getnbits();
! 
! 	if (n > WDPLG)		/* Return only long, at most. */
! 		n = WDPLG;
! 
! 	for (j = 1; j < n; j++) {
! 		i >>= nbits;
! 		*++buf = i;
! 	}
! 
! 	return(n);
! }
! 
! static int getnbits()
! {
! 	register int i, n;
! 
! #ifdef	EBUG
! 	return(16);
! #endif	EBUG
! 	n = 0;
! 	for (i = 1; i != 0; i <<= 1)
! 		++n;
! 	return(n);
  }

	Joe Yao		hadron!jsdy@seismo.{CSS.GOV,ARPA,UUCP}

Volume-Number: Volume 3, Number 34

std-unix@ut-sally.UUCP (Moderator, John Quarterman) (11/23/85)

Date:     Thu, 21 Nov 85 10:43:08 EST
From: Dan Franklin <dan@BBN-PROPHET.ARPA>

Mark Horton's message on ways of getting kernel-determined limits out
of files implies, to me, that the only reasonable way to get such limits
at runtime is through a kernel system call.  It solves all of the problems
Mark outlined at the cost of a few bytes of data space.

It's not clear that we need to describe the implementation at such a low
level, though.  All we really need is to standardize the interface through
which the information is maintained.  The choice of using a file or a system
call (in fact both might be appropriate, for different limits) is up to the
implementation.

(Mark's message also left me with the uneasy feeling that I might have missed
an issue or two, as I don't remember seeing anything on "cc -E | sed" before.
Have I?)

[ No, you haven't.  We've been having mailer problems associated with flaky
nameservers here and elsewhere, plus BBN sometimes forgets how to talk to us,
and the reverse.  I'll send you the ones you've missed.

Free trial offer, open to anyone:  the Volume-Number line tacked onto the
end is so you can check to see if there are any gaps in what you've received.
Send me a list of ones you didn't get and I'll send them to you again.  -mod ]

	Dan Franklin

Volume-Number: Volume 3, Number 37