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