219 |
219 |
return len;
|
220 |
220 |
}
|
221 |
221 |
|
222 |
|
static CharDriverState *qemu_chr_open_null(QemuOpts *opts)
|
|
222 |
static int qemu_chr_open_null(QemuOpts *opts, CharDriverState **_chr)
|
223 |
223 |
{
|
224 |
224 |
CharDriverState *chr;
|
225 |
225 |
|
226 |
226 |
chr = qemu_mallocz(sizeof(CharDriverState));
|
227 |
227 |
chr->chr_write = null_chr_write;
|
228 |
|
return chr;
|
|
228 |
|
|
229 |
*_chr= chr;
|
|
230 |
return 0;
|
229 |
231 |
}
|
230 |
232 |
|
231 |
233 |
/* MUX driver for serial I/O splitting */
|
... | ... | |
634 |
636 |
return chr;
|
635 |
637 |
}
|
636 |
638 |
|
637 |
|
static CharDriverState *qemu_chr_open_file_out(QemuOpts *opts)
|
|
639 |
static int qemu_chr_open_file_out(QemuOpts *opts, CharDriverState **_chr)
|
638 |
640 |
{
|
639 |
641 |
int fd_out;
|
640 |
642 |
|
641 |
643 |
TFR(fd_out = qemu_open(qemu_opt_get(opts, "path"),
|
642 |
644 |
O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666));
|
643 |
|
if (fd_out < 0)
|
644 |
|
return NULL;
|
645 |
|
return qemu_chr_open_fd(-1, fd_out);
|
|
645 |
if (fd_out < 0) {
|
|
646 |
return -errno;
|
|
647 |
}
|
|
648 |
|
|
649 |
*_chr = qemu_chr_open_fd(-1, fd_out);
|
|
650 |
return 0;
|
646 |
651 |
}
|
647 |
652 |
|
648 |
|
static CharDriverState *qemu_chr_open_pipe(QemuOpts *opts)
|
|
653 |
static int qemu_chr_open_pipe(QemuOpts *opts, CharDriverState **_chr)
|
649 |
654 |
{
|
650 |
655 |
int fd_in, fd_out;
|
651 |
656 |
char filename_in[256], filename_out[256];
|
... | ... | |
653 |
658 |
|
654 |
659 |
if (filename == NULL) {
|
655 |
660 |
fprintf(stderr, "chardev: pipe: no filename given\n");
|
656 |
|
return NULL;
|
|
661 |
return -EINVAL;
|
657 |
662 |
}
|
658 |
663 |
|
659 |
664 |
snprintf(filename_in, 256, "%s.in", filename);
|
... | ... | |
665 |
670 |
close(fd_in);
|
666 |
671 |
if (fd_out >= 0)
|
667 |
672 |
close(fd_out);
|
668 |
|
TFR(fd_in = fd_out = open(filename, O_RDWR | O_BINARY));
|
669 |
|
if (fd_in < 0)
|
670 |
|
return NULL;
|
|
673 |
TFR(fd_in = fd_out = qemu_open(filename, O_RDWR | O_BINARY));
|
|
674 |
if (fd_in < 0) {
|
|
675 |
return -errno;
|
|
676 |
}
|
671 |
677 |
}
|
672 |
|
return qemu_chr_open_fd(fd_in, fd_out);
|
|
678 |
|
|
679 |
*_chr = qemu_chr_open_fd(fd_in, fd_out);
|
|
680 |
return 0;
|
673 |
681 |
}
|
674 |
682 |
|
675 |
683 |
|
... | ... | |
760 |
768 |
fd_chr_close(chr);
|
761 |
769 |
}
|
762 |
770 |
|
763 |
|
static CharDriverState *qemu_chr_open_stdio(QemuOpts *opts)
|
|
771 |
static int qemu_chr_open_stdio(QemuOpts *opts, CharDriverState **_chr)
|
764 |
772 |
{
|
765 |
773 |
CharDriverState *chr;
|
766 |
774 |
|
767 |
|
if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
|
768 |
|
return NULL;
|
|
775 |
if (stdio_nb_clients >= STDIO_MAX_CLIENTS) {
|
|
776 |
return -EBUSY;
|
|
777 |
}
|
|
778 |
|
769 |
779 |
if (stdio_nb_clients == 0) {
|
770 |
780 |
old_fd0_flags = fcntl(0, F_GETFL);
|
771 |
781 |
tcgetattr (0, &oldtty);
|
... | ... | |
782 |
792 |
display_type != DT_NOGRAPHIC);
|
783 |
793 |
qemu_chr_set_echo(chr, false);
|
784 |
794 |
|
785 |
|
return chr;
|
|
795 |
*_chr = chr;
|
|
796 |
return 0;
|
786 |
797 |
}
|
787 |
798 |
|
788 |
799 |
#ifdef __sun__
|
... | ... | |
969 |
980 |
qemu_chr_event(chr, CHR_EVENT_CLOSED);
|
970 |
981 |
}
|
971 |
982 |
|
972 |
|
static CharDriverState *qemu_chr_open_pty(QemuOpts *opts)
|
|
983 |
static int qemu_chr_open_pty(QemuOpts *opts, CharDriverState **_chr)
|
973 |
984 |
{
|
974 |
985 |
CharDriverState *chr;
|
975 |
986 |
PtyCharDriver *s;
|
... | ... | |
987 |
998 |
s = qemu_mallocz(sizeof(PtyCharDriver));
|
988 |
999 |
|
989 |
1000 |
if (openpty(&s->fd, &slave_fd, pty_name, NULL, NULL) < 0) {
|
990 |
|
return NULL;
|
|
1001 |
return -errno;
|
991 |
1002 |
}
|
992 |
1003 |
|
993 |
1004 |
/* Set raw attributes on the pty. */
|
... | ... | |
1009 |
1020 |
|
1010 |
1021 |
s->timer = qemu_new_timer_ms(rt_clock, pty_chr_timer, chr);
|
1011 |
1022 |
|
1012 |
|
return chr;
|
|
1023 |
*_chr = chr;
|
|
1024 |
return 0;
|
1013 |
1025 |
}
|
1014 |
1026 |
|
1015 |
1027 |
static void tty_serial_init(int fd, int speed,
|
... | ... | |
1210 |
1222 |
}
|
1211 |
1223 |
}
|
1212 |
1224 |
|
1213 |
|
static CharDriverState *qemu_chr_open_tty(QemuOpts *opts)
|
|
1225 |
static int qemu_chr_open_tty(QemuOpts *opts, CharDriverState **_chr)
|
1214 |
1226 |
{
|
1215 |
1227 |
const char *filename = qemu_opt_get(opts, "path");
|
1216 |
1228 |
CharDriverState *chr;
|
1217 |
1229 |
int fd;
|
1218 |
1230 |
|
1219 |
|
TFR(fd = open(filename, O_RDWR | O_NONBLOCK));
|
|
1231 |
TFR(fd = qemu_open(filename, O_RDWR | O_NONBLOCK));
|
1220 |
1232 |
if (fd < 0) {
|
1221 |
|
return NULL;
|
|
1233 |
return -errno;
|
1222 |
1234 |
}
|
1223 |
1235 |
tty_serial_init(fd, 115200, 'N', 8, 1);
|
1224 |
1236 |
chr = qemu_chr_open_fd(fd, fd);
|
1225 |
|
if (!chr) {
|
1226 |
|
close(fd);
|
1227 |
|
return NULL;
|
1228 |
|
}
|
1229 |
1237 |
chr->chr_ioctl = tty_serial_ioctl;
|
1230 |
1238 |
chr->chr_close = qemu_chr_close_tty;
|
1231 |
|
return chr;
|
|
1239 |
|
|
1240 |
*_chr = chr;
|
|
1241 |
return 0;
|
1232 |
1242 |
}
|
1233 |
1243 |
#else /* ! __linux__ && ! __sun__ */
|
1234 |
|
static CharDriverState *qemu_chr_open_pty(QemuOpts *opts)
|
|
1244 |
static int qemu_chr_open_pty(QemuOpts *opts, CharDriverState **_chr)
|
1235 |
1245 |
{
|
1236 |
|
return NULL;
|
|
1246 |
return -ENOTSUP;
|
1237 |
1247 |
}
|
1238 |
1248 |
#endif /* __linux__ || __sun__ */
|
1239 |
1249 |
|
... | ... | |
1347 |
1357 |
qemu_chr_event(chr, CHR_EVENT_CLOSED);
|
1348 |
1358 |
}
|
1349 |
1359 |
|
1350 |
|
static CharDriverState *qemu_chr_open_pp(QemuOpts *opts)
|
|
1360 |
static int qemu_chr_open_pp(QemuOpts *opts, CharDriverState **_chr)
|
1351 |
1361 |
{
|
1352 |
1362 |
const char *filename = qemu_opt_get(opts, "path");
|
1353 |
1363 |
CharDriverState *chr;
|
... | ... | |
1355 |
1365 |
int fd;
|
1356 |
1366 |
|
1357 |
1367 |
TFR(fd = open(filename, O_RDWR));
|
1358 |
|
if (fd < 0)
|
1359 |
|
return NULL;
|
|
1368 |
if (fd < 0) {
|
|
1369 |
return -errno;
|
|
1370 |
}
|
1360 |
1371 |
|
1361 |
1372 |
if (ioctl(fd, PPCLAIM) < 0) {
|
1362 |
1373 |
close(fd);
|
1363 |
|
return NULL;
|
|
1374 |
return -errno;
|
1364 |
1375 |
}
|
1365 |
1376 |
|
1366 |
1377 |
drv = qemu_mallocz(sizeof(ParallelCharDriver));
|
... | ... | |
1375 |
1386 |
|
1376 |
1387 |
qemu_chr_generic_open(chr);
|
1377 |
1388 |
|
1378 |
|
return chr;
|
|
1389 |
*_chr = chr;
|
|
1390 |
return 0;
|
1379 |
1391 |
}
|
1380 |
1392 |
#endif /* __linux__ */
|
1381 |
1393 |
|
... | ... | |
1417 |
1429 |
return 0;
|
1418 |
1430 |
}
|
1419 |
1431 |
|
1420 |
|
static CharDriverState *qemu_chr_open_pp(QemuOpts *opts)
|
|
1432 |
static int qemu_chr_open_pp(QemuOpts *opts, CharDriverState **_chr)
|
1421 |
1433 |
{
|
1422 |
1434 |
const char *filename = qemu_opt_get(opts, "path");
|
1423 |
1435 |
CharDriverState *chr;
|
1424 |
1436 |
int fd;
|
1425 |
1437 |
|
1426 |
|
fd = open(filename, O_RDWR);
|
1427 |
|
if (fd < 0)
|
1428 |
|
return NULL;
|
|
1438 |
fd = qemu_open(filename, O_RDWR);
|
|
1439 |
if (fd < 0) {
|
|
1440 |
return -errno;
|
|
1441 |
}
|
1429 |
1442 |
|
1430 |
1443 |
chr = qemu_mallocz(sizeof(CharDriverState));
|
1431 |
1444 |
chr->opaque = (void *)(intptr_t)fd;
|
1432 |
1445 |
chr->chr_write = null_chr_write;
|
1433 |
1446 |
chr->chr_ioctl = pp_ioctl;
|
1434 |
|
return chr;
|
|
1447 |
|
|
1448 |
*_chr = chr;
|
|
1449 |
return 0;
|
1435 |
1450 |
}
|
1436 |
1451 |
#endif
|
1437 |
1452 |
|
... | ... | |
1637 |
1652 |
return 0;
|
1638 |
1653 |
}
|
1639 |
1654 |
|
1640 |
|
static CharDriverState *qemu_chr_open_win(QemuOpts *opts)
|
|
1655 |
static int qemu_chr_open_win(QemuOpts *opts, CharDriverState **_chr)
|
1641 |
1656 |
{
|
1642 |
1657 |
const char *filename = qemu_opt_get(opts, "path");
|
1643 |
1658 |
CharDriverState *chr;
|
... | ... | |
1652 |
1667 |
if (win_chr_init(chr, filename) < 0) {
|
1653 |
1668 |
free(s);
|
1654 |
1669 |
free(chr);
|
1655 |
|
return NULL;
|
|
1670 |
return -EIO;
|
1656 |
1671 |
}
|
1657 |
1672 |
qemu_chr_generic_open(chr);
|
1658 |
|
return chr;
|
|
1673 |
|
|
1674 |
*_chr = chr;
|
|
1675 |
return 0;
|
1659 |
1676 |
}
|
1660 |
1677 |
|
1661 |
1678 |
static int win_chr_pipe_poll(void *opaque)
|
... | ... | |
1737 |
1754 |
}
|
1738 |
1755 |
|
1739 |
1756 |
|
1740 |
|
static CharDriverState *qemu_chr_open_win_pipe(QemuOpts *opts)
|
|
1757 |
static int qemu_chr_open_win_pipe(QemuOpts *opts, CharDriverState **_chr)
|
1741 |
1758 |
{
|
1742 |
1759 |
const char *filename = qemu_opt_get(opts, "path");
|
1743 |
1760 |
CharDriverState *chr;
|
... | ... | |
1752 |
1769 |
if (win_chr_pipe_init(chr, filename) < 0) {
|
1753 |
1770 |
free(s);
|
1754 |
1771 |
free(chr);
|
1755 |
|
return NULL;
|
|
1772 |
return -EIO;
|
1756 |
1773 |
}
|
1757 |
1774 |
qemu_chr_generic_open(chr);
|
1758 |
|
return chr;
|
|
1775 |
|
|
1776 |
*_chr = chr;
|
|
1777 |
return 0;
|
1759 |
1778 |
}
|
1760 |
1779 |
|
1761 |
1780 |
static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
|
... | ... | |
1772 |
1791 |
return chr;
|
1773 |
1792 |
}
|
1774 |
1793 |
|
1775 |
|
static CharDriverState *qemu_chr_open_win_con(QemuOpts *opts)
|
|
1794 |
static int qemu_chr_open_win_con(QemuOpts *opts, CharDriverState **_chr)
|
1776 |
1795 |
{
|
1777 |
|
return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE));
|
|
1796 |
return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE), chr);
|
1778 |
1797 |
}
|
1779 |
1798 |
|
1780 |
|
static CharDriverState *qemu_chr_open_win_file_out(QemuOpts *opts)
|
|
1799 |
static int qemu_chr_open_win_file_out(QemuOpts *opts, CharDriverState **_chr)
|
1781 |
1800 |
{
|
1782 |
1801 |
const char *file_out = qemu_opt_get(opts, "path");
|
1783 |
1802 |
HANDLE fd_out;
|
1784 |
1803 |
|
1785 |
1804 |
fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
|
1786 |
1805 |
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
1787 |
|
if (fd_out == INVALID_HANDLE_VALUE)
|
1788 |
|
return NULL;
|
|
1806 |
if (fd_out == INVALID_HANDLE_VALUE) {
|
|
1807 |
return -EIO;
|
|
1808 |
}
|
1789 |
1809 |
|
1790 |
|
return qemu_chr_open_win_file(fd_out);
|
|
1810 |
return qemu_chr_open_win_file(fd_out, _chr);
|
1791 |
1811 |
}
|
1792 |
1812 |
#endif /* !_WIN32 */
|
1793 |
1813 |
|
... | ... | |
1868 |
1888 |
qemu_chr_event(chr, CHR_EVENT_CLOSED);
|
1869 |
1889 |
}
|
1870 |
1890 |
|
1871 |
|
static CharDriverState *qemu_chr_open_udp(QemuOpts *opts)
|
|
1891 |
static int qemu_chr_open_udp(QemuOpts *opts, CharDriverState **_chr)
|
1872 |
1892 |
{
|
1873 |
1893 |
CharDriverState *chr = NULL;
|
1874 |
1894 |
NetCharDriver *s = NULL;
|
1875 |
1895 |
int fd = -1;
|
|
1896 |
int ret;
|
1876 |
1897 |
|
1877 |
1898 |
chr = qemu_mallocz(sizeof(CharDriverState));
|
1878 |
1899 |
s = qemu_mallocz(sizeof(NetCharDriver));
|
... | ... | |
1880 |
1901 |
fd = inet_dgram_opts(opts);
|
1881 |
1902 |
if (fd < 0) {
|
1882 |
1903 |
fprintf(stderr, "inet_dgram_opts failed\n");
|
|
1904 |
ret = -errno;
|
1883 |
1905 |
goto return_err;
|
1884 |
1906 |
}
|
1885 |
1907 |
|
... | ... | |
1890 |
1912 |
chr->chr_write = udp_chr_write;
|
1891 |
1913 |
chr->chr_update_read_handler = udp_chr_update_read_handler;
|
1892 |
1914 |
chr->chr_close = udp_chr_close;
|
1893 |
|
return chr;
|
|
1915 |
|
|
1916 |
*_chr = chr;
|
|
1917 |
return 0;
|
1894 |
1918 |
|
1895 |
1919 |
return_err:
|
1896 |
|
if (chr)
|
1897 |
|
free(chr);
|
1898 |
|
if (s)
|
1899 |
|
free(s);
|
1900 |
|
if (fd >= 0)
|
|
1920 |
qemu_free(chr);
|
|
1921 |
qemu_free(s);
|
|
1922 |
if (fd >= 0) {
|
1901 |
1923 |
closesocket(fd);
|
1902 |
|
return NULL;
|
|
1924 |
}
|
|
1925 |
return ret;
|
1903 |
1926 |
}
|
1904 |
1927 |
|
1905 |
1928 |
/***********************************************************/
|
... | ... | |
2178 |
2201 |
qemu_chr_event(chr, CHR_EVENT_CLOSED);
|
2179 |
2202 |
}
|
2180 |
2203 |
|
2181 |
|
static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
|
|
2204 |
static int qemu_chr_open_socket(QemuOpts *opts, CharDriverState **_chr)
|
2182 |
2205 |
{
|
2183 |
2206 |
CharDriverState *chr = NULL;
|
2184 |
2207 |
TCPCharDriver *s = NULL;
|
... | ... | |
2188 |
2211 |
int do_nodelay;
|
2189 |
2212 |
int is_unix;
|
2190 |
2213 |
int is_telnet;
|
|
2214 |
int ret;
|
2191 |
2215 |
|
2192 |
2216 |
is_listen = qemu_opt_get_bool(opts, "server", 0);
|
2193 |
2217 |
is_waitconnect = qemu_opt_get_bool(opts, "wait", 1);
|
... | ... | |
2213 |
2237 |
fd = inet_connect_opts(opts);
|
2214 |
2238 |
}
|
2215 |
2239 |
}
|
2216 |
|
if (fd < 0)
|
|
2240 |
if (fd < 0) {
|
|
2241 |
ret = -errno;
|
2217 |
2242 |
goto fail;
|
|
2243 |
}
|
2218 |
2244 |
|
2219 |
2245 |
if (!is_waitconnect)
|
2220 |
2246 |
socket_set_nonblock(fd);
|
... | ... | |
2266 |
2292 |
tcp_chr_accept(chr);
|
2267 |
2293 |
socket_set_nonblock(s->listen_fd);
|
2268 |
2294 |
}
|
2269 |
|
return chr;
|
|
2295 |
|
|
2296 |
*_chr = chr;
|
|
2297 |
return 0;
|
2270 |
2298 |
|
2271 |
2299 |
fail:
|
2272 |
2300 |
if (fd >= 0)
|
2273 |
2301 |
closesocket(fd);
|
2274 |
2302 |
qemu_free(s);
|
2275 |
2303 |
qemu_free(chr);
|
2276 |
|
return NULL;
|
|
2304 |
return ret;
|
2277 |
2305 |
}
|
2278 |
2306 |
|
2279 |
2307 |
/***********************************************************/
|
... | ... | |
2466 |
2494 |
|
2467 |
2495 |
static const struct {
|
2468 |
2496 |
const char *name;
|
2469 |
|
CharDriverState *(*open)(QemuOpts *opts);
|
|
2497 |
int (*open)(QemuOpts *opts, CharDriverState **chr);
|
2470 |
2498 |
} backend_table[] = {
|
2471 |
2499 |
{ .name = "null", .open = qemu_chr_open_null },
|
2472 |
2500 |
{ .name = "socket", .open = qemu_chr_open_socket },
|
... | ... | |
2506 |
2534 |
{
|
2507 |
2535 |
CharDriverState *chr;
|
2508 |
2536 |
int i;
|
|
2537 |
int ret;
|
2509 |
2538 |
|
2510 |
2539 |
if (qemu_opts_id(opts) == NULL) {
|
2511 |
2540 |
fprintf(stderr, "chardev: no id specified\n");
|
... | ... | |
2527 |
2556 |
return NULL;
|
2528 |
2557 |
}
|
2529 |
2558 |
|
2530 |
|
chr = backend_table[i].open(opts);
|
2531 |
|
if (!chr) {
|
2532 |
|
fprintf(stderr, "chardev: opening backend \"%s\" failed\n",
|
2533 |
|
qemu_opt_get(opts, "backend"));
|
|
2559 |
ret = backend_table[i].open(opts, &chr);
|
|
2560 |
if (ret < 0) {
|
|
2561 |
fprintf(stderr, "chardev: opening backend \"%s\" failed: %s\n",
|
|
2562 |
qemu_opt_get(opts, "backend"), strerror(-ret));
|
2534 |
2563 |
return NULL;
|
2535 |
2564 |
}
|
2536 |
2565 |
|