nicer formatting
[tridge/junkcode.git] / nettest.c
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <errno.h>
4 #include <string.h>
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <stdlib.h>
8
9 static int am_sender;
10
11 #define rprintf fprintf
12 #define FERROR stderr
13 #define exit_cleanup(x) exit(1)
14 #define do_fork fork
15 #define STDIN_FILENO 0
16 #define STDOUT_FILENO 1
17
18 #define TOTAL_SIZE (10*1024*1024)
19
20 static int write_loop(int fd, char *buf, int size)
21 {
22         int total=0;
23
24         while (size) {
25                 int n = write(fd, buf, size);
26                 if (n <= 0) break;
27                 size -= n;
28                 buf += n;
29                 total += n;
30         }
31         return total;
32 }
33
34 int piped_child(char *command,int *f_in,int *f_out)
35 {
36   int pid;
37   int to_child_pipe[2];
38   int from_child_pipe[2];
39
40   if (pipe(to_child_pipe) < 0 ||
41       pipe(from_child_pipe) < 0) {
42     rprintf(FERROR,"pipe: %s\n",strerror(errno));
43     exit_cleanup(RERR_IPC);
44   }
45
46
47   pid = do_fork();
48   if (pid < 0) {
49     rprintf(FERROR,"fork: %s\n",strerror(errno));
50     exit_cleanup(RERR_IPC);
51   }
52
53   if (pid == 0)
54     {
55       if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
56           close(to_child_pipe[1]) < 0 ||
57           close(from_child_pipe[0]) < 0 ||
58           dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
59         rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
60         exit_cleanup(RERR_IPC);
61       }
62       if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
63       if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
64       system(command);
65       exit_cleanup(RERR_IPC);
66     }
67
68   if (close(from_child_pipe[1]) < 0 ||
69       close(to_child_pipe[0]) < 0) {
70     rprintf(FERROR,"Failed to close : %s\n",strerror(errno));   
71     exit_cleanup(RERR_IPC);
72   }
73
74   *f_in = from_child_pipe[0];
75   *f_out = to_child_pipe[1];
76
77   return pid;
78 }
79
80 static void sender(int fin, int fout)
81 {
82         int n;
83         char buf[1024];
84         int total = 0;
85
86         while (total < TOTAL_SIZE) {
87                 n = read(fin, buf, sizeof(buf));
88                 if (n <= 0) {
89                         fprintf(stderr,"write error in sender at %d\n", total);
90                         break;
91                 }
92                 write_loop(fout, buf, n);
93                 total += n;
94                 fprintf(stderr, "-");
95         }
96         fprintf(stderr, "sender done\n");
97 }
98
99 static void generator(int fd)
100 {
101         int n;
102         char buf[1024];
103         int total=0;
104
105         while (total < TOTAL_SIZE) {
106                 n = 1 + random() % (sizeof(buf)-1);
107                 n = write_loop(fd, buf, n);
108                 if (n <= 0) {
109                         fprintf(stderr,"write error in generator at %d\n", total);
110                         break;
111                 }
112                 total += n;
113                 fprintf(stderr, "*");
114         }
115         fprintf(stderr, "generator done\n");
116 }
117
118 static void receiver(int fd)
119 {
120         ssize_t n;
121         ssize_t total=0;
122         char buf[1024];
123
124         while (total < TOTAL_SIZE) {
125                 n = read(fd, buf, sizeof(buf));
126                 if (n <= 0) {
127                         fprintf(stderr,"read error in receiver\n");
128                         break;
129                 }
130                 total += n;
131                 fprintf(stderr, "+");
132         }
133         fprintf(stderr, "receiver done\n");
134 }
135
136 int main(int argc, char *argv[])
137 {
138         int c, f_in, f_out;
139
140         while ((c = getopt(argc, argv, "s")) != -1) {
141                 switch (c){
142                 case 's':
143                         am_sender = 1;
144                         break;
145                 }
146         }
147         
148         if (am_sender) {
149                 sender(0, 1);
150         } else {
151                 char *command = argv[1];
152                 printf("running %s\n", command);
153                 piped_child(command, &f_in, &f_out);
154                 if (fork()) {
155                         generator(f_out);
156                 } else {
157                         receiver(f_in);
158                 }
159         }
160
161         return 0;
162 }