Initial import of kqueue files:
[eleutheria.git] / kqclient.c
blob1e3f0f5fd4c061614e87dd6d4dc077a7aa5d5ed1
1 #include <netinet/in.h>
2 #include <sys/event.h>
3 #include <sys/socket.h>
4 #include <sys/time.h>
5 #include <netdb.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
11 #define BUFSIZE 1024
13 /* function prototypes */
14 void diep(const char *s);
15 int tcpopen(const char *host, int port);
16 void sendbuftosck(int sckfd, const char *buf, int len);
18 int main(int argc, char *argv[])
20 struct kevent chlist[2]; /* events we want to monitor */
21 struct kevent evlist[2]; /* events that were triggered */
22 char buf[BUFSIZE];
23 int sckfd, kq, nev, i;
25 /* check argument count */
26 if (argc != 3) {
27 fprintf(stderr, "usage: %s host port\n", argv[0]);
28 exit(EXIT_FAILURE);
31 /* open a connection to a host:port pair */
32 sckfd = tcpopen(argv[1], atoi(argv[2]));
34 /* create a new kernel event queue */
35 if ((kq = kqueue()) == -1)
36 diep("kqueue()");
38 /* initialise kevent structures */
39 EV_SET(&chlist[0], sckfd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
40 EV_SET(&chlist[1], fileno(stdin), EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
42 /* loop forever */
43 for (;;) {
44 nev = kevent(kq, chlist, 2, evlist, 2, NULL);
46 if (nev < 0)
47 diep("kevent()");
49 else if (nev > 0) {
50 if (evlist[0].flags & EV_EOF) /* read direction of socket has shutdown */
51 exit(EXIT_FAILURE);
53 for (i = 0; i < nev; i++) {
54 if (evlist[i].flags & EV_ERROR) { /* report errors */
55 fprintf(stderr, "EV_ERROR: %s\n", strerror(evlist[i].data));
56 exit(EXIT_FAILURE);
59 if (evlist[i].ident == sckfd) { /* we have data from the host */
60 memset(buf, 0, BUFSIZE);
61 if (read(sckfd, buf, BUFSIZE) < 0)
62 diep("read()");
63 fputs(buf, stdout);
66 else if (evlist[i].ident == fileno(stdin)) { /* we have data from stdin */
67 memset(buf, 0, BUFSIZE);
68 fgets(buf, BUFSIZE, stdin);
69 sendbuftosck(sckfd, buf, strlen(buf));
75 close(kq);
76 return EXIT_SUCCESS;
79 void diep(const char *s)
81 perror(s);
82 exit(EXIT_FAILURE);
85 int tcpopen(const char *host, int port)
87 struct sockaddr_in server;
88 struct hostent *hp;
89 int sckfd;
91 if ((hp = gethostbyname(host)) == NULL)
92 diep("gethostbyname()");
94 if ((sckfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
95 diep("socket()");
97 server.sin_family = AF_INET;
98 server.sin_port = htons(port);
99 server.sin_addr = *((struct in_addr *)hp->h_addr);
100 memset(&(server.sin_zero), 0, 8);
102 if (connect(sckfd, (struct sockaddr *)&server, sizeof(struct sockaddr)) < 0)
103 diep("connect()");
105 return sckfd;
108 void sendbuftosck(int sckfd, const char *buf, int len)
110 int bytessent, pos;
112 pos = 0;
113 do {
114 if ((bytessent = send(sckfd, buf + pos, len - pos, 0)) < 0)
115 diep("send()");
116 pos += bytessent;
117 } while (bytessent > 0);