commit 33db3341a40340d0b9e0f0872131380cbb84cfcb
Author: Antoine Amarilli <a3nm@a3nm.net>
Date: Sat, 15 Dec 2012 19:34:13 +0100
initial commit
Diffstat:
select.c | | | 121 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 121 insertions(+), 0 deletions(-)
diff --git a/select.c b/select.c
@@ -0,0 +1,121 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/select.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <argp.h> // TODO
+#include <string.h>
+
+// TODO
+#define MAXFDS 242
+#define BUFSIZE 1024
+
+#define E_SELECT 2
+#define E_READ 4
+
+int fds[MAXFDS];
+fd_set rfds;
+int nfds;
+
+int initfds() {
+ int i, max = -1;
+ for (i = 0; i < nfds; i++) {
+ if (fds[i] < 0)
+ continue;
+ FD_SET(fds[i], &rfds);
+ if (fds[i] > max)
+ max = fds[i];
+ }
+ return max;
+}
+
+int main(int argc, char **argv) {
+ int i, j, ret, max = 0;
+ int ready;
+ char buf[1024];
+ char separator[] = "\t";
+
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ nfds = argc;
+ fds[0] = -1;
+ // TODO
+ //if (argc == 1)
+ //FD_SET(0, &fds);
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "-")) {
+ fds[i] = 0;
+ continue;
+ }
+ fds[i] = open(argv[i], O_RDONLY | O_NONBLOCK);
+ //printf("opened %s pos %d to %d\n", argv[i], i, fds[i]);
+ if (fds[i] < 0) {
+ perror(argv[i]); // TODO better
+ // TODO exit?
+ continue;
+ }
+ }
+
+ max = initfds();
+
+ // TODO timeout?
+ // TODO signals?
+ while (max >= 0) {
+ //printf("\n\nabout to select max %d nfds %d\n", max+1, nfds);
+ ret = select(max+1, &rfds, NULL, NULL, NULL);
+ //printf("done selecting\n");
+ // ignore signals?
+ // if (r == -1 && errno == EINTR
+ // continue;
+ if (ret < 0) {
+ perror("select");
+ exit(E_SELECT);
+ }
+ for (i = 1; i < argc; i++) {
+ if (fds[i] < 0) continue;
+ if (!FD_ISSET(fds[i], &rfds)) continue;
+ ready = 1;
+ while (ready) {
+ ret = read(fds[i], buf, BUFSIZE);
+ //printf("%s%s/read %d", argv[i], separator, ret); // TODO
+ if (ret < 0) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ //printf("\n%s%s/wouldblock", argv[i], separator); // TODO
+ break;
+ }
+ // TODO signals?
+ // TODO accept errors here?
+ perror(argv[i]); // TODO better reporting?
+ exit(E_READ);
+ }
+ if (!ret) {
+ //printf("%s%s/closed", argv[i], separator); // TODO
+ FD_CLR(fds[i], &rfds);
+ close(fds[i]);
+ // TODO try to reopen?
+ fds[i] = -1;
+ break;
+ }
+ printf("%s%s", argv[i], separator);
+ // TODO is this really safe or might lines get cut?
+ for (j = 0; j < ret; j++) {
+ putchar(buf[j]);
+ if (buf[j] == '\n' && j != ret-1) {
+ printf("%s%s", argv[i], separator);
+ }
+ }
+ if (buf[ret-1] != '\n')
+ putchar('\n');
+ }
+ //printf("\n%s%s/doneread nfds%d", argv[i], separator, nfds); // TODO
+ max = initfds();
+ }
+ }
+ for (i = 1; i < argc; i++)
+ if (fds[i] > 0)
+ close(fds[i]);
+ return 0;
+}
+