summaryrefslogtreecommitdiff
path: root/utils.c
diff options
context:
space:
mode:
authorByron Rakitzis <byron@archone.tamu.edu>1992-05-27 00:00:01 +0100
committerToby Goodwin <toby@paccrat.org>2015-05-16 21:22:04 +0100
commit6bb38f6a01dbf4bbd584e038ceace0a00faa27bb (patch)
tree589705b2492ce4681760846d9ca45600f0af298d /utils.c
release: rc-1.4
Diffstat (limited to 'utils.c')
-rw-r--r--utils.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/utils.c b/utils.c
new file mode 100644
index 0000000..6ab303c
--- /dev/null
+++ b/utils.c
@@ -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;
+}