test-char.c 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471
  1. #include "qemu/osdep.h"
  2. #include <glib/gstdio.h>
  3. #include "qemu/config-file.h"
  4. #include "qemu/module.h"
  5. #include "qemu/option.h"
  6. #include "qemu/sockets.h"
  7. #include "chardev/char-fe.h"
  8. #include "chardev/char-mux.h"
  9. #include "sysemu/sysemu.h"
  10. #include "qapi/error.h"
  11. #include "qapi/qapi-commands-char.h"
  12. #include "qapi/qmp/qdict.h"
  13. #include "qom/qom-qobject.h"
  14. #include "io/channel-socket.h"
  15. #include "qapi/qobject-input-visitor.h"
  16. #include "qapi/qapi-visit-sockets.h"
  17. #include "socket-helpers.h"
  18. static bool quit;
  19. typedef struct FeHandler {
  20. int read_count;
  21. bool is_open;
  22. int openclose_count;
  23. bool openclose_mismatch;
  24. int last_event;
  25. char read_buf[128];
  26. } FeHandler;
  27. static void main_loop(void)
  28. {
  29. quit = false;
  30. do {
  31. main_loop_wait(false);
  32. } while (!quit);
  33. }
  34. static int fe_can_read(void *opaque)
  35. {
  36. FeHandler *h = opaque;
  37. return sizeof(h->read_buf) - h->read_count;
  38. }
  39. static void fe_read(void *opaque, const uint8_t *buf, int size)
  40. {
  41. FeHandler *h = opaque;
  42. g_assert_cmpint(size, <=, fe_can_read(opaque));
  43. memcpy(h->read_buf + h->read_count, buf, size);
  44. h->read_count += size;
  45. quit = true;
  46. }
  47. static void fe_event(void *opaque, int event)
  48. {
  49. FeHandler *h = opaque;
  50. bool new_open_state;
  51. h->last_event = event;
  52. switch (event) {
  53. case CHR_EVENT_BREAK:
  54. break;
  55. case CHR_EVENT_OPENED:
  56. case CHR_EVENT_CLOSED:
  57. h->openclose_count++;
  58. new_open_state = (event == CHR_EVENT_OPENED);
  59. if (h->is_open == new_open_state) {
  60. h->openclose_mismatch = true;
  61. }
  62. h->is_open = new_open_state;
  63. /* no break */
  64. default:
  65. quit = true;
  66. break;
  67. }
  68. }
  69. #ifdef _WIN32
  70. static void char_console_test_subprocess(void)
  71. {
  72. QemuOpts *opts;
  73. Chardev *chr;
  74. opts = qemu_opts_create(qemu_find_opts("chardev"), "console-label",
  75. 1, &error_abort);
  76. qemu_opt_set(opts, "backend", "console", &error_abort);
  77. chr = qemu_chr_new_from_opts(opts, NULL, NULL);
  78. g_assert_nonnull(chr);
  79. qemu_chr_write_all(chr, (const uint8_t *)"CONSOLE", 7);
  80. qemu_opts_del(opts);
  81. object_unparent(OBJECT(chr));
  82. }
  83. static void char_console_test(void)
  84. {
  85. g_test_trap_subprocess("/char/console/subprocess", 0, 0);
  86. g_test_trap_assert_passed();
  87. g_test_trap_assert_stdout("CONSOLE");
  88. }
  89. #endif
  90. static void char_stdio_test_subprocess(void)
  91. {
  92. Chardev *chr;
  93. CharBackend be;
  94. int ret;
  95. chr = qemu_chr_new("label", "stdio", NULL);
  96. g_assert_nonnull(chr);
  97. qemu_chr_fe_init(&be, chr, &error_abort);
  98. qemu_chr_fe_set_open(&be, true);
  99. ret = qemu_chr_fe_write(&be, (void *)"buf", 4);
  100. g_assert_cmpint(ret, ==, 4);
  101. qemu_chr_fe_deinit(&be, true);
  102. }
  103. static void char_stdio_test(void)
  104. {
  105. g_test_trap_subprocess("/char/stdio/subprocess", 0, 0);
  106. g_test_trap_assert_passed();
  107. g_test_trap_assert_stdout("buf");
  108. }
  109. static void char_ringbuf_test(void)
  110. {
  111. QemuOpts *opts;
  112. Chardev *chr;
  113. CharBackend be;
  114. char *data;
  115. int ret;
  116. opts = qemu_opts_create(qemu_find_opts("chardev"), "ringbuf-label",
  117. 1, &error_abort);
  118. qemu_opt_set(opts, "backend", "ringbuf", &error_abort);
  119. qemu_opt_set(opts, "size", "5", &error_abort);
  120. chr = qemu_chr_new_from_opts(opts, NULL, NULL);
  121. g_assert_null(chr);
  122. qemu_opts_del(opts);
  123. opts = qemu_opts_create(qemu_find_opts("chardev"), "ringbuf-label",
  124. 1, &error_abort);
  125. qemu_opt_set(opts, "backend", "ringbuf", &error_abort);
  126. qemu_opt_set(opts, "size", "2", &error_abort);
  127. chr = qemu_chr_new_from_opts(opts, NULL, &error_abort);
  128. g_assert_nonnull(chr);
  129. qemu_opts_del(opts);
  130. qemu_chr_fe_init(&be, chr, &error_abort);
  131. ret = qemu_chr_fe_write(&be, (void *)"buff", 4);
  132. g_assert_cmpint(ret, ==, 4);
  133. data = qmp_ringbuf_read("ringbuf-label", 4, false, 0, &error_abort);
  134. g_assert_cmpstr(data, ==, "ff");
  135. g_free(data);
  136. data = qmp_ringbuf_read("ringbuf-label", 4, false, 0, &error_abort);
  137. g_assert_cmpstr(data, ==, "");
  138. g_free(data);
  139. qemu_chr_fe_deinit(&be, true);
  140. /* check alias */
  141. opts = qemu_opts_create(qemu_find_opts("chardev"), "memory-label",
  142. 1, &error_abort);
  143. qemu_opt_set(opts, "backend", "memory", &error_abort);
  144. qemu_opt_set(opts, "size", "2", &error_abort);
  145. chr = qemu_chr_new_from_opts(opts, NULL, NULL);
  146. g_assert_nonnull(chr);
  147. object_unparent(OBJECT(chr));
  148. qemu_opts_del(opts);
  149. }
  150. static void char_mux_test(void)
  151. {
  152. QemuOpts *opts;
  153. Chardev *chr, *base;
  154. char *data;
  155. FeHandler h1 = { 0, false, 0, false, }, h2 = { 0, false, 0, false, };
  156. CharBackend chr_be1, chr_be2;
  157. opts = qemu_opts_create(qemu_find_opts("chardev"), "mux-label",
  158. 1, &error_abort);
  159. qemu_opt_set(opts, "backend", "ringbuf", &error_abort);
  160. qemu_opt_set(opts, "size", "128", &error_abort);
  161. qemu_opt_set(opts, "mux", "on", &error_abort);
  162. chr = qemu_chr_new_from_opts(opts, NULL, &error_abort);
  163. g_assert_nonnull(chr);
  164. qemu_opts_del(opts);
  165. qemu_chr_fe_init(&chr_be1, chr, &error_abort);
  166. qemu_chr_fe_set_handlers(&chr_be1,
  167. fe_can_read,
  168. fe_read,
  169. fe_event,
  170. NULL,
  171. &h1,
  172. NULL, true);
  173. qemu_chr_fe_init(&chr_be2, chr, &error_abort);
  174. qemu_chr_fe_set_handlers(&chr_be2,
  175. fe_can_read,
  176. fe_read,
  177. fe_event,
  178. NULL,
  179. &h2,
  180. NULL, true);
  181. qemu_chr_fe_take_focus(&chr_be2);
  182. base = qemu_chr_find("mux-label-base");
  183. g_assert_cmpint(qemu_chr_be_can_write(base), !=, 0);
  184. qemu_chr_be_write(base, (void *)"hello", 6);
  185. g_assert_cmpint(h1.read_count, ==, 0);
  186. g_assert_cmpint(h2.read_count, ==, 6);
  187. g_assert_cmpstr(h2.read_buf, ==, "hello");
  188. h2.read_count = 0;
  189. g_assert_cmpint(h1.last_event, !=, 42); /* should be MUX_OUT or OPENED */
  190. g_assert_cmpint(h2.last_event, !=, 42); /* should be MUX_IN or OPENED */
  191. /* sending event on the base broadcast to all fe, historical reasons? */
  192. qemu_chr_be_event(base, 42);
  193. g_assert_cmpint(h1.last_event, ==, 42);
  194. g_assert_cmpint(h2.last_event, ==, 42);
  195. qemu_chr_be_event(chr, -1);
  196. g_assert_cmpint(h1.last_event, ==, 42);
  197. g_assert_cmpint(h2.last_event, ==, -1);
  198. /* switch focus */
  199. qemu_chr_be_write(base, (void *)"\1b", 2);
  200. g_assert_cmpint(h1.last_event, ==, 42);
  201. g_assert_cmpint(h2.last_event, ==, CHR_EVENT_BREAK);
  202. qemu_chr_be_write(base, (void *)"\1c", 2);
  203. g_assert_cmpint(h1.last_event, ==, CHR_EVENT_MUX_IN);
  204. g_assert_cmpint(h2.last_event, ==, CHR_EVENT_MUX_OUT);
  205. qemu_chr_be_event(chr, -1);
  206. g_assert_cmpint(h1.last_event, ==, -1);
  207. g_assert_cmpint(h2.last_event, ==, CHR_EVENT_MUX_OUT);
  208. qemu_chr_be_write(base, (void *)"hello", 6);
  209. g_assert_cmpint(h2.read_count, ==, 0);
  210. g_assert_cmpint(h1.read_count, ==, 6);
  211. g_assert_cmpstr(h1.read_buf, ==, "hello");
  212. h1.read_count = 0;
  213. qemu_chr_be_write(base, (void *)"\1b", 2);
  214. g_assert_cmpint(h1.last_event, ==, CHR_EVENT_BREAK);
  215. g_assert_cmpint(h2.last_event, ==, CHR_EVENT_MUX_OUT);
  216. /* open/close state and corresponding events */
  217. g_assert_true(qemu_chr_fe_backend_open(&chr_be1));
  218. g_assert_true(qemu_chr_fe_backend_open(&chr_be2));
  219. g_assert_true(h1.is_open);
  220. g_assert_false(h1.openclose_mismatch);
  221. g_assert_true(h2.is_open);
  222. g_assert_false(h2.openclose_mismatch);
  223. h1.openclose_count = h2.openclose_count = 0;
  224. qemu_chr_fe_set_handlers(&chr_be1, NULL, NULL, NULL, NULL,
  225. NULL, NULL, false);
  226. qemu_chr_fe_set_handlers(&chr_be2, NULL, NULL, NULL, NULL,
  227. NULL, NULL, false);
  228. g_assert_cmpint(h1.openclose_count, ==, 0);
  229. g_assert_cmpint(h2.openclose_count, ==, 0);
  230. h1.is_open = h2.is_open = false;
  231. qemu_chr_fe_set_handlers(&chr_be1,
  232. NULL,
  233. NULL,
  234. fe_event,
  235. NULL,
  236. &h1,
  237. NULL, false);
  238. qemu_chr_fe_set_handlers(&chr_be2,
  239. NULL,
  240. NULL,
  241. fe_event,
  242. NULL,
  243. &h2,
  244. NULL, false);
  245. g_assert_cmpint(h1.openclose_count, ==, 1);
  246. g_assert_false(h1.openclose_mismatch);
  247. g_assert_cmpint(h2.openclose_count, ==, 1);
  248. g_assert_false(h2.openclose_mismatch);
  249. qemu_chr_be_event(base, CHR_EVENT_CLOSED);
  250. qemu_chr_be_event(base, CHR_EVENT_OPENED);
  251. g_assert_cmpint(h1.openclose_count, ==, 3);
  252. g_assert_false(h1.openclose_mismatch);
  253. g_assert_cmpint(h2.openclose_count, ==, 3);
  254. g_assert_false(h2.openclose_mismatch);
  255. qemu_chr_fe_set_handlers(&chr_be2,
  256. fe_can_read,
  257. fe_read,
  258. fe_event,
  259. NULL,
  260. &h2,
  261. NULL, false);
  262. qemu_chr_fe_set_handlers(&chr_be1,
  263. fe_can_read,
  264. fe_read,
  265. fe_event,
  266. NULL,
  267. &h1,
  268. NULL, false);
  269. /* remove first handler */
  270. qemu_chr_fe_set_handlers(&chr_be1, NULL, NULL, NULL, NULL,
  271. NULL, NULL, true);
  272. qemu_chr_be_write(base, (void *)"hello", 6);
  273. g_assert_cmpint(h1.read_count, ==, 0);
  274. g_assert_cmpint(h2.read_count, ==, 0);
  275. qemu_chr_be_write(base, (void *)"\1c", 2);
  276. qemu_chr_be_write(base, (void *)"hello", 6);
  277. g_assert_cmpint(h1.read_count, ==, 0);
  278. g_assert_cmpint(h2.read_count, ==, 6);
  279. g_assert_cmpstr(h2.read_buf, ==, "hello");
  280. h2.read_count = 0;
  281. /* print help */
  282. qemu_chr_be_write(base, (void *)"\1?", 2);
  283. data = qmp_ringbuf_read("mux-label-base", 128, false, 0, &error_abort);
  284. g_assert_cmpint(strlen(data), !=, 0);
  285. g_free(data);
  286. qemu_chr_fe_deinit(&chr_be1, false);
  287. qemu_chr_fe_deinit(&chr_be2, true);
  288. }
  289. static void websock_server_read(void *opaque, const uint8_t *buf, int size)
  290. {
  291. g_assert_cmpint(size, ==, 5);
  292. g_assert(memcmp(buf, "world", size) == 0);
  293. quit = true;
  294. }
  295. static int websock_server_can_read(void *opaque)
  296. {
  297. return 10;
  298. }
  299. static bool websock_check_http_headers(char *buf, int size)
  300. {
  301. int i;
  302. const char *ans[] = { "HTTP/1.1 101 Switching Protocols\r\n",
  303. "Server: QEMU VNC\r\n",
  304. "Upgrade: websocket\r\n",
  305. "Connection: Upgrade\r\n",
  306. "Sec-WebSocket-Accept:",
  307. "Sec-WebSocket-Protocol: binary\r\n" };
  308. for (i = 0; i < 6; i++) {
  309. if (g_strstr_len(buf, size, ans[i]) == NULL) {
  310. return false;
  311. }
  312. }
  313. return true;
  314. }
  315. static void websock_client_read(void *opaque, const uint8_t *buf, int size)
  316. {
  317. const uint8_t ping[] = { 0x89, 0x85, /* Ping header */
  318. 0x07, 0x77, 0x9e, 0xf9, /* Masking key */
  319. 0x6f, 0x12, 0xf2, 0x95, 0x68 /* "hello" */ };
  320. const uint8_t binary[] = { 0x82, 0x85, /* Binary header */
  321. 0x74, 0x90, 0xb9, 0xdf, /* Masking key */
  322. 0x03, 0xff, 0xcb, 0xb3, 0x10 /* "world" */ };
  323. Chardev *chr_client = opaque;
  324. if (websock_check_http_headers((char *) buf, size)) {
  325. qemu_chr_fe_write(chr_client->be, ping, sizeof(ping));
  326. } else if (buf[0] == 0x8a && buf[1] == 0x05) {
  327. g_assert(strncmp((char *) buf + 2, "hello", 5) == 0);
  328. qemu_chr_fe_write(chr_client->be, binary, sizeof(binary));
  329. } else {
  330. g_assert(buf[0] == 0x88 && buf[1] == 0x16);
  331. g_assert(strncmp((char *) buf + 4, "peer requested close", 10) == 0);
  332. quit = true;
  333. }
  334. }
  335. static int websock_client_can_read(void *opaque)
  336. {
  337. return 4096;
  338. }
  339. static void char_websock_test(void)
  340. {
  341. QObject *addr;
  342. QDict *qdict;
  343. const char *port;
  344. char *tmp;
  345. char *handshake_port;
  346. CharBackend be;
  347. CharBackend client_be;
  348. Chardev *chr_client;
  349. Chardev *chr = qemu_chr_new("server",
  350. "websocket:127.0.0.1:0,server,nowait", NULL);
  351. const char handshake[] = "GET / HTTP/1.1\r\n"
  352. "Upgrade: websocket\r\n"
  353. "Connection: Upgrade\r\n"
  354. "Host: localhost:%s\r\n"
  355. "Origin: http://localhost:%s\r\n"
  356. "Sec-WebSocket-Key: o9JHNiS3/0/0zYE1wa3yIw==\r\n"
  357. "Sec-WebSocket-Version: 13\r\n"
  358. "Sec-WebSocket-Protocol: binary\r\n\r\n";
  359. const uint8_t close[] = { 0x88, 0x82, /* Close header */
  360. 0xef, 0xaa, 0xc5, 0x97, /* Masking key */
  361. 0xec, 0x42 /* Status code */ };
  362. addr = object_property_get_qobject(OBJECT(chr), "addr", &error_abort);
  363. qdict = qobject_to(QDict, addr);
  364. port = qdict_get_str(qdict, "port");
  365. tmp = g_strdup_printf("tcp:127.0.0.1:%s", port);
  366. handshake_port = g_strdup_printf(handshake, port, port);
  367. qobject_unref(qdict);
  368. qemu_chr_fe_init(&be, chr, &error_abort);
  369. qemu_chr_fe_set_handlers(&be, websock_server_can_read, websock_server_read,
  370. NULL, NULL, chr, NULL, true);
  371. chr_client = qemu_chr_new("client", tmp, NULL);
  372. qemu_chr_fe_init(&client_be, chr_client, &error_abort);
  373. qemu_chr_fe_set_handlers(&client_be, websock_client_can_read,
  374. websock_client_read,
  375. NULL, NULL, chr_client, NULL, true);
  376. g_free(tmp);
  377. qemu_chr_write_all(chr_client,
  378. (uint8_t *) handshake_port,
  379. strlen(handshake_port));
  380. g_free(handshake_port);
  381. main_loop();
  382. g_assert(object_property_get_bool(OBJECT(chr), "connected", &error_abort));
  383. g_assert(object_property_get_bool(OBJECT(chr_client),
  384. "connected", &error_abort));
  385. qemu_chr_write_all(chr_client, close, sizeof(close));
  386. main_loop();
  387. object_unparent(OBJECT(chr_client));
  388. object_unparent(OBJECT(chr));
  389. }
  390. #ifndef _WIN32
  391. static void char_pipe_test(void)
  392. {
  393. gchar *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL);
  394. gchar *tmp, *in, *out, *pipe = g_build_filename(tmp_path, "pipe", NULL);
  395. Chardev *chr;
  396. CharBackend be;
  397. int ret, fd;
  398. char buf[10];
  399. FeHandler fe = { 0, };
  400. in = g_strdup_printf("%s.in", pipe);
  401. if (mkfifo(in, 0600) < 0) {
  402. abort();
  403. }
  404. out = g_strdup_printf("%s.out", pipe);
  405. if (mkfifo(out, 0600) < 0) {
  406. abort();
  407. }
  408. tmp = g_strdup_printf("pipe:%s", pipe);
  409. chr = qemu_chr_new("pipe", tmp, NULL);
  410. g_assert_nonnull(chr);
  411. g_free(tmp);
  412. qemu_chr_fe_init(&be, chr, &error_abort);
  413. ret = qemu_chr_fe_write(&be, (void *)"pipe-out", 9);
  414. g_assert_cmpint(ret, ==, 9);
  415. fd = open(out, O_RDWR);
  416. ret = read(fd, buf, sizeof(buf));
  417. g_assert_cmpint(ret, ==, 9);
  418. g_assert_cmpstr(buf, ==, "pipe-out");
  419. close(fd);
  420. fd = open(in, O_WRONLY);
  421. ret = write(fd, "pipe-in", 8);
  422. g_assert_cmpint(ret, ==, 8);
  423. close(fd);
  424. qemu_chr_fe_set_handlers(&be,
  425. fe_can_read,
  426. fe_read,
  427. fe_event,
  428. NULL,
  429. &fe,
  430. NULL, true);
  431. main_loop();
  432. g_assert_cmpint(fe.read_count, ==, 8);
  433. g_assert_cmpstr(fe.read_buf, ==, "pipe-in");
  434. qemu_chr_fe_deinit(&be, true);
  435. g_assert(g_unlink(in) == 0);
  436. g_assert(g_unlink(out) == 0);
  437. g_assert(g_rmdir(tmp_path) == 0);
  438. g_free(in);
  439. g_free(out);
  440. g_free(tmp_path);
  441. g_free(pipe);
  442. }
  443. #endif
  444. typedef struct SocketIdleData {
  445. GMainLoop *loop;
  446. Chardev *chr;
  447. bool conn_expected;
  448. CharBackend *be;
  449. CharBackend *client_be;
  450. } SocketIdleData;
  451. static void socket_read_hello(void *opaque, const uint8_t *buf, int size)
  452. {
  453. g_assert_cmpint(size, ==, 5);
  454. g_assert(strncmp((char *)buf, "hello", 5) == 0);
  455. quit = true;
  456. }
  457. static int socket_can_read_hello(void *opaque)
  458. {
  459. return 10;
  460. }
  461. static int make_udp_socket(int *port)
  462. {
  463. struct sockaddr_in addr = { 0, };
  464. socklen_t alen = sizeof(addr);
  465. int ret, sock = qemu_socket(PF_INET, SOCK_DGRAM, 0);
  466. g_assert_cmpint(sock, >, 0);
  467. addr.sin_family = AF_INET ;
  468. addr.sin_addr.s_addr = htonl(INADDR_ANY);
  469. addr.sin_port = 0;
  470. ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
  471. g_assert_cmpint(ret, ==, 0);
  472. ret = getsockname(sock, (struct sockaddr *)&addr, &alen);
  473. g_assert_cmpint(ret, ==, 0);
  474. *port = ntohs(addr.sin_port);
  475. return sock;
  476. }
  477. static void char_udp_test_internal(Chardev *reuse_chr, int sock)
  478. {
  479. struct sockaddr_in other;
  480. SocketIdleData d = { 0, };
  481. Chardev *chr;
  482. CharBackend *be;
  483. socklen_t alen = sizeof(other);
  484. int ret;
  485. char buf[10];
  486. char *tmp = NULL;
  487. if (reuse_chr) {
  488. chr = reuse_chr;
  489. be = chr->be;
  490. } else {
  491. int port;
  492. sock = make_udp_socket(&port);
  493. tmp = g_strdup_printf("udp:127.0.0.1:%d", port);
  494. chr = qemu_chr_new("client", tmp, NULL);
  495. g_assert_nonnull(chr);
  496. be = g_alloca(sizeof(CharBackend));
  497. qemu_chr_fe_init(be, chr, &error_abort);
  498. }
  499. d.chr = chr;
  500. qemu_chr_fe_set_handlers(be, socket_can_read_hello, socket_read_hello,
  501. NULL, NULL, &d, NULL, true);
  502. ret = qemu_chr_write_all(chr, (uint8_t *)"hello", 5);
  503. g_assert_cmpint(ret, ==, 5);
  504. ret = recvfrom(sock, buf, sizeof(buf), 0,
  505. (struct sockaddr *)&other, &alen);
  506. g_assert_cmpint(ret, ==, 5);
  507. ret = sendto(sock, buf, 5, 0, (struct sockaddr *)&other, alen);
  508. g_assert_cmpint(ret, ==, 5);
  509. main_loop();
  510. if (!reuse_chr) {
  511. close(sock);
  512. qemu_chr_fe_deinit(be, true);
  513. }
  514. g_free(tmp);
  515. }
  516. static void char_udp_test(void)
  517. {
  518. char_udp_test_internal(NULL, 0);
  519. }
  520. typedef struct {
  521. int event;
  522. bool got_pong;
  523. } CharSocketTestData;
  524. #define SOCKET_PING "Hello"
  525. #define SOCKET_PONG "World"
  526. static void
  527. char_socket_event(void *opaque, int event)
  528. {
  529. CharSocketTestData *data = opaque;
  530. data->event = event;
  531. }
  532. static void
  533. char_socket_read(void *opaque, const uint8_t *buf, int size)
  534. {
  535. CharSocketTestData *data = opaque;
  536. g_assert_cmpint(size, ==, sizeof(SOCKET_PONG));
  537. g_assert(memcmp(buf, SOCKET_PONG, size) == 0);
  538. data->got_pong = true;
  539. }
  540. static int
  541. char_socket_can_read(void *opaque)
  542. {
  543. return sizeof(SOCKET_PONG);
  544. }
  545. static char *
  546. char_socket_addr_to_opt_str(SocketAddress *addr, bool fd_pass,
  547. const char *reconnect, bool is_listen)
  548. {
  549. if (fd_pass) {
  550. QIOChannelSocket *ioc = qio_channel_socket_new();
  551. int fd;
  552. char *optstr;
  553. g_assert(!reconnect);
  554. if (is_listen) {
  555. qio_channel_socket_listen_sync(ioc, addr, 1, &error_abort);
  556. } else {
  557. qio_channel_socket_connect_sync(ioc, addr, &error_abort);
  558. }
  559. fd = ioc->fd;
  560. ioc->fd = -1;
  561. optstr = g_strdup_printf("socket,id=cdev0,fd=%d%s",
  562. fd, is_listen ? ",server,nowait" : "");
  563. object_unref(OBJECT(ioc));
  564. return optstr;
  565. } else {
  566. switch (addr->type) {
  567. case SOCKET_ADDRESS_TYPE_INET:
  568. return g_strdup_printf("socket,id=cdev0,host=%s,port=%s%s%s",
  569. addr->u.inet.host,
  570. addr->u.inet.port,
  571. reconnect ? reconnect : "",
  572. is_listen ? ",server,nowait" : "");
  573. case SOCKET_ADDRESS_TYPE_UNIX:
  574. return g_strdup_printf("socket,id=cdev0,path=%s%s%s",
  575. addr->u.q_unix.path,
  576. reconnect ? reconnect : "",
  577. is_listen ? ",server,nowait" : "");
  578. default:
  579. g_assert_not_reached();
  580. }
  581. }
  582. }
  583. static void
  584. char_socket_ping_pong(QIOChannel *ioc)
  585. {
  586. char greeting[sizeof(SOCKET_PING)];
  587. const char *response = SOCKET_PONG;
  588. qio_channel_read_all(ioc, greeting, sizeof(greeting), &error_abort);
  589. g_assert(memcmp(greeting, SOCKET_PING, sizeof(greeting)) == 0);
  590. qio_channel_write_all(ioc, response, sizeof(SOCKET_PONG), &error_abort);
  591. object_unref(OBJECT(ioc));
  592. }
  593. static gpointer
  594. char_socket_server_client_thread(gpointer data)
  595. {
  596. SocketAddress *addr = data;
  597. QIOChannelSocket *ioc = qio_channel_socket_new();
  598. qio_channel_socket_connect_sync(ioc, addr, &error_abort);
  599. char_socket_ping_pong(QIO_CHANNEL(ioc));
  600. return NULL;
  601. }
  602. typedef struct {
  603. SocketAddress *addr;
  604. bool wait_connected;
  605. bool fd_pass;
  606. } CharSocketServerTestConfig;
  607. static void char_socket_server_test(gconstpointer opaque)
  608. {
  609. const CharSocketServerTestConfig *config = opaque;
  610. Chardev *chr;
  611. CharBackend be = {0};
  612. CharSocketTestData data = {0};
  613. QObject *qaddr;
  614. SocketAddress *addr;
  615. Visitor *v;
  616. QemuThread thread;
  617. int ret;
  618. bool reconnected = false;
  619. char *optstr;
  620. QemuOpts *opts;
  621. g_setenv("QTEST_SILENT_ERRORS", "1", 1);
  622. /*
  623. * We rely on config->addr containing "nowait", otherwise
  624. * qemu_chr_new() will block until a client connects. We
  625. * can't spawn our client thread though, because until
  626. * qemu_chr_new() returns we don't know what TCP port was
  627. * allocated by the OS
  628. */
  629. optstr = char_socket_addr_to_opt_str(config->addr,
  630. config->fd_pass,
  631. NULL,
  632. true);
  633. opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"),
  634. optstr, true);
  635. g_assert_nonnull(opts);
  636. chr = qemu_chr_new_from_opts(opts, NULL, &error_abort);
  637. qemu_opts_del(opts);
  638. g_assert_nonnull(chr);
  639. g_assert(!object_property_get_bool(OBJECT(chr), "connected", &error_abort));
  640. qaddr = object_property_get_qobject(OBJECT(chr), "addr", &error_abort);
  641. g_assert_nonnull(qaddr);
  642. v = qobject_input_visitor_new(qaddr);
  643. visit_type_SocketAddress(v, "addr", &addr, &error_abort);
  644. visit_free(v);
  645. qobject_unref(qaddr);
  646. qemu_chr_fe_init(&be, chr, &error_abort);
  647. reconnect:
  648. data.event = -1;
  649. qemu_chr_fe_set_handlers(&be, NULL, NULL,
  650. char_socket_event, NULL,
  651. &data, NULL, true);
  652. g_assert(data.event == -1);
  653. /*
  654. * Kick off a thread to act as the "remote" client
  655. * which just plays ping-pong with us
  656. */
  657. qemu_thread_create(&thread, "client",
  658. char_socket_server_client_thread,
  659. addr, QEMU_THREAD_JOINABLE);
  660. g_assert(data.event == -1);
  661. if (config->wait_connected) {
  662. /* Synchronously accept a connection */
  663. qemu_chr_wait_connected(chr, &error_abort);
  664. } else {
  665. /*
  666. * Asynchronously accept a connection when the evnt
  667. * loop reports the listener socket as readable
  668. */
  669. while (data.event == -1) {
  670. main_loop_wait(false);
  671. }
  672. }
  673. g_assert(object_property_get_bool(OBJECT(chr), "connected", &error_abort));
  674. g_assert(data.event == CHR_EVENT_OPENED);
  675. data.event = -1;
  676. /* Send a greeting to the client */
  677. ret = qemu_chr_fe_write_all(&be, (const uint8_t *)SOCKET_PING,
  678. sizeof(SOCKET_PING));
  679. g_assert_cmpint(ret, ==, sizeof(SOCKET_PING));
  680. g_assert(data.event == -1);
  681. /* Setup a callback to receive the reply to our greeting */
  682. qemu_chr_fe_set_handlers(&be, char_socket_can_read,
  683. char_socket_read,
  684. char_socket_event, NULL,
  685. &data, NULL, true);
  686. g_assert(data.event == CHR_EVENT_OPENED);
  687. data.event = -1;
  688. /* Wait for the client to go away */
  689. while (data.event == -1) {
  690. main_loop_wait(false);
  691. }
  692. g_assert(!object_property_get_bool(OBJECT(chr), "connected", &error_abort));
  693. g_assert(data.event == CHR_EVENT_CLOSED);
  694. g_assert(data.got_pong);
  695. qemu_thread_join(&thread);
  696. if (!reconnected) {
  697. reconnected = true;
  698. goto reconnect;
  699. }
  700. qapi_free_SocketAddress(addr);
  701. object_unparent(OBJECT(chr));
  702. g_free(optstr);
  703. g_unsetenv("QTEST_SILENT_ERRORS");
  704. }
  705. static gpointer
  706. char_socket_client_server_thread(gpointer data)
  707. {
  708. QIOChannelSocket *ioc = data;
  709. QIOChannelSocket *cioc;
  710. cioc = qio_channel_socket_accept(ioc, &error_abort);
  711. g_assert_nonnull(cioc);
  712. char_socket_ping_pong(QIO_CHANNEL(cioc));
  713. return NULL;
  714. }
  715. typedef struct {
  716. SocketAddress *addr;
  717. const char *reconnect;
  718. bool wait_connected;
  719. bool fd_pass;
  720. } CharSocketClientTestConfig;
  721. static void char_socket_client_test(gconstpointer opaque)
  722. {
  723. const CharSocketClientTestConfig *config = opaque;
  724. QIOChannelSocket *ioc;
  725. char *optstr;
  726. Chardev *chr;
  727. CharBackend be = {0};
  728. CharSocketTestData data = {0};
  729. SocketAddress *addr;
  730. QemuThread thread;
  731. int ret;
  732. bool reconnected = false;
  733. QemuOpts *opts;
  734. /*
  735. * Setup a listener socket and determine get its address
  736. * so we know the TCP port for the client later
  737. */
  738. ioc = qio_channel_socket_new();
  739. g_assert_nonnull(ioc);
  740. qio_channel_socket_listen_sync(ioc, config->addr, 1, &error_abort);
  741. addr = qio_channel_socket_get_local_address(ioc, &error_abort);
  742. g_assert_nonnull(addr);
  743. /*
  744. * Kick off a thread to act as the "remote" client
  745. * which just plays ping-pong with us
  746. */
  747. qemu_thread_create(&thread, "client",
  748. char_socket_client_server_thread,
  749. ioc, QEMU_THREAD_JOINABLE);
  750. /*
  751. * Populate the chardev address based on what the server
  752. * is actually listening on
  753. */
  754. optstr = char_socket_addr_to_opt_str(addr,
  755. config->fd_pass,
  756. config->reconnect,
  757. false);
  758. opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"),
  759. optstr, true);
  760. g_assert_nonnull(opts);
  761. chr = qemu_chr_new_from_opts(opts, NULL, &error_abort);
  762. qemu_opts_del(opts);
  763. g_assert_nonnull(chr);
  764. if (config->reconnect) {
  765. /*
  766. * If reconnect is set, the connection will be
  767. * established in a background thread and we won't
  768. * see the "connected" status updated until we
  769. * run the main event loop, or call qemu_chr_wait_connected
  770. */
  771. g_assert(!object_property_get_bool(OBJECT(chr), "connected",
  772. &error_abort));
  773. } else {
  774. g_assert(object_property_get_bool(OBJECT(chr), "connected",
  775. &error_abort));
  776. }
  777. qemu_chr_fe_init(&be, chr, &error_abort);
  778. reconnect:
  779. data.event = -1;
  780. qemu_chr_fe_set_handlers(&be, NULL, NULL,
  781. char_socket_event, NULL,
  782. &data, NULL, true);
  783. if (config->reconnect) {
  784. g_assert(data.event == -1);
  785. } else {
  786. g_assert(data.event == CHR_EVENT_OPENED);
  787. }
  788. if (config->wait_connected) {
  789. /*
  790. * Synchronously wait for the connection to complete
  791. * This should be a no-op if reconnect is not set.
  792. */
  793. qemu_chr_wait_connected(chr, &error_abort);
  794. } else {
  795. /*
  796. * Asynchronously wait for the connection to be reported
  797. * as complete when the background thread reports its
  798. * status.
  799. * The loop will short-circuit if reconnect was set
  800. */
  801. while (data.event == -1) {
  802. main_loop_wait(false);
  803. }
  804. }
  805. g_assert(data.event == CHR_EVENT_OPENED);
  806. data.event = -1;
  807. g_assert(object_property_get_bool(OBJECT(chr), "connected", &error_abort));
  808. /* Send a greeting to the server */
  809. ret = qemu_chr_fe_write_all(&be, (const uint8_t *)SOCKET_PING,
  810. sizeof(SOCKET_PING));
  811. g_assert_cmpint(ret, ==, sizeof(SOCKET_PING));
  812. g_assert(data.event == -1);
  813. /* Setup a callback to receive the reply to our greeting */
  814. qemu_chr_fe_set_handlers(&be, char_socket_can_read,
  815. char_socket_read,
  816. char_socket_event, NULL,
  817. &data, NULL, true);
  818. g_assert(data.event == CHR_EVENT_OPENED);
  819. data.event = -1;
  820. /* Wait for the server to go away */
  821. while (data.event == -1) {
  822. main_loop_wait(false);
  823. }
  824. g_assert(data.event == CHR_EVENT_CLOSED);
  825. g_assert(!object_property_get_bool(OBJECT(chr), "connected", &error_abort));
  826. g_assert(data.got_pong);
  827. qemu_thread_join(&thread);
  828. if (config->reconnect && !reconnected) {
  829. reconnected = true;
  830. qemu_thread_create(&thread, "client",
  831. char_socket_client_server_thread,
  832. ioc, QEMU_THREAD_JOINABLE);
  833. goto reconnect;
  834. }
  835. object_unref(OBJECT(ioc));
  836. object_unparent(OBJECT(chr));
  837. qapi_free_SocketAddress(addr);
  838. g_free(optstr);
  839. }
  840. static void
  841. count_closed_event(void *opaque, int event)
  842. {
  843. int *count = opaque;
  844. if (event == CHR_EVENT_CLOSED) {
  845. (*count)++;
  846. }
  847. }
  848. static void
  849. char_socket_discard_read(void *opaque, const uint8_t *buf, int size)
  850. {
  851. }
  852. static void char_socket_server_two_clients_test(gconstpointer opaque)
  853. {
  854. SocketAddress *incoming_addr = (gpointer) opaque;
  855. Chardev *chr;
  856. CharBackend be = {0};
  857. QObject *qaddr;
  858. SocketAddress *addr;
  859. Visitor *v;
  860. char *optstr;
  861. QemuOpts *opts;
  862. QIOChannelSocket *ioc1, *ioc2;
  863. int closed = 0;
  864. g_setenv("QTEST_SILENT_ERRORS", "1", 1);
  865. /*
  866. * We rely on addr containing "nowait", otherwise
  867. * qemu_chr_new() will block until a client connects. We
  868. * can't spawn our client thread though, because until
  869. * qemu_chr_new() returns we don't know what TCP port was
  870. * allocated by the OS
  871. */
  872. optstr = char_socket_addr_to_opt_str(incoming_addr,
  873. false,
  874. NULL,
  875. true);
  876. opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"),
  877. optstr, true);
  878. g_assert_nonnull(opts);
  879. chr = qemu_chr_new_from_opts(opts, NULL, &error_abort);
  880. qemu_opts_del(opts);
  881. g_assert_nonnull(chr);
  882. g_assert(!object_property_get_bool(OBJECT(chr), "connected", &error_abort));
  883. qaddr = object_property_get_qobject(OBJECT(chr), "addr", &error_abort);
  884. g_assert_nonnull(qaddr);
  885. v = qobject_input_visitor_new(qaddr);
  886. visit_type_SocketAddress(v, "addr", &addr, &error_abort);
  887. visit_free(v);
  888. qobject_unref(qaddr);
  889. qemu_chr_fe_init(&be, chr, &error_abort);
  890. qemu_chr_fe_set_handlers(&be, char_socket_can_read, char_socket_discard_read,
  891. count_closed_event, NULL,
  892. &closed, NULL, true);
  893. ioc1 = qio_channel_socket_new();
  894. qio_channel_socket_connect_sync(ioc1, addr, &error_abort);
  895. qemu_chr_wait_connected(chr, &error_abort);
  896. /* switch the chardev to another context */
  897. GMainContext *ctx = g_main_context_new();
  898. qemu_chr_fe_set_handlers(&be, char_socket_can_read, char_socket_discard_read,
  899. count_closed_event, NULL,
  900. &closed, ctx, true);
  901. /* Start a second connection while the first is still connected.
  902. * It will be placed in the listen() backlog, and connect() will
  903. * succeed immediately.
  904. */
  905. ioc2 = qio_channel_socket_new();
  906. qio_channel_socket_connect_sync(ioc2, addr, &error_abort);
  907. object_unref(OBJECT(ioc1));
  908. /* The two connections should now be processed serially. */
  909. while (g_main_context_iteration(ctx, TRUE)) {
  910. if (closed == 1 && ioc2) {
  911. object_unref(OBJECT(ioc2));
  912. ioc2 = NULL;
  913. }
  914. if (closed == 2) {
  915. break;
  916. }
  917. }
  918. qapi_free_SocketAddress(addr);
  919. object_unparent(OBJECT(chr));
  920. g_main_context_unref(ctx);
  921. g_free(optstr);
  922. g_unsetenv("QTEST_SILENT_ERRORS");
  923. }
  924. #if defined(HAVE_CHARDEV_SERIAL) && !defined(WIN32)
  925. static void char_serial_test(void)
  926. {
  927. QemuOpts *opts;
  928. Chardev *chr;
  929. opts = qemu_opts_create(qemu_find_opts("chardev"), "serial-id",
  930. 1, &error_abort);
  931. qemu_opt_set(opts, "backend", "serial", &error_abort);
  932. qemu_opt_set(opts, "path", "/dev/null", &error_abort);
  933. chr = qemu_chr_new_from_opts(opts, NULL, NULL);
  934. g_assert_nonnull(chr);
  935. /* TODO: add more tests with a pty */
  936. object_unparent(OBJECT(chr));
  937. /* test tty alias */
  938. qemu_opt_set(opts, "backend", "tty", &error_abort);
  939. chr = qemu_chr_new_from_opts(opts, NULL, NULL);
  940. g_assert_nonnull(chr);
  941. object_unparent(OBJECT(chr));
  942. qemu_opts_del(opts);
  943. }
  944. #endif
  945. #ifndef _WIN32
  946. static void char_file_fifo_test(void)
  947. {
  948. Chardev *chr;
  949. CharBackend be;
  950. char *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL);
  951. char *fifo = g_build_filename(tmp_path, "fifo", NULL);
  952. char *out = g_build_filename(tmp_path, "out", NULL);
  953. ChardevFile file = { .in = fifo,
  954. .has_in = true,
  955. .out = out };
  956. ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE,
  957. .u.file.data = &file };
  958. FeHandler fe = { 0, };
  959. int fd, ret;
  960. if (mkfifo(fifo, 0600) < 0) {
  961. abort();
  962. }
  963. fd = open(fifo, O_RDWR);
  964. ret = write(fd, "fifo-in", 8);
  965. g_assert_cmpint(ret, ==, 8);
  966. chr = qemu_chardev_new("label-file", TYPE_CHARDEV_FILE, &backend,
  967. NULL, &error_abort);
  968. qemu_chr_fe_init(&be, chr, &error_abort);
  969. qemu_chr_fe_set_handlers(&be,
  970. fe_can_read,
  971. fe_read,
  972. fe_event,
  973. NULL,
  974. &fe, NULL, true);
  975. g_assert_cmpint(fe.last_event, !=, CHR_EVENT_BREAK);
  976. qmp_chardev_send_break("label-foo", NULL);
  977. g_assert_cmpint(fe.last_event, !=, CHR_EVENT_BREAK);
  978. qmp_chardev_send_break("label-file", NULL);
  979. g_assert_cmpint(fe.last_event, ==, CHR_EVENT_BREAK);
  980. main_loop();
  981. close(fd);
  982. g_assert_cmpint(fe.read_count, ==, 8);
  983. g_assert_cmpstr(fe.read_buf, ==, "fifo-in");
  984. qemu_chr_fe_deinit(&be, true);
  985. g_unlink(fifo);
  986. g_free(fifo);
  987. g_unlink(out);
  988. g_free(out);
  989. g_rmdir(tmp_path);
  990. g_free(tmp_path);
  991. }
  992. #endif
  993. static void char_file_test_internal(Chardev *ext_chr, const char *filepath)
  994. {
  995. char *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL);
  996. char *out;
  997. Chardev *chr;
  998. char *contents = NULL;
  999. ChardevFile file = {};
  1000. ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE,
  1001. .u.file.data = &file };
  1002. gsize length;
  1003. int ret;
  1004. if (ext_chr) {
  1005. chr = ext_chr;
  1006. out = g_strdup(filepath);
  1007. file.out = out;
  1008. } else {
  1009. out = g_build_filename(tmp_path, "out", NULL);
  1010. file.out = out;
  1011. chr = qemu_chardev_new(NULL, TYPE_CHARDEV_FILE, &backend,
  1012. NULL, &error_abort);
  1013. }
  1014. ret = qemu_chr_write_all(chr, (uint8_t *)"hello!", 6);
  1015. g_assert_cmpint(ret, ==, 6);
  1016. ret = g_file_get_contents(out, &contents, &length, NULL);
  1017. g_assert(ret == TRUE);
  1018. g_assert_cmpint(length, ==, 6);
  1019. g_assert(strncmp(contents, "hello!", 6) == 0);
  1020. if (!ext_chr) {
  1021. object_unref(OBJECT(chr));
  1022. g_unlink(out);
  1023. }
  1024. g_free(contents);
  1025. g_rmdir(tmp_path);
  1026. g_free(tmp_path);
  1027. g_free(out);
  1028. }
  1029. static void char_file_test(void)
  1030. {
  1031. char_file_test_internal(NULL, NULL);
  1032. }
  1033. static void char_null_test(void)
  1034. {
  1035. Error *err = NULL;
  1036. Chardev *chr;
  1037. CharBackend be;
  1038. int ret;
  1039. chr = qemu_chr_find("label-null");
  1040. g_assert_null(chr);
  1041. chr = qemu_chr_new("label-null", "null", NULL);
  1042. chr = qemu_chr_find("label-null");
  1043. g_assert_nonnull(chr);
  1044. g_assert(qemu_chr_has_feature(chr,
  1045. QEMU_CHAR_FEATURE_FD_PASS) == false);
  1046. g_assert(qemu_chr_has_feature(chr,
  1047. QEMU_CHAR_FEATURE_RECONNECTABLE) == false);
  1048. /* check max avail */
  1049. qemu_chr_fe_init(&be, chr, &error_abort);
  1050. qemu_chr_fe_init(&be, chr, &err);
  1051. error_free_or_abort(&err);
  1052. /* deinit & reinit */
  1053. qemu_chr_fe_deinit(&be, false);
  1054. qemu_chr_fe_init(&be, chr, &error_abort);
  1055. qemu_chr_fe_set_open(&be, true);
  1056. qemu_chr_fe_set_handlers(&be,
  1057. fe_can_read,
  1058. fe_read,
  1059. fe_event,
  1060. NULL,
  1061. NULL, NULL, true);
  1062. ret = qemu_chr_fe_write(&be, (void *)"buf", 4);
  1063. g_assert_cmpint(ret, ==, 4);
  1064. qemu_chr_fe_deinit(&be, true);
  1065. }
  1066. static void char_invalid_test(void)
  1067. {
  1068. Chardev *chr;
  1069. g_setenv("QTEST_SILENT_ERRORS", "1", 1);
  1070. chr = qemu_chr_new("label-invalid", "invalid", NULL);
  1071. g_assert_null(chr);
  1072. g_unsetenv("QTEST_SILENT_ERRORS");
  1073. }
  1074. static int chardev_change(void *opaque)
  1075. {
  1076. return 0;
  1077. }
  1078. static int chardev_change_denied(void *opaque)
  1079. {
  1080. return -1;
  1081. }
  1082. static void char_hotswap_test(void)
  1083. {
  1084. char *chr_args;
  1085. Chardev *chr;
  1086. CharBackend be;
  1087. gchar *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL);
  1088. char *filename = g_build_filename(tmp_path, "file", NULL);
  1089. ChardevFile file = { .out = filename };
  1090. ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE,
  1091. .u.file.data = &file };
  1092. ChardevReturn *ret;
  1093. int port;
  1094. int sock = make_udp_socket(&port);
  1095. g_assert_cmpint(sock, >, 0);
  1096. chr_args = g_strdup_printf("udp:127.0.0.1:%d", port);
  1097. chr = qemu_chr_new("chardev", chr_args, NULL);
  1098. qemu_chr_fe_init(&be, chr, &error_abort);
  1099. /* check that chardev operates correctly */
  1100. char_udp_test_internal(chr, sock);
  1101. /* set the handler that denies the hotswap */
  1102. qemu_chr_fe_set_handlers(&be, NULL, NULL,
  1103. NULL, chardev_change_denied, NULL, NULL, true);
  1104. /* now, change is denied and has to keep the old backend operating */
  1105. ret = qmp_chardev_change("chardev", &backend, NULL);
  1106. g_assert(!ret);
  1107. g_assert(be.chr == chr);
  1108. char_udp_test_internal(chr, sock);
  1109. /* now allow the change */
  1110. qemu_chr_fe_set_handlers(&be, NULL, NULL,
  1111. NULL, chardev_change, NULL, NULL, true);
  1112. /* has to succeed now */
  1113. ret = qmp_chardev_change("chardev", &backend, &error_abort);
  1114. g_assert(be.chr != chr);
  1115. close(sock);
  1116. chr = be.chr;
  1117. /* run the file chardev test */
  1118. char_file_test_internal(chr, filename);
  1119. object_unparent(OBJECT(chr));
  1120. qapi_free_ChardevReturn(ret);
  1121. g_unlink(filename);
  1122. g_free(filename);
  1123. g_rmdir(tmp_path);
  1124. g_free(tmp_path);
  1125. g_free(chr_args);
  1126. }
  1127. static SocketAddress tcpaddr = {
  1128. .type = SOCKET_ADDRESS_TYPE_INET,
  1129. .u.inet.host = (char *)"127.0.0.1",
  1130. .u.inet.port = (char *)"0",
  1131. };
  1132. #ifndef WIN32
  1133. static SocketAddress unixaddr = {
  1134. .type = SOCKET_ADDRESS_TYPE_UNIX,
  1135. .u.q_unix.path = (char *)"test-char.sock",
  1136. };
  1137. #endif
  1138. int main(int argc, char **argv)
  1139. {
  1140. bool has_ipv4, has_ipv6;
  1141. qemu_init_main_loop(&error_abort);
  1142. socket_init();
  1143. g_test_init(&argc, &argv, NULL);
  1144. if (socket_check_protocol_support(&has_ipv4, &has_ipv6) < 0) {
  1145. g_printerr("socket_check_protocol_support() failed\n");
  1146. goto end;
  1147. }
  1148. module_call_init(MODULE_INIT_QOM);
  1149. qemu_add_opts(&qemu_chardev_opts);
  1150. g_test_add_func("/char/null", char_null_test);
  1151. g_test_add_func("/char/invalid", char_invalid_test);
  1152. g_test_add_func("/char/ringbuf", char_ringbuf_test);
  1153. g_test_add_func("/char/mux", char_mux_test);
  1154. #ifdef _WIN32
  1155. g_test_add_func("/char/console/subprocess", char_console_test_subprocess);
  1156. g_test_add_func("/char/console", char_console_test);
  1157. #endif
  1158. g_test_add_func("/char/stdio/subprocess", char_stdio_test_subprocess);
  1159. g_test_add_func("/char/stdio", char_stdio_test);
  1160. #ifndef _WIN32
  1161. g_test_add_func("/char/pipe", char_pipe_test);
  1162. #endif
  1163. g_test_add_func("/char/file", char_file_test);
  1164. #ifndef _WIN32
  1165. g_test_add_func("/char/file-fifo", char_file_fifo_test);
  1166. #endif
  1167. #define SOCKET_SERVER_TEST(name, addr) \
  1168. static CharSocketServerTestConfig server1 ## name = \
  1169. { addr, false, false }; \
  1170. static CharSocketServerTestConfig server2 ## name = \
  1171. { addr, true, false }; \
  1172. static CharSocketServerTestConfig server3 ## name = \
  1173. { addr, false, true }; \
  1174. static CharSocketServerTestConfig server4 ## name = \
  1175. { addr, true, true }; \
  1176. g_test_add_data_func("/char/socket/server/mainloop/" # name, \
  1177. &server1 ##name, char_socket_server_test); \
  1178. g_test_add_data_func("/char/socket/server/wait-conn/" # name, \
  1179. &server2 ##name, char_socket_server_test); \
  1180. g_test_add_data_func("/char/socket/server/mainloop-fdpass/" # name, \
  1181. &server3 ##name, char_socket_server_test); \
  1182. g_test_add_data_func("/char/socket/server/wait-conn-fdpass/" # name, \
  1183. &server4 ##name, char_socket_server_test)
  1184. #define SOCKET_CLIENT_TEST(name, addr) \
  1185. static CharSocketClientTestConfig client1 ## name = \
  1186. { addr, NULL, false, false }; \
  1187. static CharSocketClientTestConfig client2 ## name = \
  1188. { addr, NULL, true, false }; \
  1189. static CharSocketClientTestConfig client3 ## name = \
  1190. { addr, ",reconnect=1", false }; \
  1191. static CharSocketClientTestConfig client4 ## name = \
  1192. { addr, ",reconnect=1", true }; \
  1193. static CharSocketClientTestConfig client5 ## name = \
  1194. { addr, NULL, false, true }; \
  1195. static CharSocketClientTestConfig client6 ## name = \
  1196. { addr, NULL, true, true }; \
  1197. g_test_add_data_func("/char/socket/client/mainloop/" # name, \
  1198. &client1 ##name, char_socket_client_test); \
  1199. g_test_add_data_func("/char/socket/client/wait-conn/" # name, \
  1200. &client2 ##name, char_socket_client_test); \
  1201. g_test_add_data_func("/char/socket/client/mainloop-reconnect/" # name, \
  1202. &client3 ##name, char_socket_client_test); \
  1203. g_test_add_data_func("/char/socket/client/wait-conn-reconnect/" # name, \
  1204. &client4 ##name, char_socket_client_test); \
  1205. g_test_add_data_func("/char/socket/client/mainloop-fdpass/" # name, \
  1206. &client5 ##name, char_socket_client_test); \
  1207. g_test_add_data_func("/char/socket/client/wait-conn-fdpass/" # name, \
  1208. &client6 ##name, char_socket_client_test)
  1209. if (has_ipv4) {
  1210. SOCKET_SERVER_TEST(tcp, &tcpaddr);
  1211. SOCKET_CLIENT_TEST(tcp, &tcpaddr);
  1212. g_test_add_data_func("/char/socket/server/two-clients/tcp", &tcpaddr,
  1213. char_socket_server_two_clients_test);
  1214. }
  1215. #ifndef WIN32
  1216. SOCKET_SERVER_TEST(unix, &unixaddr);
  1217. SOCKET_CLIENT_TEST(unix, &unixaddr);
  1218. g_test_add_data_func("/char/socket/server/two-clients/unix", &unixaddr,
  1219. char_socket_server_two_clients_test);
  1220. #endif
  1221. g_test_add_func("/char/udp", char_udp_test);
  1222. #if defined(HAVE_CHARDEV_SERIAL) && !defined(WIN32)
  1223. g_test_add_func("/char/serial", char_serial_test);
  1224. #endif
  1225. g_test_add_func("/char/hotswap", char_hotswap_test);
  1226. g_test_add_func("/char/websocket", char_websock_test);
  1227. end:
  1228. return g_test_run();
  1229. }