Add .gitignore
[splice.git] / splice-net.c
1 /*
2  * Splice stdin to net
3  */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <unistd.h>
7 #include <netdb.h>
8 #include <unistd.h>
9 #include <fcntl.h>
10 #include <signal.h>
11 #include <netinet/in.h>
12 #include <arpa/inet.h>
13 #include <string.h>
14 #include <sys/time.h>
15 #include <errno.h>
16
17 #include "splice.h"
18
19 static struct timeval start_time;
20 static unsigned long long kb_sent;
21 static unsigned long iters;
22
23 static unsigned long mtime_since(struct timeval *s, struct timeval *e)
24 {
25         double sec, usec;
26
27         sec = e->tv_sec - s->tv_sec;
28         usec = e->tv_usec - s->tv_usec;
29         if (sec > 0 && usec < 0) {
30                 sec--;
31                 usec += 1000000;
32         }
33
34         sec *= (double) 1000;
35         usec /= (double) 1000;
36
37         return sec + usec;
38 }
39
40 static unsigned long mtime_since_now(struct timeval *s)
41 {
42         struct timeval t;
43
44         gettimeofday(&t, NULL);
45         return mtime_since(s, &t);
46 }
47
48 void show_rate(int sig)
49 {
50         unsigned long msecs = mtime_since_now(&start_time);
51
52         printf("Throughput: %LuMiB/sec (%Lu MiB in %lu msecs)\n", kb_sent / msecs, kb_sent, msecs);
53         printf("avg put: %Lu\n", kb_sent / iters);
54 }
55
56 int main(int argc, char *argv[])
57 {
58         struct sockaddr_in addr;
59         unsigned short port;
60         int fd, pfd[2], ffd, ret;
61         int bla = 1;
62
63         if (argc < 4) {
64                 printf("%s: file target port\n", argv[0]);
65                 return 1;
66         }
67
68         port = atoi(argv[3]);
69
70         memset(&addr, 0, sizeof(addr));
71         addr.sin_family = AF_INET;
72         addr.sin_port = htons(port);
73
74         if (inet_aton(argv[2], &addr.sin_addr) != 1) {
75                 struct hostent *hent = gethostbyname(argv[2]);
76
77                 if (!hent)
78                         return error("gethostbyname");
79
80                 memcpy(&addr.sin_addr, hent->h_addr, 4);
81         }
82
83         printf("Connecting to %s/%d\n", argv[2], port);
84
85         fd = socket(AF_INET, SOCK_STREAM, 0);
86         if (fd < 0)
87                 return error("socket");
88
89         if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
90                 return error("connect");
91
92         if (pipe(pfd) < 0)
93                 return error("pipe");
94
95         ffd = open(argv[1], O_RDWR);
96         if (ffd < 0)
97                 return error("open input");
98
99         signal(SIGINT, show_rate);
100         gettimeofday(&start_time, NULL);
101
102         do {
103                 ret = splice(ffd, NULL, pfd[1], NULL, SPLICE_SIZE, SPLICE_F_NONBLOCK);
104
105                 if (!bla)
106                         printf("spliced %d\n", ret);
107
108                 if (ret < 0) {
109                         if (errno == EAGAIN) {
110                                 usleep(100);
111                                 continue;
112                         }
113                         return error("splice");
114                 } else if (!ret)
115                         break;
116
117                 kb_sent += ret >> 10;
118                 iters++;
119                 while (ret > 0) {
120                         int flags = 0;
121                         int written = splice(pfd[0], NULL, fd, NULL, ret, flags);
122                         if (written < 0)
123                                 return error("splice-out");
124                         else if (!written)
125                                 break;
126                         ret -= written;
127                 }
128         } while (kb_sent < 512 * 1024 && bla);
129
130         show_rate(0);
131         close(fd);
132         return 0;
133 }