BSD 4_4_Lite1 development
[unix-history] / usr / src / contrib / rc-1.4 / utils.c
CommitLineData
9d25673b
C
1/* utils.c: functions of general utility */
2
3#include <errno.h>
4#include <setjmp.h>
5#include "rc.h"
6#include "jbwrap.h"
7
8/* print error with line number on noninteractive shells (i.e., scripts) */
9
10extern void pr_error(char *s) {
11 if (s != NULL) {
12 if (interactive)
13 fprint(2, "%s\n", s);
14 else
15 fprint(2, "line %d: %s\n", lineno - 1, s);
16 }
17}
18
19/* our perror */
20
21extern void uerror(char *s) {
22 extern int sys_nerr;
23 extern char *sys_errlist[];
24 if (errno > sys_nerr)
25 return;
26 if (s != NULL)
27 fprint(2, "%s: %s\n", s, sys_errlist[errno]);
28 else
29 fprint(2, "%s\n", sys_errlist[errno]);
30}
31
32/* Die horribly. This should never get called. Please let me know if it does. */
33
34#define PANICMSG "rc panic: "
35
36extern void panic(char *s) {
37 write(2, PANICMSG, conststrlen(PANICMSG));
38 write(2, s, strlen(s));
39 write(2, "!\n", 2);
40 exit(1);
41}
42
43/* ascii -> unsigned conversion routines. -1 indicates conversion error. */
44
45extern int n2u(char *s, unsigned int base) {
46 unsigned int i;
47 for (i = 0; *s != '\0'; s++) {
48 unsigned int j = (unsigned int) *s - '0';
49 if (j >= base) /* small hack with unsigned ints -- one compare for range test */
50 return -1;
51 i = i * base + j;
52 }
53 return (int) i;
54}
55
56/* The last word in portable ANSI: a strcmp wrapper for qsort */
57
58extern int starstrcmp(const void *s1, const void *s2) {
59 return strcmp(*(char **)s1, *(char **)s2);
60}
61
62/* tests to see if pathname begins with "/", "./", or "../" */
63
64extern bool isabsolute(char *path) {
65 return path[0] == '/' || (path[0] == '.' && (path[1] == '/' || (path[1] == '.' && path[2] == '/')));
66}
67
68/* signal-safe read and write (for BSD slow devices). writeall also allows partial writes */
69
70extern void writeall(int fd, char *buf, size_t remain) {
71 int i;
72 for (i = 0; remain > 0; buf += i, remain -= i) {
73 interrupt_happened = FALSE;
74 if (!setjmp(slowbuf.j)) {
75 slow = TRUE;
76 if (interrupt_happened)
77 break;
78 else if ((i = write(fd, buf, remain)) <= 0)
79 break; /* abort silently on errors in write() */
80 } else
81 break;
82 slow = FALSE;
83 }
84 slow = FALSE;
85 SIGCHK;
86}
87
88extern int rc_read(int fd, char *buf, size_t n) {
89 long /*ssize_t*/ r;
90 interrupt_happened = FALSE;
91 if (!setjmp(slowbuf.j)) {
92 slow = TRUE;
93 if (!interrupt_happened)
94 r = read(fd, buf, n);
95 else
96 r = -2;
97 } else
98 r = -2;
99 slow = FALSE;
100 if (r == -2) {
101 errno = EINTR;
102 r = -1;
103 }
104 SIGCHK;
105 return r;
106}
107
108/* clear out z bytes from character string s */
109
110extern char *clear(char *s, size_t z) {
111 while (z != 0)
112 s[--z] = 0;
113 return s;
114}
115
116/* duplicate a fd and close the old one only if necessary */
117
118extern int mvfd(int i, int j) {
119 if (i != j) {
120 int s = dup2(i, j);
121 close(i);
122 return s;
123 }
124 return 0;
125}