diff --git a/modules/src/string/bts2str.c b/modules/src/string/bts2str.c new file mode 100644 index 000000000..d6a4705d8 --- /dev/null +++ b/modules/src/string/bts2str.c @@ -0,0 +1,33 @@ +/* bts2str() turns a row of bytes b with length n into string s + The ASCII set of characters is used. + 86/03/17 EHB +*/ + +#define is_print(c) ((unsigned)((c) - ' ') <= '~' - ' ') + +char * +bts2str(b, n, s) + char *b, *s; + register int n; +{ + register char *f = b, *t = s; + + while (n-- > 0) { + if (is_print(*f)) + *t++ = *f++; + else { + register int n = (*f++ & 0377); + register int i; + register char *p; + + *t = '\\'; + p = (t += 4); + for (i = 0; i < 3; i++) { + *--p = (n & 07) + '0'; + n >>= 3; + } + } + } + *t = '\000'; + return s; +} diff --git a/modules/src/string/btscat.c b/modules/src/string/btscat.c new file mode 100644 index 000000000..a5f3caf61 --- /dev/null +++ b/modules/src/string/btscat.c @@ -0,0 +1,16 @@ +/* btscat() +*/ + +char * +btscat(b1, n1, b2, n2) + char *b1; + int n1; + register char *b2; + register int n2; +{ + register char *b = b1 + n1; + + while (n2-- > 0) + *b++ = *b2++; + return b1; +} diff --git a/modules/src/string/btscmp.c b/modules/src/string/btscmp.c new file mode 100644 index 000000000..32e794b58 --- /dev/null +++ b/modules/src/string/btscmp.c @@ -0,0 +1,16 @@ +/* btscmp() +*/ + +int +btscmp(b1, n1, b2, n2) + register char *b1, *b2; + int n1, n2; +{ + register n = (n1 <= n2) ? n1 : n2; + + while (n-- > 0) { + if (*b1++ != *b2++) + return *--b1 - *--b2; + } + return n2 - n1; +} diff --git a/modules/src/string/btscpy.c b/modules/src/string/btscpy.c new file mode 100644 index 000000000..e5c6adbb5 --- /dev/null +++ b/modules/src/string/btscpy.c @@ -0,0 +1,14 @@ +/* btscpy() +*/ + +char * +btscpy(b1, b2, n) + register char *b1, *b2; + register int n; +{ + char *b1s = b1; + + while (n-- > 0) + *b1++ = *b2++; + return b1s; +} diff --git a/modules/src/string/btszero.c b/modules/src/string/btszero.c new file mode 100644 index 000000000..c4aca369f --- /dev/null +++ b/modules/src/string/btszero.c @@ -0,0 +1,11 @@ +/* btszero() +*/ + +char * +btszero(b, n) + register char *b; + register int n; +{ + while (n-- > 0) + *b++ = '\0'; +} diff --git a/modules/src/string/long2str.c b/modules/src/string/long2str.c new file mode 100644 index 000000000..b50eaa0e3 --- /dev/null +++ b/modules/src/string/long2str.c @@ -0,0 +1,60 @@ +/* Integer to String translator + -> base is a value from [-16,-2] V [2,16] + -> base < 0: see 'val' as unsigned value + -> no checks for buffer overflow and illegal parameters + (1985, EHB) +*/ + +#define MAXWIDTH 32 + +char * +long2str(val, base) + register long val; + register base; +{ + static char numbuf[MAXWIDTH]; + static char vec[] = "0123456789ABCDEF"; + register char *p = &numbuf[MAXWIDTH]; + int sign = (base > 0); + + *--p = '\0'; /* null-terminate string */ + if (val) { + if (base > 0) { + if (val < 0L) { + if ((val = -val) < 0L) + goto overflow; + } + else + sign = 0; + } + else + if (base < 0) { /* unsigned */ + base = -base; + if (val < 0L) { /* taken from Amoeba src */ + register mod, i; + overflow: + mod = 0; + for (i = 0; i < 8 * sizeof val; i++) { + mod <<= 1; + if (val < 0) + mod++; + val <<= 1; + if (mod >= base) { + mod -= base; + val++; + } + } + *--p = vec[mod]; + } + } + do { + *--p = vec[(int) (val % base)]; + val /= base; + } while (val != 0L); + if (sign) + *--p = '-'; /* don't forget it !! */ + } + else + *--p = '0'; /* just a simple 0 */ + return p; +} diff --git a/modules/src/string/str2bts.c b/modules/src/string/str2bts.c new file mode 100644 index 000000000..eec3b6459 --- /dev/null +++ b/modules/src/string/str2bts.c @@ -0,0 +1,67 @@ +/* str2bts -- (1985, EHB) +*/ +static +is_oct(c) + char c; +{ + return (c == '0' || c == '1' || c == '2' || c == '3' || + c == '4' || c == '5' || c == '6' || c == '7'); +} + +/* str2bts() strips the escaped characters of a + string and replaces them by the ascii characters they stand for. + The ascii length of the resulting string is returned, including the + terminating null-character. +*/ +char * +str2bts(str, bts, pn) + register char *str; + char *bts; + int *pn; +{ + register char *t = bts; + + while (*str) { + if (*str == '\\') { + switch (*++str) { + case 'b': + *t++ = '\b'; + str++; + break; + case 'f': + *t++ = '\f'; + str++; + break; + case 'n': + *t++ = '\n'; + str++; + break; + case 'r': + *t++ = '\r'; + str++; + break; + case 't': + *t++ = '\t'; + str++; + break; + default: + if (is_oct(*str)) { + register cnt = 0, oct = 0; + + do + oct = oct * 8 + *str - '0'; + while (is_oct(*++str) && ++cnt < 3); + *t++ = (char) oct; + break; + } + *t++ = *str++; + break; + } + } + else + *t++ = *str++; + } + *t = '\0'; /* don't forget this one !!! */ + *pn = t - bts + 1; + return bts; +} diff --git a/modules/src/string/str2long.c b/modules/src/string/str2long.c new file mode 100644 index 000000000..a058987c4 --- /dev/null +++ b/modules/src/string/str2long.c @@ -0,0 +1,32 @@ +/* str2long() +*/ + +value(c, b) + char c; + int b; +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + return b; +} + +long +str2long(str, base) + register char *str; + int base; +{ + int minus = 0, d; + long l = 0; + + if (*str == '-') { + minus++; + str++; + } + while ((d = value(*str++, base)) < base) + l = base * l + d; + return minus ? -l : l; +} diff --git a/modules/src/string/strcat.c b/modules/src/string/strcat.c new file mode 100644 index 000000000..861d663f8 --- /dev/null +++ b/modules/src/string/strcat.c @@ -0,0 +1,15 @@ +/* append t to s +*/ +char * +strcat(s, t) + register char *s, *t; +{ + register char *b = s; + + while (*s++) + ; + s--; + while (*s++ = *t++) + ; + return b; +} diff --git a/modules/src/string/strcmp.c b/modules/src/string/strcmp.c new file mode 100644 index 000000000..ca69d45fe --- /dev/null +++ b/modules/src/string/strcmp.c @@ -0,0 +1,12 @@ +/* return negative, zero or positive value if + resp. s < t, s == t or s > t +*/ +int +strcmp(s, t) + register char *s, *t; +{ + while (*s == *t++) + if (*s++ == '\0') + return 0; + return *s - *--t; +} diff --git a/modules/src/string/strcpy.c b/modules/src/string/strcpy.c new file mode 100644 index 000000000..409d0bf3d --- /dev/null +++ b/modules/src/string/strcpy.c @@ -0,0 +1,12 @@ +/* Copy t into s +*/ +char * +strcpy(s, t) + register char *s, *t; +{ + register char *b = s; + + while (*s++ = *t++) + ; + return b; +} diff --git a/modules/src/string/strindex.c b/modules/src/string/strindex.c new file mode 100644 index 000000000..49e446440 --- /dev/null +++ b/modules/src/string/strindex.c @@ -0,0 +1,12 @@ +/* strindex() -- (86/03/18 EHB) +*/ + +char * +strindex(s, c) + register char *s, c; +{ + while (*s) + if (*s++ == c) + return --s; + return (char *)0; +} diff --git a/modules/src/string/string.3 b/modules/src/string/string.3 new file mode 100644 index 000000000..e4ea42d1e --- /dev/null +++ b/modules/src/string/string.3 @@ -0,0 +1,250 @@ +.TH STRING 3ACK "86/03/18" +.SH NAME +strcpy, strncpy, strcat, strncat, strcmp, strncmp, +strlen, strindex, strrindex, strzero, str2bts, +long2str, str2long, +btscpy, btscat, btscmp, btszero, bts2str \- operations on and +conversions between strings and row of bytes +.SH SYNOPSIS +.nf +.B char *strcpy(s1, s2) +.B char *s1, *s2; +.PP +.B char *strncpy(s1, s2, n) +.B char *s1, *s2; +.PP +.B char *strcat(s1, s2) +.B char *s1, *s2; +.PP +.B char *strncat(s1, s2, n) +.B char *s1, *s2; +.PP +.B int strcmp(s1, s2) +.B char *s1, *s2; +.PP +.B int strncmp(s1, s2, n) +.B char *s1, *s2; +.PP +.B int strlen(s) +.B char *s; +.PP +.B char *strindex(s, c) +.B char *s, c; +.PP +.B char *strrindex(s, c) +.B char *s, c; +.PP +.B char *strzero(s) +.B char *s; +.PP +.B char *str2bts(s, b, pn) +.B char *s, *b; +.B int *pn; +.PP +.B char *long2str(l, base) +.B long l; +.B int base; +.PP +.B long str2long(s, base) +.B char *s; +.B int base; +.PP +.B char *btscpy(b1, b2, n) +.B char *b1, *b2; +.B int n; +.PP +.B char *btscat(b1, n1, b2, n2) +.B char *b1, *b2; +.B int n1, n2; +.PP +.B int btscmp(b1, n1, b2, n2) +.B char *b1, *b2; +.B int n1, n2; +.PP +.B char *btszero(b, n) +.B char *b; +.B int n; +.PP +.B char *bts2str(b, n, s) +.B char *b, *s; +.B int n; +.fi +.SH DESCRIPTION +The +.IR str * +functions operate on null-terminated strings. +The +.IR bts * +functions operate on variable-length rows of bytes, +regardless of null bytes. +Neither of these functions check for overflow of any receiving area. +.PP +.I Strcpy +copies string +.I s2 +to +.I s1, +stopping after the null character has been moved. +.I Strncpy +copies exactly +.I n +characters, +truncating or null-padding +.I s2; +the target may not be null-terminated if the length +of +.I s2 +is +.I n +or more. +Both return +.IR s1 . +.PP +.I Strcat +appends a copy of string +.I s2 +to the end of string +.IR s1 . +.I Strncat +copies at most +.I n +characters. +Both return a pointer to the null-terminated result +.IR s1 . +.PP +.I Strcmp +compares its arguments and returns an integer +greater than, equal to, or less than 0, if +.I s1 +is lexicographically greater than, equal to, or +less than +.IR s2 , +respectively. +.I Strncmp +makes the same comparison but checks at most +.I n +characters. +.PP +.I Strlen +returns the number of characters before the null-character. +.IR s . +.PP +.I Strindex +.RI ( strrindex ) +returns a pointer to the first (last) +occurrence of character +.I c +in string +.I s, +or zero if +.I c +does not occur in +.IR s . +.PP +.I Bts2str +turns a row of +.I n +consecutive bytes, the first of which is pointed by +.IR b , +into a null-terminated string, starting at +.IR s . +Printable characters are copied and non-printable characters are transformed +into sequences of printable characters, representing those characters. +The transformation agrees with the representation of non-printable +characters in C strings. +.br +E.g., the row of 2 bytes +.RS +\&'\e0' '\en' +.RE +is turned into the string consisting of the following characters +.RS +\&'\e\e' '0' '0' '0' '\e\e' 'n' '\e0' +.RE +The latter string could be represented in C as "\e\e000\e\en". +.PP +.I Str2bts +turns string +.I s +into a sequence of bytes pointed by +.IR b . +It has the inverse effect to +.IR bts2str . +The length of the resulting byte sequence is returned in +.RI * pn . +.br +Both the functions +.I bts2str +and +.I str2bts +return a pointer to the result. +.PP +.I Long2str +converts a long value +.I l +into a null-terminated string according to +.IR base , +which indicates the base to use. +This base may be any of 2..16. +A negative base (in the range -16..-2) indicates that the long must be +seen as unsigned. +A pointer to the string is returned. +.I Str2long +returns the value that is represented in +.IR s , +according to +.IR base . +.PP +.I Btscpy +copies +.I n +bytes from the string of bytes +.I b2 +to +.I b1 +and returns +.IR b1 . +.PP +.I Btscat +appends a copy of +.I n2 +bytes from +.I b2 +to the end of +.IR b1 , +consisting of +.I n1 +bytes. +.I B1 +is returned. +.PP +.I Btscmp +compares row of bytes +.I b1 +with length +.I n1 +and +.I b2 +with length +.I n2 +and returns an integer greater than, equal to, or less than 0, if +.I b1 +is lexicographically greater then, equal to, or less than +.IR b2 , +respectively. +.PP +.I Btszero +places +.I n +null bytes in the string +.IR b . +.I B +is returned. +.SH FILES +~em/modules/lib/libstring.a +.SH "SEE ALSO" +string(3), bstring(3), atof(3) +.SH BUGS +No checks for overflow or illegal parameters. +.SH AUTHOR +Erik Baalbergen diff --git a/modules/src/string/strlen.c b/modules/src/string/strlen.c new file mode 100644 index 000000000..581fcbd54 --- /dev/null +++ b/modules/src/string/strlen.c @@ -0,0 +1,12 @@ +/* return length of s +*/ +int +strlen(s) + char *s; +{ + register char *b = s; + + while (*b++) + ; + return b - s - 1; +} diff --git a/modules/src/string/strncat.c b/modules/src/string/strncat.c new file mode 100644 index 000000000..881454a73 --- /dev/null +++ b/modules/src/string/strncat.c @@ -0,0 +1,16 @@ +/* append t to s, upto n characters +*/ +char * +strncat(s, t, n) + register char *s, *t; + register int n; +{ + register char *b = s; + + while (*s++) + ; + s--; + while ((n-- > 0) && (*s++ = *t++)) + ; + return b; +} diff --git a/modules/src/string/strncmp.c b/modules/src/string/strncmp.c new file mode 100644 index 000000000..86d39c025 --- /dev/null +++ b/modules/src/string/strncmp.c @@ -0,0 +1,18 @@ +/* return negative, zero or positive value if + resp. s < t, s == t or s > t; compare at most n characters +*/ +int +strncmp(s, t, n) + register char *s, *t; + register int n; +{ + while (n-- > 0) { + if (*s == *t++) { + if (*s++ == '\0') + return 0; + } + else + return *s - *--t; + } + return 0; +} diff --git a/modules/src/string/strncpy.c b/modules/src/string/strncpy.c new file mode 100644 index 000000000..f554d0c2f --- /dev/null +++ b/modules/src/string/strncpy.c @@ -0,0 +1,13 @@ +/* Copy t into s, upto n characters +*/ +char * +strncpy(s, t, n) + register char *s, *t; + register int n; +{ + register char *b = s; + + while ((n-- > 0) && (*s++ = *t++)) + ; + return b; +} diff --git a/modules/src/string/strrindex.c b/modules/src/string/strrindex.c new file mode 100644 index 000000000..d55bf01b3 --- /dev/null +++ b/modules/src/string/strrindex.c @@ -0,0 +1,11 @@ +char * +strrindex(str, chr) + register char *str, chr; +{ + register char *retptr = 0; + + while (*str) + if (*str++ == chr) + retptr = &str[-1]; + return retptr; +} diff --git a/modules/src/string/strzero.c b/modules/src/string/strzero.c new file mode 100644 index 000000000..86036a926 --- /dev/null +++ b/modules/src/string/strzero.c @@ -0,0 +1,9 @@ +/* strzero() +*/ + +char * +strzero(s) + char *s; +{ + *s = '\0'; +} diff --git a/modules/src/system/access.c b/modules/src/system/access.c new file mode 100644 index 000000000..7300c87e4 --- /dev/null +++ b/modules/src/system/access.c @@ -0,0 +1,11 @@ +/* $Header$ */ + +#include + +int +sys_access(path, mode) + char *path; + int mode; +{ + return access(path, mode) == 0; +} diff --git a/modules/src/system/break.c b/modules/src/system/break.c new file mode 100644 index 000000000..1160d326e --- /dev/null +++ b/modules/src/system/break.c @@ -0,0 +1,17 @@ +/* $Header$ */ + +#include + +char *sbrk(); + +char * +sys_break(incr) + int incr; +{ + char *sbrk(); + char *brk = sbrk(incr); + + if (brk == (char *) 0 || brk == (char *)-1) + return ILL_BREAK; + return brk; +} diff --git a/modules/src/system/chmode.c b/modules/src/system/chmode.c new file mode 100644 index 000000000..ce14844ee --- /dev/null +++ b/modules/src/system/chmode.c @@ -0,0 +1,9 @@ +/* $Header$ */ + +int +sys_chmode(path, mode) + char *path; + int mode; +{ + return chmod(path, mode) == 0; +} diff --git a/modules/src/system/close.c b/modules/src/system/close.c new file mode 100644 index 000000000..ffb9b7ea3 --- /dev/null +++ b/modules/src/system/close.c @@ -0,0 +1,11 @@ +/* $Header$ */ + +#include + +sys_close(fp) + register File *fp; +{ + fp->o_flags = 0; + close(fp->o_fd); + fp->o_fd = -1; +} diff --git a/modules/src/system/create.c b/modules/src/system/create.c new file mode 100644 index 000000000..c33ddbfb9 --- /dev/null +++ b/modules/src/system/create.c @@ -0,0 +1,24 @@ +/* $Header$ */ + +#include + +extern File *_get_entry(); + +int +sys_create(filep, path, mode) + File **filep; + char *path; + int mode; +{ + register fd; + register File *fp; + + if ((fp = _get_entry()) == (File *)0) + return 0; + if ((fd = creat(path, mode)) < 0) + return 0; + fp->o_fd = fd; + fp->o_flags = OP_WRITE; + *filep = fp; + return 1; +} diff --git a/modules/src/system/exit.c b/modules/src/system/exit.c new file mode 100644 index 000000000..011fd466e --- /dev/null +++ b/modules/src/system/exit.c @@ -0,0 +1,9 @@ +/* $Header$ */ +/* called by /lib/crt0.o; needed to suppress the loading of the + standard exit() which performs unnecessary cleanup actions +*/ + +exit(n) +{ + _exit(n); +} diff --git a/modules/src/system/filesize.c b/modules/src/system/filesize.c new file mode 100644 index 000000000..588d66eba --- /dev/null +++ b/modules/src/system/filesize.c @@ -0,0 +1,15 @@ +/* $Header$ */ + +#include +#include + +long +sys_filesize(path) + char *path; +{ + struct stat st_buf; + + if (stat(path, &st_buf) != 0) + return -1L; + return (long) st_buf.st_size; +} diff --git a/modules/src/system/lock.c b/modules/src/system/lock.c new file mode 100644 index 000000000..608ad3c52 --- /dev/null +++ b/modules/src/system/lock.c @@ -0,0 +1,27 @@ +/* $Header$ */ + +int +sys_lock(path) + char *path; +{ + char buf[1024]; + char *tmpf = ".lockXXXXXX"; + char *strrindex(); + char *p; + int ok, fd; + + strcpy(buf, path); + if (p = strrindex(buf, '/')) { + ++p; + strcpy(p, tmpf); + } + else + strcpy(buf, tmpf); + mktemp(buf); + if ((fd = creat(buf, 0)) < 0) + return 0; + close(fd); + ok = (link(buf, path) == 0); + unlink(buf); + return ok; +} diff --git a/modules/src/system/modtime.c b/modules/src/system/modtime.c new file mode 100644 index 000000000..ff81b00ce --- /dev/null +++ b/modules/src/system/modtime.c @@ -0,0 +1,15 @@ +/* $Header$ */ + +#include +#include + +long +sys_modtime(path) + char *path; +{ + struct stat st_buf; + + if (stat(path, &st_buf) != 0) + return -1L; + return (long) st_buf.st_mtime; +} diff --git a/modules/src/system/open.c b/modules/src/system/open.c new file mode 100644 index 000000000..65aefd0d2 --- /dev/null +++ b/modules/src/system/open.c @@ -0,0 +1,53 @@ +/* $Header$ */ + +#include + +extern File *_get_entry(); + +int +sys_open(path, flag, filep) + char *path; + int flag; + File **filep; +{ + register fd; + register File *fp; + int open_mode; + long lseek(); + + switch (flag) { + case OP_READ: + open_mode = 0; + break; + case OP_WRITE: + case OP_APPEND: + open_mode = 1; + break; + default: + return 0; + } + if ((fp = _get_entry()) == (File *)0) + return 0; + if (flag == OP_WRITE) { + if ((fd = creat(path, 0644)) < 0) + return 0; + } + else /* OP_READ or OP_APPEND */ + if ((fd = open(path, open_mode)) < 0) { + if (flag == OP_READ || access(path, 0) == 0) + return 0; + /* now: flag == OP_APPEND */ + if ((fd = creat(path, 0644)) < 0) + return 0; + } + else { + if (flag == OP_APPEND && (lseek(fd, 0L, 2) < 0L)) { + close(fd); + return 0; + } + } + fp->o_flags = flag; + fp->o_fd = fd; + *filep = fp; + return 1; +} diff --git a/modules/src/system/read.c b/modules/src/system/read.c new file mode 100644 index 000000000..93e08e036 --- /dev/null +++ b/modules/src/system/read.c @@ -0,0 +1,12 @@ +/* $Header$ */ + +#include + +int +sys_read(fp, bufptr, bufsiz, pnbytes) + File *fp; + char *bufptr; + int bufsiz, *pnbytes; +{ + return (*pnbytes = read(fp->o_fd, bufptr, bufsiz)) >= 0; +} diff --git a/modules/src/system/remove.c b/modules/src/system/remove.c new file mode 100644 index 000000000..0b6452cbd --- /dev/null +++ b/modules/src/system/remove.c @@ -0,0 +1,8 @@ +/* $Header$ */ + +int +sys_remove(path) + char *path; +{ + return unlink(path) == 0; +} diff --git a/modules/src/system/stop.c b/modules/src/system/stop.c new file mode 100644 index 000000000..57ea38111 --- /dev/null +++ b/modules/src/system/stop.c @@ -0,0 +1,17 @@ +/* $Header$ */ + +#include + +sys_stop(how) + int how; +{ + switch(how) { + case S_END: + exit(0); + case S_EXIT: + exit(1); + case S_ABORT: + default: + abort(); + } +} diff --git a/modules/src/system/system.3 b/modules/src/system/system.3 new file mode 100644 index 000000000..a2fb51023 --- /dev/null +++ b/modules/src/system/system.3 @@ -0,0 +1,281 @@ +.TH SYSTEM 3ACK "86/03/24" +.SH NAME +sys_open, sys_close, sys_read, sys_write, sys_reset, sys_access, +sys_modtime, sys_remove, sys_filesize, sys_chmode, +sys_lock, sys_unlock, +sys_break, sys_stop, sys_time \- system call interface +.SH SYNOPSIS +.nf +.B #include +.PP +.B File *STDIN, *STDOUT, *STDERR; +.PP +.B int sys_open(path, flag, filep) +.B char *path; +.B int flag; +.B File **filep; +.PP +.B sys_close(filep) +.B File *filep; +.PP +.B int sys_read(filep, bufptr, bufsiz, pnbytes) +.B File *filep; +.B char *bufptr; +.B int bufsiz, *pnbytes; +.PP +.B int sys_write(filep, bufptr, nbytes) +.B File *filep; +.B char *bufptr; +.B int nbytes; +.PP +.B int sys_reset(filep) +.B File *filep +.PP +.B int sys_access(path, mode) +.B char *path; +.B int mode; +.PP +.B int sys_remove(path) +.B char *path; +.PP +.B long sys_filesize(path) +.B char *path; +.PP +.B int sys_chmode(path, mode) +.B char *path; +.B int mode; +.PP +.B int sys_lock(name) +.B char *name; +.PP +.B int sys_unlock(name) +.B char *name; +.PP +.B char *sys_break(incr) +.B int incr; +.PP +.B sys_stop(how) +.B int how; +.PP +.B long sys_time(); +.PP +.B long sys_modtime(path) +.B char *path; +.fi +.SH DESCRIPTION +This package provides a rather system-independent set of "system" calls +primarily intended for use in compilers. +The include file contains a defined constant, +.IR BUFSIZ , +which gives the system-dependent block size. +Another constant, +.IR SYS_NOPEN , +gives the maximum number of open files in a process. +.PP +.I Sys_open +opens a file called +.I path +for sequential reading or writing, as specified by +.I flag +and returns in +.I filep +a decsriptor for the opened file. +The allowed values for +.I flag +are +.IP OP_READ 15 +open for reading +.IP OP_WRITE 15 +open for rewriting (create +.I path +if it did not exist) +.IP OP_APPEND 15 +open for writing at the end (create +.I path +if it did not exist) +.LP +Created files are given read and write permission for its creator and +read permission for other users. +.br +Specifying +.I path +as null pointer opens a so-called anonymous file, which has no name and +disappears when it is closed or when the program exits. +It is possible to read the contents of an anonymous file by using +.I reset . +.br +There are three normally open files with the following descriptors: +.IP STDIN 15 +standard input file; opened as OP_READ +.IP STDOUT 15 +standard output file; opened as OP_APPEND +.IP STDERR 15 +standard error file; opened as OP_APPEND +.LP +.I Sys_close +causes the open file known by +.I filep +to be closed. +.PP +.I Sys_read +causes up to +.I bufsiz +contiguous bytes to be read from the open file known by +.I filep +into a piece of memory pointed at by +.IR bufptr . +The number of bytes actually read is returned in +.IR *pnbytes . +If +.I *pnbytes +is set to 0 then the end-of-file is reached. +.PP +.I Sys_write +writes +.I nbytes +contiguous bytes from the memory pointed at by +.I bufptr +onto the open file known by +.IR filep . +A non-zero return value indicates that +.I nbytes +are actually written. +.PP +.I Sys_reset +causes the open file known by +.I filep +to be re-opened for reading (cf. open flag OP_READ). +This may be useful in reading anonymous files. +.PP +.I Sys_access +checks the given file +.I path +for accessibility according to +.I mode +which is the result of +.IR or 'ing +one or more of the following values: +.IP AC_READ 15 +file exists and is readable +.IP AC_WRITE 15 +file exists and is writable +.IP AC_EXEC 15 +file exists and is executable +.LP +Specifying +.I mode +as 0 tests whether the directories leading to the file can be searched and the +file exists. +The return value is either 0 if the +file is not reachable, does not exist or if the access is not allowed, +or 1 if the indicated access is permitted. +.PP +.I Sys_modtime +returns the last-modified time of the file specified in +.IR path . +Any failure is indicated by a return value of \-1L. +.PP +.I Sys_remove +removes file +.I path +from the system. +It is supposed that, if the file is still open, the contents of +the file are available until the last +.I sys_close +is performed on it. +A non-zero return value indicates successful action whereas 0 +indicates that the given file does not exist or cannot be removed. +.PP +The function +.I sys_filesize +returns the size in bytes of the +file specified by +.IR path , +if possible. +The value \-1L is returned if the size cannot be retrieved for some reason. +.PP +.I Sys_chmode +changes the file-protection mode of file +.I path +to +.IR mode . +.PP +.I Sys_lock +and +.I sys_unlock +provide a mechanism for setting and clearing symbolic locks for external +objects. +This is done by creating and removing file +.IR name . +.I Sys_lock +returns zero if the lock is already set and a non-zero value if the lock +did not exist and has been created. +.I Sys_unlock +returns a non-zero value if the lock did not exist or if the lock has been +removed succesfully. +Zero is returned otherwise. +The actions performed by these routines are atomic: +race conditions cannot +occur. +.PP +.I Sys_break +adds +.I incr +more bytes to the program's data space and returns a pointer to +the newly allocated area. +ILL_BREAK is returned in case of some error, due to a lack of space or +some interrupt. +It is equivalent to the UNIX version 7 +.IR sbrk (2). +.PP +.I Sys_stop +should be called when the process is terminated due to +the end of the program or some error. +This routine closes all open files and causes the program to +stop in a way specified by +.IR how , +which parameter has one of the following values: +.IP S_END 15 +normal termination, indicate successful completion +.IP S_EXIT 15 +terminate the process with status +.B 1 +.IP S_ABORT 15 +abort this process and produce a post-mortem dump +.LP +.PP +.I Sys_time +returns a long value that stands for the system's time. +Its return value is a long that stands for the time +since 00:00:00 GMT, Jan. 1, 1970, measured in seconds. +.SH FILES +.nf +~em/modules/h/system.h +~em/modules/lib/libsystem.a +.fi +.SH DIAGNOSTICS +.PP +The routines +.IR sys_open , +.IR sys_read , +.IR sys_write , +.IR sys_reset , +.I sys_chmode +and +.I sys_remove +return a value of zero upon any failure and a non-zero +value if the call succeeds. +.SH BUGS +The current implementation does not allow the use of anonymous files. +.br +.I Sys_reset +is not implemented. +A +.I sys_close +followed by a +.I sys_open +with the proper mode has the same effect on non-anonymous files. +.SH "SEE ALSO" +UNIX version 7 manual volume 1, chapter 2 +.SH AUTHOR +Erik Baalbergen diff --git a/modules/src/system/system.c b/modules/src/system/system.c new file mode 100644 index 000000000..68871deaa --- /dev/null +++ b/modules/src/system/system.c @@ -0,0 +1,20 @@ +/* RCS: $Header$ */ + +#include + +File _sys_ftab[SYS_NOPEN] = { + { 0, OP_READ}, + { 1, OP_APPEND}, + { 2, OP_APPEND} +}; + +File * +_get_entry() +{ + register File *fp; + + for (fp = &_sys_ftab[0]; fp < &_sys_ftab[SYS_NOPEN]; fp++) + if (fp->o_flags == 0) + return fp; + return (File *)0; +} diff --git a/modules/src/system/system.h b/modules/src/system/system.h new file mode 100644 index 000000000..a43e1e2a0 --- /dev/null +++ b/modules/src/system/system.h @@ -0,0 +1,40 @@ +/* RCS: $Header$ */ + +struct _sys_fildes { + int o_fd; /* UNIX filedescriptor */ + int o_flags; /* flags for open; 0 if not used */ +}; + +typedef struct _sys_fildes File; + +extern File _sys_ftab[]; + +/* flags for sys_open() */ +#define OP_READ 01 +#define OP_WRITE 02 +#define OP_APPEND 04 + +/* flags for sys_access() */ +#define AC_EXIST 00 +#define AC_READ 04 +#define AC_WRITE 02 +#define AC_EXEC 01 + +/* flags for sys_stop() */ +#define S_END 0 +#define S_EXIT 1 +#define S_ABORT 2 + +/* standard file decsriptors */ +#define STDIN &_sys_ftab[0] +#define STDOUT &_sys_ftab[1] +#define STDERR &_sys_ftab[2] + +/* maximum number of open files */ +#define SYS_NOPEN 20 + +/* return value for sys_break */ +#define ILL_BREAK ((char *)0) + +/* system's idea of block */ +#define BUFSIZ 1024 diff --git a/modules/src/system/time.c b/modules/src/system/time.c new file mode 100644 index 000000000..ede8eee5c --- /dev/null +++ b/modules/src/system/time.c @@ -0,0 +1,9 @@ +/* $Header$ */ + +long time(); + +long +sys_time() +{ + return time(0); +} diff --git a/modules/src/system/unlock.c b/modules/src/system/unlock.c new file mode 100644 index 000000000..9d30a4113 --- /dev/null +++ b/modules/src/system/unlock.c @@ -0,0 +1,8 @@ +/* $Header$ */ + +int +sys_unlock(path) + char *path; +{ + return unlink(path) == 0; +} diff --git a/modules/src/system/write.c b/modules/src/system/write.c new file mode 100644 index 000000000..97b7de71a --- /dev/null +++ b/modules/src/system/write.c @@ -0,0 +1,12 @@ +/* $Header$ */ + +#include + +int +sys_write(fp, bufptr, nbytes) + File *fp; + char *bufptr; + int nbytes; +{ + return write(fp->o_fd, bufptr, nbytes) == nbytes; +}