commit aca33971e8c64b565d7ab5006b2c7bc9f2970b94
parent cdebef2d61705d76b56ece92f2e7e18a0f78fcb4
Author: tgoodwin <tgoodwin>
Date: Tue, 30 Sep 1997 09:41:34 +0000
Initial revision
Diffstat:
A | utils.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;
+}