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