select.c (2814B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <sys/select.h> 5 #include <sys/types.h> 6 #include <sys/stat.h> 7 #include <fcntl.h> 8 #include <argp.h> // TODO 9 #include <string.h> 10 11 // TODO 12 #define MAXFDS 242 13 #define BUFSIZE 1024 14 15 #define E_SELECT 2 16 #define E_READ 4 17 18 int fds[MAXFDS]; 19 fd_set rfds; 20 int nfds; 21 22 int initfds() { 23 int i, max = -1; 24 for (i = 0; i < nfds; i++) { 25 if (fds[i] < 0) 26 continue; 27 FD_SET(fds[i], &rfds); 28 if (fds[i] > max) 29 max = fds[i]; 30 } 31 return max; 32 } 33 34 int main(int argc, char **argv) { 35 int i, j, ret, max = 0; 36 int ready; 37 char buf[1024]; 38 char separator[] = "\t"; 39 40 setvbuf(stdout, NULL, _IONBF, 0); 41 42 nfds = argc; 43 fds[0] = -1; 44 // TODO 45 //if (argc == 1) 46 //FD_SET(0, &fds); 47 for (i = 1; i < argc; i++) { 48 if (!strcmp(argv[i], "-")) { 49 fds[i] = 0; 50 continue; 51 } 52 fds[i] = open(argv[i], O_RDONLY | O_NONBLOCK); 53 //printf("opened %s pos %d to %d\n", argv[i], i, fds[i]); 54 if (fds[i] < 0) { 55 perror(argv[i]); // TODO better 56 // TODO exit? 57 continue; 58 } 59 } 60 61 max = initfds(); 62 63 // TODO timeout? 64 // TODO signals? 65 while (max >= 0) { 66 //printf("\n\nabout to select max %d nfds %d\n", max+1, nfds); 67 ret = select(max+1, &rfds, NULL, NULL, NULL); 68 //printf("done selecting\n"); 69 // ignore signals? 70 // if (r == -1 && errno == EINTR 71 // continue; 72 if (ret < 0) { 73 perror("select"); 74 exit(E_SELECT); 75 } 76 for (i = 1; i < argc; i++) { 77 if (fds[i] < 0) continue; 78 if (!FD_ISSET(fds[i], &rfds)) continue; 79 ready = 1; 80 while (ready) { 81 ret = read(fds[i], buf, BUFSIZE); 82 //printf("%s%s/read %d", argv[i], separator, ret); // TODO 83 if (ret < 0) { 84 if (errno == EAGAIN || errno == EWOULDBLOCK) { 85 //printf("\n%s%s/wouldblock", argv[i], separator); // TODO 86 break; 87 } 88 // TODO signals? 89 // TODO accept errors here? 90 perror(argv[i]); // TODO better reporting? 91 exit(E_READ); 92 } 93 if (!ret) { 94 //printf("%s%s/closed", argv[i], separator); // TODO 95 FD_CLR(fds[i], &rfds); 96 close(fds[i]); 97 // TODO try to reopen? 98 fds[i] = -1; 99 break; 100 } 101 printf("%s%s", argv[i], separator); 102 // TODO is this really safe or might lines get cut? 103 for (j = 0; j < ret; j++) { 104 putchar(buf[j]); 105 if (buf[j] == '\n' && j != ret-1) { 106 printf("%s%s", argv[i], separator); 107 } 108 } 109 if (buf[ret-1] != '\n') 110 putchar('\n'); 111 } 112 //printf("\n%s%s/doneread nfds%d", argv[i], separator, nfds); // TODO 113 max = initfds(); 114 } 115 } 116 for (i = 1; i < argc; i++) 117 if (fds[i] > 0) 118 close(fds[i]); 119 return 0; 120 } 121