1 /**
2 * @file
3 * @section AUTHORS
4 *
5 * Copyright (C) 2010 Rafal Wojtczuk <rafal@invisiblethingslab.com>
6 *
7 * Authors:
8 * Rafal Wojtczuk <rafal@invisiblethingslab.com>
9 * Daniel De Graaf <dgdegra@tycho.nsa.gov>
10 *
11 * @section LICENSE
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; either
16 * version 2.1 of the License, or (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
22 *
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with this program; If not, see <http://www.gnu.org/licenses/>.
25 *
26 * @section DESCRIPTION
27 *
28 * This is a test program for libxenvchan. Communications are in one direction,
29 * either server (grant offeror) to client or vice versa.
30 */
31
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <unistd.h>
36 #include <time.h>
37
38 #include <libxenvchan.h>
39
libxenvchan_write_all(struct libxenvchan * ctrl,char * buf,int size)40 int libxenvchan_write_all(struct libxenvchan *ctrl, char *buf, int size)
41 {
42 int written = 0;
43 int ret;
44 while (written < size) {
45 ret = libxenvchan_write(ctrl, buf + written, size - written);
46 if (ret <= 0) {
47 perror("write");
48 exit(1);
49 }
50 written += ret;
51 }
52 return size;
53 }
54
write_all(int fd,char * buf,int size)55 int write_all(int fd, char *buf, int size)
56 {
57 int written = 0;
58 int ret;
59 while (written < size) {
60 ret = write(fd, buf + written, size - written);
61 if (ret <= 0) {
62 perror("write");
63 exit(1);
64 }
65 written += ret;
66 }
67 return size;
68 }
69
usage(char ** argv)70 void usage(char** argv)
71 {
72 fprintf(stderr, "usage:\n"
73 "%s [client|server] [read|write] domid nodepath\n", argv[0]);
74 exit(1);
75 }
76
77 #define BUFSIZE 5000
78 char buf[BUFSIZE];
reader(struct libxenvchan * ctrl)79 void reader(struct libxenvchan *ctrl)
80 {
81 int size;
82 for (;;) {
83 size = rand() % (BUFSIZE - 1) + 1;
84 size = libxenvchan_read(ctrl, buf, size);
85 fprintf(stderr, "#");
86 if (size < 0) {
87 perror("read vchan");
88 libxenvchan_close(ctrl);
89 exit(1);
90 }
91 size = write_all(1, buf, size);
92 if (size < 0) {
93 perror("stdout write");
94 exit(1);
95 }
96 if (size == 0) {
97 perror("write size=0?\n");
98 exit(1);
99 }
100 }
101 }
102
writer(struct libxenvchan * ctrl)103 void writer(struct libxenvchan *ctrl)
104 {
105 int size;
106 for (;;) {
107 size = rand() % (BUFSIZE - 1) + 1;
108 size = read(0, buf, size);
109 if (size < 0) {
110 perror("read stdin");
111 libxenvchan_close(ctrl);
112 exit(1);
113 }
114 if (size == 0)
115 break;
116 size = libxenvchan_write_all(ctrl, buf, size);
117 fprintf(stderr, "#");
118 if (size < 0) {
119 perror("vchan write");
120 exit(1);
121 }
122 if (size == 0) {
123 perror("write size=0?\n");
124 exit(1);
125 }
126 }
127 }
128
129
130 /**
131 Simple libxenvchan application, both client and server.
132 One side does writing, the other side does reading; both from
133 standard input/output fds.
134 */
main(int argc,char ** argv)135 int main(int argc, char **argv)
136 {
137 int seed = time(0);
138 struct libxenvchan *ctrl = 0;
139 int wr = 0;
140 if (argc < 4)
141 usage(argv);
142 if (!strcmp(argv[2], "read"))
143 wr = 0;
144 else if (!strcmp(argv[2], "write"))
145 wr = 1;
146 else
147 usage(argv);
148 if (!strcmp(argv[1], "server"))
149 ctrl = libxenvchan_server_init(NULL, atoi(argv[3]), argv[4], 0, 0);
150 else if (!strcmp(argv[1], "client"))
151 ctrl = libxenvchan_client_init(NULL, atoi(argv[3]), argv[4]);
152 else
153 usage(argv);
154 if (!ctrl) {
155 perror("libxenvchan_*_init");
156 exit(1);
157 }
158 ctrl->blocking = 1;
159
160 srand(seed);
161 fprintf(stderr, "seed=%d\n", seed);
162 if (wr)
163 writer(ctrl);
164 else
165 reader(ctrl);
166 libxenvchan_close(ctrl);
167 return 0;
168 }
169