diff options
| author | Byron Rakitzis <byron@archone.tamu.edu> | 1992-05-27 00:00:01 +0100 |
|---|---|---|
| committer | Toby Goodwin <toby@paccrat.org> | 2015-05-16 21:22:04 +0100 |
| commit | 6bb38f6a01dbf4bbd584e038ceace0a00faa27bb (patch) | |
| tree | 589705b2492ce4681760846d9ca45600f0af298d /utils.c | |
release: rc-1.4
Diffstat (limited to 'utils.c')
| -rw-r--r-- | utils.c | 125 |
1 files changed, 125 insertions, 0 deletions
@@ -0,0 +1,125 @@ +/* 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; + } + SIGCHK; + return r; +} + +/* clear out z bytes from character string s */ + +extern char *clear(char *s, SIZE_T z) { + while (z != 0) + s[--z] = 0; + return s; +} + +/* 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; +} |