balance.c (2056B)
1 /* balance.c 2 * 06jul05abu 3 */ 4 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <unistd.h> 8 #include <string.h> 9 #include <errno.h> 10 #include <signal.h> 11 #include <sys/wait.h> 12 13 int Len, Siz; 14 char *Line, **Data; 15 16 static void giveup(char *msg) { 17 fprintf(stderr, "balance: %s\n", msg); 18 exit(1); 19 } 20 21 static char *getLine(FILE *fp) { 22 int i, c; 23 char *s; 24 25 i = 0; 26 while ((c = getc_unlocked(fp)) != '\n') { 27 if (c == EOF) 28 return NULL; 29 Line[i] = c; 30 if (++i == Len && !(Line = realloc(Line, Len *= 2))) 31 giveup("No memory"); 32 } 33 Line[i] = '\0'; 34 if (!(s = strdup(Line))) 35 giveup("No memory"); 36 return s; 37 } 38 39 static void balance(char **data, int len) { 40 if (len) { 41 int n = (len + 1) / 2; 42 char **p = data + n - 1; 43 44 printf("%s\n", *p); 45 balance(data, n - 1); 46 balance(p + 1, len - n); 47 } 48 } 49 50 // balance [-<cmd> [<arg> ..]] 51 // balance [<file>] 52 int main(int ac, char *av[]) { 53 int cnt; 54 char *s; 55 pid_t pid = 0; 56 FILE *fp = stdin; 57 58 if (ac > 1) { 59 if (*av[1] == '-') { 60 int pfd[2]; 61 62 if (pipe(pfd) < 0) 63 giveup("Pipe error\n"); 64 if ((pid = fork()) == 0) { 65 close(pfd[0]); 66 if (pfd[1] != STDOUT_FILENO) 67 dup2(pfd[1], STDOUT_FILENO), close(pfd[1]); 68 execvp(av[1]+1, av+1); 69 } 70 if (pid < 0) 71 giveup("Fork error\n"); 72 close(pfd[1]); 73 if (!(fp = fdopen(pfd[0], "r"))) 74 giveup("Pipe open error\n"); 75 } 76 else if (!(fp = fopen(av[1], "r"))) 77 giveup("File open error\n"); 78 } 79 Line = malloc(Len = 4096); 80 Data = malloc((Siz = 4096) * sizeof(char*)); 81 for (cnt = 0; s = getLine(fp); ++cnt) { 82 if (cnt == Siz && !(Data = realloc(Data, (Siz *= 2) * sizeof(char*)))) 83 giveup("No memory"); 84 Data[cnt] = s; 85 } 86 if (pid) { 87 fclose(fp); 88 while (waitpid(pid, NULL, 0) < 0) 89 if (errno != EINTR) 90 giveup("Pipe close error\n"); 91 } 92 balance(Data, cnt); 93 return 0; 94 }