dcdccdd471574ce34b94b05a8194835470ccb2d1
[silc.git] / lib / silcutil / tests / test_silcfdstream.c
1 /* SILC FD Stream tests */
2
3 #include "silcincludes.h"
4
5 SilcBool success = FALSE;
6 SilcSchedule schedule;
7 SilcStream stream;
8 char buf1[10240];
9 int buf1_len = sizeof(buf1);
10
11 static void stream_notifier(SilcStream stream, SilcStreamStatus status,
12                             void *context)
13 {
14   SILC_LOG_DEBUG(("Notifier"));
15
16   /* XXX we probably never get here with this test program */
17
18   silc_fsm_continue(context);
19 }
20
21 static void stream_notifier2(SilcStream stream, SilcStreamStatus status,
22                              void *context)
23 {
24   SILC_LOG_DEBUG(("Notifier"));
25
26   /* XXX we probably never get here with this test program */
27
28   silc_fsm_continue(context);
29 }
30
31 SILC_FSM_STATE(st_end)
32 {
33   unlink("/tmp/test_silcfdstream");
34   unlink("/tmp/test_silcfdstream_copy");
35   return SILC_FSM_FINISH;
36 }
37
38 SILC_FSM_STATE(st_readwrite)
39 {
40   int ret, i, k, fd1, fd2;
41   char *cp;
42
43   SILC_LOG_DEBUG(("Opening two files, one for reading, one for writing"));
44
45   SILC_LOG_DEBUG(("Open file /tmp/test_silcfdstream for reading"));
46   fd1 = silc_file_open("/tmp/test_silcfdstream", O_RDONLY);
47   if (fd1 < 0) {
48     SILC_LOG_DEBUG(("Error opening file"));
49     goto err;
50   }
51
52   SILC_LOG_DEBUG(("Open file /tmp/test_silcfdstream_copy for writing"));
53   unlink("/tmp/test_silcfdstream_copy");
54   fd2 = silc_file_open("/tmp/test_silcfdstream_copy", O_CREAT | O_WRONLY);
55   if (fd2 < 0) {
56     SILC_LOG_DEBUG(("Error opening file"));
57     goto err;
58   }
59
60   SILC_LOG_DEBUG(("Creating FD stream (two fds)"));
61   stream = silc_fd_stream_create2(fd1, fd2, schedule);
62   if (!stream) {
63     SILC_LOG_DEBUG(("Error creating stream"));
64     goto err;
65   }
66
67   silc_stream_set_notifier(stream, stream_notifier2, fsm);
68
69   /* Stream between the fiels */
70   SILC_LOG_DEBUG(("Read/write 3 bytes at a time"));
71   memset(buf1, 0, sizeof(buf1));
72   while ((ret = silc_stream_read(stream, buf1, 3)) > 0) {
73     k = ret;
74     cp = buf1;
75     while (k > 0) {
76       i = silc_stream_write(stream, cp, k);
77
78       if (i == 0) {
79         SILC_LOG_DEBUG(("EOF"));
80         goto err;
81       }
82
83       if (i == -1) {
84         SILC_LOG_DEBUG(("Would block, write later"));
85         silc_fsm_next(fsm, st_end);
86         return SILC_FSM_WAIT;
87       }
88
89       if (i == -2) {
90         SILC_LOG_DEBUG(("Error: %s", strerror(silc_fd_stream_get_error(stream))));
91         goto err;
92       }
93
94       k -= i;
95       cp += i;
96     }
97   }
98
99   if (ret == -1) {
100     SILC_LOG_DEBUG(("Would block, read later"));
101     silc_fsm_next(fsm, st_end);
102     return SILC_FSM_WAIT;
103   }
104
105   if (ret == -2) {
106     SILC_LOG_DEBUG(("Error: %s", strerror(silc_fd_stream_get_error(stream))));
107     goto err;
108   }
109
110   if (ret == 0) {
111     SILC_LOG_DEBUG(("EOF, ok"));
112     success = TRUE;
113     SILC_LOG_DEBUG(("Closing stream"));
114     silc_stream_close(stream);
115     SILC_LOG_DEBUG(("Destroying stream"));
116     silc_stream_destroy(stream);
117   }
118  
119   silc_fsm_next(fsm, st_end);
120   return SILC_FSM_CONTINUE;
121
122  err:
123   silc_fsm_next(fsm, st_end);
124   return SILC_FSM_CONTINUE;
125 }
126
127 SILC_FSM_STATE(st_write)
128 {
129   int ret, i, k, fd;
130   char *cp;
131
132   /* Simple writing example */
133   SILC_LOG_DEBUG(("Open file /tmp/test_silcfdstream for writing"));
134
135   unlink("/tmp/test_silcfdstream");
136   fd = silc_file_open("/tmp/test_silcfdstream", O_CREAT | O_RDWR);
137   if (fd < 0) {
138     SILC_LOG_DEBUG(("Error opening file"));
139     goto err;
140   }
141
142   SILC_LOG_DEBUG(("Creating FD stream"));
143   stream = silc_fd_stream_create(fd, schedule);
144   if (!stream) {
145     SILC_LOG_DEBUG(("Error creating stream"));
146     goto err;
147   }
148
149   silc_stream_set_notifier(stream, stream_notifier, fsm);
150
151   memset(buf1, 0, sizeof(buf1));
152   for (i = 0; i < sizeof(buf1); i++)
153     buf1[i] = i;
154
155   SILC_LOG_DEBUG(("Writing data"));
156   k = buf1_len;
157   cp = buf1;
158   while (k > 0) {
159     ret = silc_stream_write(stream, cp, k);
160
161     if (ret == 0) {
162       SILC_LOG_DEBUG(("EOF"));
163       goto err;
164     }
165
166     if (ret == -1) {
167       SILC_LOG_DEBUG(("Would block, write later"));
168       silc_fsm_next(fsm, st_readwrite);
169       return SILC_FSM_WAIT;
170     }
171
172     if (ret == -2) {
173       SILC_LOG_DEBUG(("Error: %s", strerror(silc_fd_stream_get_error(stream))));
174       goto err;
175     }
176
177     k -= ret;
178     cp += ret;
179   }
180
181   SILC_LOG_DEBUG(("Closing stream"));
182   silc_stream_close(stream);
183
184   SILC_LOG_DEBUG(("Destroying stream"));
185   silc_stream_destroy(stream);
186
187   SILC_LOG_DEBUG(("Continue to next state"));
188   silc_fsm_next(fsm, st_readwrite);
189   return SILC_FSM_CONTINUE;
190
191  err:
192   silc_fsm_next(fsm, st_end);
193   return SILC_FSM_CONTINUE;
194 }
195
196 static void fsm_dest(SilcFSM fsm, void *fsm_context, void *context)
197 {
198   silc_fsm_free(fsm);
199   silc_schedule_stop(schedule);
200 }
201
202 int main(int argc, char **argv)
203 {
204   SilcFSM fsm;
205
206   if (argc > 1 && !strcmp(argv[1], "-d")) {
207     silc_log_debug(TRUE);
208     silc_log_debug_hexdump(TRUE);
209     silc_log_set_debug_string("fdstream*");
210   }
211
212   SILC_LOG_DEBUG(("Allocating scheduler"));
213   schedule = silc_schedule_init(0, NULL);
214   if (!schedule)
215     goto err;
216
217   SILC_LOG_DEBUG(("Allocating FSM"));
218   fsm = silc_fsm_alloc(NULL, fsm_dest, NULL, schedule);
219   if (!fsm)
220     goto err;
221
222   silc_fsm_start(fsm, st_write);
223
224   SILC_LOG_DEBUG(("Running scheduler"));
225   silc_schedule(schedule);
226
227   if (!success)
228     goto err;
229
230   silc_schedule_uninit(schedule);
231   success = TRUE;
232
233  err:
234   SILC_LOG_DEBUG(("Testing was %s", success ? "SUCCESS" : "FAILURE"));
235   fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE");
236
237   return success;
238 }