limits

Moderator, John Quarterman std-unix at ut-sally.UUCP
Sat Nov 23 03:21:39 AEST 1985


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 at seismo.{CSS.GOV,ARPA,UUCP}

Volume-Number: Volume 3, Number 34



More information about the Mod.std.unix mailing list