utils.c (1739B)
1 /* utils.c: functions of general utility */ 2 3 #include "rc.h" 4 5 #include <errno.h> 6 #include <setjmp.h> 7 8 #include "jbwrap.h" 9 10 /* print error with line number on noninteractive shells (i.e., scripts) */ 11 12 extern void pr_error(char *s, int offset) { 13 if (s != NULL) { 14 if (interactive) 15 fprint(2, RC "%s\n", s); 16 else 17 fprint(2, RC "line %d: %s\n", lineno + offset, s); 18 } 19 } 20 21 /* our perror */ 22 23 extern void uerror(char *s) { 24 char *err; 25 26 err = strerror(errno); 27 if (!err) err = "unknown error"; 28 29 if (s) 30 fprint(2, RC "%s: %s\n", s, err); 31 else 32 fprint(2, RC "%s\n", err); 33 } 34 35 /* Die horribly. This should never get called. Please let me know if it does. */ 36 37 #define PANICMSG "rc panic: " 38 39 extern void panic(char *s) { 40 write(2, PANICMSG, conststrlen(PANICMSG)); 41 write(2, s, strlen(s)); 42 write(2, "!\n", 2); 43 exit(1); 44 } 45 46 /* ascii -> unsigned conversion routines. -1 indicates conversion error. */ 47 48 extern int n2u(char *s, unsigned int base) { 49 unsigned int i; 50 for (i = 0; *s != '\0'; s++) { 51 unsigned int j = (unsigned int) *s - '0'; 52 if (j >= base) /* small hack with unsigned ints -- one compare for range test */ 53 return -1; 54 i = i * base + j; 55 } 56 return (int) i; 57 } 58 59 /* The last word in portable ANSI: a strcmp wrapper for qsort */ 60 61 extern int starstrcmp(const void *s1, const void *s2) { 62 return strcmp(*(char * const *)s1, *(char * const *)s2); 63 } 64 65 /* tests to see if pathname begins with "/", "./", or "../" */ 66 67 extern bool isabsolute(char *path) { 68 return path[0] == '/' || (path[0] == '.' && (path[1] == '/' || (path[1] == '.' && path[2] == '/'))); 69 } 70 71 72 /* duplicate a fd and close the old one only if necessary */ 73 74 extern int mvfd(int i, int j) { 75 if (i != j) { 76 int s = dup2(i, j); 77 close(i); 78 return s; 79 } 80 return 0; 81 }