LCA2011 version
[tridge/junkcode.git] / socklib / sock_source.c
1 #include "socklib.h"
2
3
4 static char *tcp_options="TCP_NODELAY IPTOS_THROUGHPUT";
5 static int port=7001;
6 static int bufsize=0x10000;
7 static int use_sendfile;
8
9 #if WITH_SENDFILE
10 #include <sys/sendfile.h>
11
12 static int do_write(int fd, const char *buf, size_t size)
13 {
14         off_t offset = 0;
15         static int tmp_fd = -1;
16         char template[] = "/tmp/socklib.XXXXXX";
17
18         if (!use_sendfile) {
19                 return write(fd, buf, size);
20         }
21
22         if (tmp_fd == -1) {
23                 tmp_fd = mkstemp(template);
24                 if (tmp_fd == -1) {
25                         perror("mkstemp");
26                         exit(1);
27                 }
28                 unlink(template);
29                 write(tmp_fd, buf, size);
30         }
31
32         return sendfile(fd, tmp_fd, &offset, size);
33 }
34 #else
35 static int do_write(int fd, const char *buf, size_t size)
36 {
37         return write(fd, buf, size);
38 }
39 #endif
40
41 static void server(int fd)
42 {
43         char *buf;
44         uint64_t total=0;
45
46         signal(SIGPIPE, SIG_IGN);
47         
48         set_socket_options(fd, tcp_options);
49
50         buf = (char *)malloc(bufsize);
51         if (!buf) {
52                 fprintf(stderr,"out of memory\n");
53                 exit(1);
54         }
55
56         memset(buf, 'Z', bufsize);
57
58         start_timer();
59
60         while (1) {
61                 int ret = do_write(fd, buf, bufsize);
62                 if (ret <= 0) break;
63                 total += ret;
64                 if (end_timer() > 2.0) {
65                         report_time(total);
66                         total = 0;
67                         start_timer();
68                 }
69         }
70         report_time(total);
71
72         exit(0);
73 }
74
75 static void listener(void)
76 {
77         int sock;
78         
79         sock = open_socket_in(SOCK_STREAM, port, INADDR_ANY);
80
81         if (listen(sock, 5) == -1) {
82                 fprintf(stderr,"listen failed\n");
83                 exit(1);
84         }
85
86         while (1) {
87                 struct sockaddr addr;
88                 int in_addrlen = sizeof(addr);
89                 int fd;
90
91                 printf("waiting for connection\n");
92
93                 fd = accept(sock,&addr,&in_addrlen);
94
95                 if (fd != -1) {
96                         printf("accepted\n");
97                         if (fork() == 0) server(fd);
98                 }
99         }
100 }
101
102
103 static void usage(void)
104 {
105         printf("-p port\n-t socket options\n-b bufsize\n\n");
106         printf("Use -S to enable sendfile\n");
107 }
108
109 int main(int argc, char *argv[])
110 {
111         int opt;
112         extern char *optarg;
113
114         while ((opt = getopt (argc, argv, "p:t:H:b:hS")) != EOF) {
115                 switch (opt) {
116                 case 'p':
117                         port = strtol(optarg, NULL, 0);
118                         break;
119                 case 'S':
120 #if WITH_SENDFILE
121                         use_sendfile = 1;
122 #else
123                         printf("sendfile not compiled in\n");
124                         exit(1);
125 #endif
126                         break;
127                 case 't':
128                         tcp_options = optarg;
129                         break;
130                 case 'b':
131                         bufsize = strtol(optarg, NULL, 0);
132                         break;
133
134                 case 'h':
135                 default:
136                         usage();
137                         exit(1);
138                 }
139         }
140
141         printf("port=%d bufsize=%d options=[%s]\n", port, bufsize, tcp_options);
142
143         listener();
144
145         return 0;
146 }