rc

[fork] interactive rc shell
Log | Files | Refs | README | LICENSE

commit aca33971e8c64b565d7ab5006b2c7bc9f2970b94
parent cdebef2d61705d76b56ece92f2e7e18a0f78fcb4
Author: tgoodwin <tgoodwin>
Date:   Tue, 30 Sep 1997 09:41:34 +0000

Initial revision

Diffstat:
Autils.c | 116+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 116 insertions(+), 0 deletions(-)

diff --git a/utils.c b/utils.c @@ -0,0 +1,116 @@ +/* utils.c: functions of general utility */ + +#include <errno.h> +#include <setjmp.h> +#include "rc.h" +#include "jbwrap.h" + +/* print error with line number on noninteractive shells (i.e., scripts) */ + +extern void pr_error(char *s) { + if (s != NULL) { + if (interactive) + fprint(2, "%s\n", s); + else + fprint(2, "line %d: %s\n", lineno - 1, s); + } +} + +/* our perror */ + +extern void uerror(char *s) { + extern int sys_nerr; + extern char *sys_errlist[]; + if (errno > sys_nerr) + return; + if (s != NULL) + fprint(2, "%s: %s\n", s, sys_errlist[errno]); + else + fprint(2, "%s\n", sys_errlist[errno]); +} + +/* Die horribly. This should never get called. Please let me know if it does. */ + +#define PANICMSG "rc panic: " + +extern void panic(char *s) { + write(2, PANICMSG, conststrlen(PANICMSG)); + write(2, s, strlen(s)); + write(2, "!\n", 2); + exit(1); +} + +/* ascii -> unsigned conversion routines. -1 indicates conversion error. */ + +extern int n2u(char *s, unsigned int base) { + unsigned int i; + for (i = 0; *s != '\0'; s++) { + unsigned int j = (unsigned int) *s - '0'; + if (j >= base) /* small hack with unsigned ints -- one compare for range test */ + return -1; + i = i * base + j; + } + return (int) i; +} + +/* The last word in portable ANSI: a strcmp wrapper for qsort */ + +extern int starstrcmp(const void *s1, const void *s2) { + return strcmp(*(char **)s1, *(char **)s2); +} + +/* tests to see if pathname begins with "/", "./", or "../" */ + +extern bool isabsolute(char *path) { + return path[0] == '/' || (path[0] == '.' && (path[1] == '/' || (path[1] == '.' && path[2] == '/'))); +} + +/* signal-safe read and write (for BSD slow devices). writeall also allows partial writes */ + +extern void writeall(int fd, char *buf, size_t remain) { + int i; + for (i = 0; remain > 0; buf += i, remain -= i) { + interrupt_happened = FALSE; + if (!setjmp(slowbuf.j)) { + slow = TRUE; + if (interrupt_happened) + break; + else if ((i = write(fd, buf, remain)) <= 0) + break; /* abort silently on errors in write() */ + } else + break; + slow = FALSE; + } + slow = FALSE; + sigchk(); +} + +extern int rc_read(int fd, char *buf, size_t n) { + long /*ssize_t*/ r; + interrupt_happened = FALSE; + if (!setjmp(slowbuf.j)) { + slow = TRUE; + if (!interrupt_happened) + r = read(fd, buf, n); + else + r = -2; + } else + r = -2; + slow = FALSE; + if (r == -2) { + errno = EINTR; + r = -1; + } + return r; +} + +/* duplicate a fd and close the old one only if necessary */ + +extern int mvfd(int i, int j) { + if (i != j) { + int s = dup2(i, j); + close(i); + return s; + } + return 0; +}