Mercurial > vim
comparison src/channel.c @ 8059:19304db153bc v7.4.1324
commit https://github.com/vim/vim/commit/d807036d10615b960c814ef3890ecad335b57f56
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Feb 15 21:56:54 2016 +0100
patch 7.4.1324
Problem: Channels with pipes don't work on MS-Windows.
Solution: Add pipe I/O support. (Yasuhiro Matsumoto)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Mon, 15 Feb 2016 22:00:04 +0100 |
parents | 6db4b1c863ec |
children | 7fe3b9dc132b |
comparison
equal
deleted
inserted
replaced
8058:a78f2d2ed4b9 | 8059:19304db153bc |
---|---|
30 # define EWOULDBLOCK WSAEWOULDBLOCK | 30 # define EWOULDBLOCK WSAEWOULDBLOCK |
31 # ifdef EINTR | 31 # ifdef EINTR |
32 # undef EINTR | 32 # undef EINTR |
33 # endif | 33 # endif |
34 # define EINTR WSAEINTR | 34 # define EINTR WSAEINTR |
35 # define sock_write(sd, buf, len) send(sd, buf, len, 0) | 35 # define sock_write(sd, buf, len) send((SOCKET)sd, buf, len, 0) |
36 # define sock_read(sd, buf, len) recv(sd, buf, len, 0) | 36 # define sock_read(sd, buf, len) recv((SOCKET)sd, buf, len, 0) |
37 # define sock_close(sd) closesocket(sd) | 37 # define sock_close(sd) closesocket((SOCKET)sd) |
38 # define sleep(t) Sleep(t*1000) /* WinAPI Sleep() accepts milliseconds */ | |
39 #else | 38 #else |
40 # include <netdb.h> | 39 # include <netdb.h> |
41 # include <netinet/in.h> | 40 # include <netinet/in.h> |
42 | 41 |
43 # include <sys/socket.h> | 42 # include <sys/socket.h> |
46 # endif | 45 # endif |
47 # define SOCK_ERRNO | 46 # define SOCK_ERRNO |
48 # define sock_write(sd, buf, len) write(sd, buf, len) | 47 # define sock_write(sd, buf, len) write(sd, buf, len) |
49 # define sock_read(sd, buf, len) read(sd, buf, len) | 48 # define sock_read(sd, buf, len) read(sd, buf, len) |
50 # define sock_close(sd) close(sd) | 49 # define sock_close(sd) close(sd) |
50 # define fd_read(fd, buf, len, timeout) read(fd, buf, len) | |
51 # define fd_write(sd, buf, len) write(sd, buf, len) | |
52 # define fd_close(sd) close(sd) | |
51 #endif | 53 #endif |
52 | 54 |
53 #ifdef FEAT_GUI_W32 | 55 #ifdef FEAT_GUI_W32 |
54 extern HWND s_hwnd; /* Gvim's Window handle */ | 56 extern HWND s_hwnd; /* Gvim's Window handle */ |
55 #endif | 57 #endif |
56 | 58 |
59 #ifdef WIN32 | |
60 static int | |
61 fd_read(sock_T fd, char_u *buf, size_t len, int timeout) | |
62 { | |
63 HANDLE h = (HANDLE)fd; | |
64 DWORD nread; | |
65 | |
66 if (!ReadFile(h, buf, (DWORD)len, &nread, NULL)) | |
67 return -1; | |
68 return (int)nread; | |
69 } | |
70 | |
71 static int | |
72 fd_write(sock_T fd, char_u *buf, size_t len) | |
73 { | |
74 HANDLE h = (HANDLE)fd; | |
75 DWORD nwrite; | |
76 | |
77 if (!WriteFile(h, buf, (DWORD)len, &nwrite, NULL)) | |
78 return -1; | |
79 return (int)nwrite; | |
80 } | |
81 | |
82 static void | |
83 fd_close(sock_T fd) | |
84 { | |
85 HANDLE h = (HANDLE)fd; | |
86 | |
87 CloseHandle(h); | |
88 } | |
89 #endif | |
57 | 90 |
58 /* Log file opened with ch_logfile(). */ | 91 /* Log file opened with ch_logfile(). */ |
59 static FILE *log_fd = NULL; | 92 static FILE *log_fd = NULL; |
60 | 93 |
61 void | 94 void |
226 for (which = CHAN_SOCK; which <= CHAN_IN; ++which) | 259 for (which = CHAN_SOCK; which <= CHAN_IN; ++which) |
227 #else | 260 #else |
228 which = CHAN_SOCK; | 261 which = CHAN_SOCK; |
229 #endif | 262 #endif |
230 { | 263 { |
231 channel->ch_pfd[which].ch_fd = (sock_T)-1; | 264 channel->ch_pfd[which].ch_fd = CHAN_FD_INVALID; |
232 #ifdef FEAT_GUI_X11 | 265 #ifdef FEAT_GUI_X11 |
233 channel->ch_pfd[which].ch_inputHandler = (XtInputId)NULL; | 266 channel->ch_pfd[which].ch_inputHandler = (XtInputId)NULL; |
234 #endif | 267 #endif |
235 #ifdef FEAT_GUI_GTK | 268 #ifdef FEAT_GUI_GTK |
236 channel->ch_pfd[which].ch_inputHandler = 0; | 269 channel->ch_pfd[which].ch_inputHandler = 0; |
361 channel_gui_register(channel_T *channel) | 394 channel_gui_register(channel_T *channel) |
362 { | 395 { |
363 if (!CH_HAS_GUI) | 396 if (!CH_HAS_GUI) |
364 return; | 397 return; |
365 | 398 |
366 if (channel->CH_SOCK >= 0) | 399 if (channel->CH_SOCK != CHAN_FD_INVALID) |
367 channel_gui_register_one(channel, CHAN_SOCK); | 400 channel_gui_register_one(channel, CHAN_SOCK); |
368 # ifdef CHANNEL_PIPES | 401 # ifdef CHANNEL_PIPES |
369 if (channel->CH_OUT >= 0) | 402 if (channel->CH_OUT != CHAN_FD_INVALID) |
370 channel_gui_register_one(channel, CHAN_OUT); | 403 channel_gui_register_one(channel, CHAN_OUT); |
371 if (channel->CH_ERR >= 0) | 404 if (channel->CH_ERR != CHAN_FD_INVALID) |
372 channel_gui_register_one(channel, CHAN_ERR); | 405 channel_gui_register_one(channel, CHAN_ERR); |
373 # endif | 406 # endif |
374 } | 407 } |
375 | 408 |
376 /* | 409 /* |
455 ch_error(NULL, "Cannot allocate channel.\n"); | 488 ch_error(NULL, "Cannot allocate channel.\n"); |
456 EMSG(_("E897: All channels are in use")); | 489 EMSG(_("E897: All channels are in use")); |
457 return NULL; | 490 return NULL; |
458 } | 491 } |
459 | 492 |
460 if ((sd = (sock_T)socket(AF_INET, SOCK_STREAM, 0)) == (sock_T)-1) | 493 if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) |
461 { | 494 { |
462 ch_error(NULL, "in socket() in channel_open().\n"); | 495 ch_error(NULL, "in socket() in channel_open().\n"); |
463 PERROR("E898: socket() in channel_open()"); | 496 PERROR("E898: socket() in channel_open()"); |
464 channel_free(channel); | 497 channel_free(channel); |
465 return NULL; | 498 return NULL; |
562 | 595 |
563 /* Only retry for netbeans. TODO: can we use a waittime instead? */ | 596 /* Only retry for netbeans. TODO: can we use a waittime instead? */ |
564 if (errno == ECONNREFUSED && close_cb != NULL) | 597 if (errno == ECONNREFUSED && close_cb != NULL) |
565 { | 598 { |
566 sock_close(sd); | 599 sock_close(sd); |
567 if ((sd = (sock_T)socket(AF_INET, SOCK_STREAM, 0)) == (sock_T)-1) | 600 if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) |
568 { | 601 { |
569 SOCK_ERRNO; | 602 SOCK_ERRNO; |
570 ch_log(NULL, "socket() retry in channel_open()\n"); | 603 ch_log(NULL, "socket() retry in channel_open()\n"); |
571 PERROR("E900: socket() retry in channel_open()"); | 604 PERROR("E900: socket() retry in channel_open()"); |
572 channel_free(channel); | 605 channel_free(channel); |
607 return NULL; | 640 return NULL; |
608 } | 641 } |
609 } | 642 } |
610 } | 643 } |
611 | 644 |
612 channel->CH_SOCK = sd; | 645 channel->CH_SOCK = (sock_T)sd; |
613 channel->ch_close_cb = close_cb; | 646 channel->ch_close_cb = close_cb; |
614 | 647 |
615 #ifdef FEAT_GUI | 648 #ifdef FEAT_GUI |
616 channel_gui_register(channel); | 649 channel_gui_register(channel); |
617 #endif | 650 #endif |
619 return channel; | 652 return channel; |
620 } | 653 } |
621 | 654 |
622 #if defined(CHANNEL_PIPES) || defined(PROTO) | 655 #if defined(CHANNEL_PIPES) || defined(PROTO) |
623 void | 656 void |
624 channel_set_pipes(channel_T *channel, int in, int out, int err) | 657 channel_set_pipes(channel_T *channel, sock_T in, sock_T out, sock_T err) |
625 { | 658 { |
626 channel->CH_IN = in; | 659 channel->CH_IN = in; |
627 channel->CH_OUT = out; | 660 channel->CH_OUT = out; |
628 channel->CH_ERR = err; | 661 channel->CH_ERR = err; |
629 } | 662 } |
1142 * Also returns FALSE or invalid "channel". | 1175 * Also returns FALSE or invalid "channel". |
1143 */ | 1176 */ |
1144 int | 1177 int |
1145 channel_can_write_to(channel_T *channel) | 1178 channel_can_write_to(channel_T *channel) |
1146 { | 1179 { |
1147 return channel != NULL && (channel->CH_SOCK >= 0 | 1180 return channel != NULL && (channel->CH_SOCK != CHAN_FD_INVALID |
1148 #ifdef CHANNEL_PIPES | 1181 #ifdef CHANNEL_PIPES |
1149 || channel->CH_IN >= 0 | 1182 || channel->CH_IN != CHAN_FD_INVALID |
1150 #endif | 1183 #endif |
1151 ); | 1184 ); |
1152 } | 1185 } |
1153 | 1186 |
1154 /* | 1187 /* |
1156 * Also returns FALSE for invalid "channel". | 1189 * Also returns FALSE for invalid "channel". |
1157 */ | 1190 */ |
1158 int | 1191 int |
1159 channel_is_open(channel_T *channel) | 1192 channel_is_open(channel_T *channel) |
1160 { | 1193 { |
1161 return channel != NULL && (channel->CH_SOCK >= 0 | 1194 return channel != NULL && (channel->CH_SOCK != CHAN_FD_INVALID |
1162 #ifdef CHANNEL_PIPES | 1195 #ifdef CHANNEL_PIPES |
1163 || channel->CH_IN >= 0 | 1196 || channel->CH_IN != CHAN_FD_INVALID |
1164 || channel->CH_OUT >= 0 | 1197 || channel->CH_OUT != CHAN_FD_INVALID |
1165 || channel->CH_ERR >= 0 | 1198 || channel->CH_ERR != CHAN_FD_INVALID |
1166 #endif | 1199 #endif |
1167 ); | 1200 ); |
1168 } | 1201 } |
1169 | 1202 |
1170 /* | 1203 /* |
1191 | 1224 |
1192 #ifdef FEAT_GUI | 1225 #ifdef FEAT_GUI |
1193 channel_gui_unregister(channel); | 1226 channel_gui_unregister(channel); |
1194 #endif | 1227 #endif |
1195 | 1228 |
1196 if (channel->CH_SOCK >= 0) | 1229 if (channel->CH_SOCK != CHAN_FD_INVALID) |
1197 { | 1230 { |
1198 sock_close(channel->CH_SOCK); | 1231 sock_close(channel->CH_SOCK); |
1199 channel->CH_SOCK = -1; | 1232 channel->CH_SOCK = CHAN_FD_INVALID; |
1200 } | 1233 } |
1201 #if defined(CHANNEL_PIPES) | 1234 #if defined(CHANNEL_PIPES) |
1202 if (channel->CH_IN >= 0) | 1235 if (channel->CH_IN != CHAN_FD_INVALID) |
1203 { | 1236 { |
1204 close(channel->CH_IN); | 1237 fd_close(channel->CH_IN); |
1205 channel->CH_IN = -1; | 1238 channel->CH_IN = CHAN_FD_INVALID; |
1206 } | 1239 } |
1207 if (channel->CH_OUT >= 0) | 1240 if (channel->CH_OUT != CHAN_FD_INVALID) |
1208 { | 1241 { |
1209 close(channel->CH_OUT); | 1242 fd_close(channel->CH_OUT); |
1210 channel->CH_OUT = -1; | 1243 channel->CH_OUT = CHAN_FD_INVALID; |
1211 } | 1244 } |
1212 if (channel->CH_ERR >= 0) | 1245 if (channel->CH_ERR != CHAN_FD_INVALID) |
1213 { | 1246 { |
1214 close(channel->CH_ERR); | 1247 fd_close(channel->CH_ERR); |
1215 channel->CH_ERR = -1; | 1248 channel->CH_ERR = CHAN_FD_INVALID; |
1216 } | 1249 } |
1217 #endif | 1250 #endif |
1218 | 1251 |
1219 channel->ch_close_cb = NULL; | 1252 channel->ch_close_cb = NULL; |
1220 channel_clear(channel); | 1253 channel_clear(channel); |
1323 * Check for reading from "fd" with "timeout" msec. | 1356 * Check for reading from "fd" with "timeout" msec. |
1324 * Return FAIL when there is nothing to read. | 1357 * Return FAIL when there is nothing to read. |
1325 * Always returns OK for FEAT_GUI_W32. | 1358 * Always returns OK for FEAT_GUI_W32. |
1326 */ | 1359 */ |
1327 static int | 1360 static int |
1328 channel_wait(channel_T *channel, int fd, int timeout) | 1361 channel_wait(channel_T *channel, sock_T fd, int timeout) |
1329 { | 1362 { |
1330 #if defined(HAVE_SELECT) && !defined(FEAT_GUI_W32) | 1363 #if defined(HAVE_SELECT) && !defined(FEAT_GUI_W32) |
1331 struct timeval tval; | 1364 struct timeval tval; |
1332 fd_set rfds; | 1365 fd_set rfds; |
1333 int ret; | 1366 int ret; |
1334 | 1367 |
1335 if (timeout > 0) | 1368 if (timeout > 0) |
1336 ch_logn(channel, "Waiting for %d msec\n", timeout); | 1369 ch_logn(channel, "Waiting for %d msec\n", timeout); |
1370 | |
1371 | |
1372 # ifdef WIN32 | |
1373 if (channel->CH_SOCK == CHAN_FD_INVALID) | |
1374 { | |
1375 DWORD nread; | |
1376 int diff; | |
1377 DWORD deadline = GetTickCount() + timeout; | |
1378 | |
1379 /* reading from a pipe, not a socket */ | |
1380 while (TRUE) | |
1381 { | |
1382 if (PeekNamedPipe(fd, NULL, 0, NULL, &nread, NULL) && nread > 0) | |
1383 return OK; | |
1384 diff = deadline - GetTickCount(); | |
1385 if (diff < 0) | |
1386 break; | |
1387 /* Wait for 5 msec. | |
1388 * TODO: increase the sleep time when looping more often */ | |
1389 Sleep(5); | |
1390 } | |
1391 return FAIL; | |
1392 } | |
1393 #endif | |
1394 | |
1337 FD_ZERO(&rfds); | 1395 FD_ZERO(&rfds); |
1338 FD_SET(fd, &rfds); | 1396 FD_SET((int)fd, &rfds); |
1339 tval.tv_sec = timeout / 1000; | 1397 tval.tv_sec = timeout / 1000; |
1340 tval.tv_usec = (timeout % 1000) * 1000; | 1398 tval.tv_usec = (timeout % 1000) * 1000; |
1341 for (;;) | 1399 for (;;) |
1342 { | 1400 { |
1343 ret = select(fd + 1, &rfds, NULL, NULL, &tval); | 1401 ret = select((int)fd + 1, &rfds, NULL, NULL, &tval); |
1344 # ifdef EINTR | 1402 # ifdef EINTR |
1345 if (ret == -1 && errno == EINTR) | 1403 if (ret == -1 && errno == EINTR) |
1346 continue; | 1404 continue; |
1347 # endif | 1405 # endif |
1348 if (ret <= 0) | 1406 if (ret <= 0) |
1383 | 1441 |
1384 /* | 1442 /* |
1385 * Get the file descriptor to read from, either the socket or stdout. | 1443 * Get the file descriptor to read from, either the socket or stdout. |
1386 * TODO: should have a way to read stderr. | 1444 * TODO: should have a way to read stderr. |
1387 */ | 1445 */ |
1388 static int | 1446 static sock_T |
1389 get_read_fd(channel_T *channel) | 1447 get_read_fd(channel_T *channel) |
1390 { | 1448 { |
1391 if (channel->CH_SOCK >= 0) | 1449 if (channel->CH_SOCK != CHAN_FD_INVALID) |
1392 return channel->CH_SOCK; | 1450 return channel->CH_SOCK; |
1393 #if defined(CHANNEL_PIPES) | 1451 #if defined(CHANNEL_PIPES) |
1394 if (channel->CH_OUT >= 0) | 1452 if (channel->CH_OUT != CHAN_FD_INVALID) |
1395 return channel->CH_OUT; | 1453 return channel->CH_OUT; |
1396 #endif | 1454 #endif |
1397 ch_error(channel, "channel_read() called while socket is closed\n"); | 1455 ch_error(channel, "channel_read() called while socket is closed\n"); |
1398 return -1; | 1456 return CHAN_FD_INVALID; |
1399 } | 1457 } |
1400 | 1458 |
1401 /* | 1459 /* |
1402 * Read from channel "channel" for as long as there is something to read. | 1460 * Read from channel "channel" for as long as there is something to read. |
1403 * "which" is CHAN_SOCK, CHAN_OUT or CHAN_ERR. When -1 use CHAN_SOCK or | 1461 * "which" is CHAN_SOCK, CHAN_OUT or CHAN_ERR. When -1 use CHAN_SOCK or |
1408 channel_read(channel_T *channel, int which, char *func) | 1466 channel_read(channel_T *channel, int which, char *func) |
1409 { | 1467 { |
1410 static char_u *buf = NULL; | 1468 static char_u *buf = NULL; |
1411 int len = 0; | 1469 int len = 0; |
1412 int readlen = 0; | 1470 int readlen = 0; |
1413 int fd; | 1471 sock_T fd; |
1414 int use_socket = FALSE; | 1472 int use_socket = FALSE; |
1415 | 1473 |
1416 if (which < 0) | 1474 if (which < 0) |
1417 fd = get_read_fd(channel); | 1475 fd = get_read_fd(channel); |
1418 else | 1476 else |
1419 fd = channel->ch_pfd[which].ch_fd; | 1477 fd = channel->ch_pfd[which].ch_fd; |
1420 if (fd < 0) | 1478 if (fd == CHAN_FD_INVALID) |
1421 return; | 1479 return; |
1422 use_socket = fd == channel->CH_SOCK; | 1480 use_socket = fd == channel->CH_SOCK; |
1423 | 1481 |
1424 /* Allocate a buffer to read into. */ | 1482 /* Allocate a buffer to read into. */ |
1425 if (buf == NULL) | 1483 if (buf == NULL) |
1437 if (channel_wait(channel, fd, 0) == FAIL) | 1495 if (channel_wait(channel, fd, 0) == FAIL) |
1438 break; | 1496 break; |
1439 if (use_socket) | 1497 if (use_socket) |
1440 len = sock_read(fd, buf, MAXMSGSIZE); | 1498 len = sock_read(fd, buf, MAXMSGSIZE); |
1441 else | 1499 else |
1442 len = read(fd, buf, MAXMSGSIZE); | 1500 len = fd_read(fd, buf, MAXMSGSIZE, channel->ch_timeout); |
1443 if (len <= 0) | 1501 if (len <= 0) |
1444 break; /* error or nothing more to read */ | 1502 break; /* error or nothing more to read */ |
1445 | 1503 |
1446 /* Store the read message in the queue. */ | 1504 /* Store the read message in the queue. */ |
1447 channel_save(channel, buf, len); | 1505 channel_save(channel, buf, len); |
1507 channel_read_block(channel_T *channel) | 1565 channel_read_block(channel_T *channel) |
1508 { | 1566 { |
1509 ch_log(channel, "Reading raw\n"); | 1567 ch_log(channel, "Reading raw\n"); |
1510 if (channel_peek(channel) == NULL) | 1568 if (channel_peek(channel) == NULL) |
1511 { | 1569 { |
1512 int fd = get_read_fd(channel); | 1570 sock_T fd = get_read_fd(channel); |
1513 | 1571 |
1514 /* TODO: read both out and err if they are different */ | 1572 /* TODO: read both out and err if they are different */ |
1515 ch_log(channel, "No readahead\n"); | 1573 ch_log(channel, "No readahead\n"); |
1516 /* Wait for up to the channel timeout. */ | 1574 /* Wait for up to the channel timeout. */ |
1517 if (fd < 0 || channel_wait(channel, fd, channel->ch_timeout) == FAIL) | 1575 if (fd == CHAN_FD_INVALID |
1576 || channel_wait(channel, fd, channel->ch_timeout) == FAIL) | |
1518 return NULL; | 1577 return NULL; |
1519 channel_read(channel, -1, "channel_read_block"); | 1578 channel_read(channel, -1, "channel_read_block"); |
1520 } | 1579 } |
1521 | 1580 |
1522 /* TODO: only get the first message */ | 1581 /* TODO: only get the first message */ |
1531 */ | 1590 */ |
1532 int | 1591 int |
1533 channel_read_json_block(channel_T *channel, int id, typval_T **rettv) | 1592 channel_read_json_block(channel_T *channel, int id, typval_T **rettv) |
1534 { | 1593 { |
1535 int more; | 1594 int more; |
1536 int fd; | 1595 sock_T fd; |
1537 | 1596 |
1538 ch_log(channel, "Reading JSON\n"); | 1597 ch_log(channel, "Reading JSON\n"); |
1539 channel->ch_block_id = id; | 1598 channel->ch_block_id = id; |
1540 for (;;) | 1599 for (;;) |
1541 { | 1600 { |
1555 if (channel_parse_messages()) | 1614 if (channel_parse_messages()) |
1556 continue; | 1615 continue; |
1557 | 1616 |
1558 /* Wait for up to the channel timeout. */ | 1617 /* Wait for up to the channel timeout. */ |
1559 fd = get_read_fd(channel); | 1618 fd = get_read_fd(channel); |
1560 if (fd < 0 || channel_wait(channel, fd, channel->ch_timeout) | 1619 if (fd == CHAN_FD_INVALID |
1561 == FAIL) | 1620 || channel_wait(channel, fd, channel->ch_timeout) == FAIL) |
1562 break; | 1621 break; |
1563 channel_read(channel, -1, "channel_read_json_block"); | 1622 channel_read(channel, -1, "channel_read_json_block"); |
1564 } | 1623 } |
1565 } | 1624 } |
1566 channel->ch_block_id = 0; | 1625 channel->ch_block_id = 0; |
1576 channel_fd2channel(sock_T fd, int *whichp) | 1635 channel_fd2channel(sock_T fd, int *whichp) |
1577 { | 1636 { |
1578 channel_T *channel; | 1637 channel_T *channel; |
1579 int i; | 1638 int i; |
1580 | 1639 |
1581 if (fd >= 0) | 1640 if (fd != CHAN_FD_INVALID) |
1582 for (channel = first_channel; channel != NULL; | 1641 for (channel = first_channel; channel != NULL; |
1583 channel = channel->ch_next) | 1642 channel = channel->ch_next) |
1584 { | 1643 { |
1585 # ifdef CHANNEL_PIPES | 1644 # ifdef CHANNEL_PIPES |
1586 for (i = CHAN_SOCK; i < CHAN_IN; ++i) | 1645 for (i = CHAN_SOCK; i < CHAN_IN; ++i) |
1605 int | 1664 int |
1606 channel_send(channel_T *channel, char_u *buf, char *fun) | 1665 channel_send(channel_T *channel, char_u *buf, char *fun) |
1607 { | 1666 { |
1608 int len = (int)STRLEN(buf); | 1667 int len = (int)STRLEN(buf); |
1609 int res; | 1668 int res; |
1610 int fd = -1; | 1669 sock_T fd = CHAN_FD_INVALID; |
1611 int use_socket = FALSE; | 1670 int use_socket = FALSE; |
1612 | 1671 |
1613 if (channel->CH_SOCK >= 0) | 1672 if (channel->CH_SOCK != CHAN_FD_INVALID) |
1614 { | 1673 { |
1615 fd = channel->CH_SOCK; | 1674 fd = channel->CH_SOCK; |
1616 use_socket = TRUE; | 1675 use_socket = TRUE; |
1617 } | 1676 } |
1618 #if defined(CHANNEL_PIPES) | 1677 #if defined(CHANNEL_PIPES) |
1619 else if (channel->CH_IN >= 0) | 1678 else if (channel->CH_IN != CHAN_FD_INVALID) |
1620 fd = channel->CH_IN; | 1679 fd = channel->CH_IN; |
1621 #endif | 1680 #endif |
1622 if (fd < 0) | 1681 if (fd == CHAN_FD_INVALID) |
1623 { | 1682 { |
1624 if (!channel->ch_error && fun != NULL) | 1683 if (!channel->ch_error && fun != NULL) |
1625 { | 1684 { |
1626 ch_errors(channel, "%s(): write while not connected\n", fun); | 1685 ch_errors(channel, "%s(): write while not connected\n", fun); |
1627 EMSG2("E630: %s(): write while not connected", fun); | 1686 EMSG2("E630: %s(): write while not connected", fun); |
1640 } | 1699 } |
1641 | 1700 |
1642 if (use_socket) | 1701 if (use_socket) |
1643 res = sock_write(fd, buf, len); | 1702 res = sock_write(fd, buf, len); |
1644 else | 1703 else |
1645 res = write(fd, buf, len); | 1704 res = fd_write(fd, buf, len); |
1646 if (res != len) | 1705 if (res != len) |
1647 { | 1706 { |
1648 if (!channel->ch_error && fun != NULL) | 1707 if (!channel->ch_error && fun != NULL) |
1649 { | 1708 { |
1650 ch_errors(channel, "%s(): write failed\n", fun); | 1709 ch_errors(channel, "%s(): write failed\n", fun); |
1678 for (which = CHAN_SOCK; which < CHAN_IN; ++which) | 1737 for (which = CHAN_SOCK; which < CHAN_IN; ++which) |
1679 # else | 1738 # else |
1680 which = CHAN_SOCK; | 1739 which = CHAN_SOCK; |
1681 # endif | 1740 # endif |
1682 { | 1741 { |
1683 if (channel->ch_pfd[which].ch_fd >= 0) | 1742 if (channel->ch_pfd[which].ch_fd != CHAN_FD_INVALID) |
1684 { | 1743 { |
1685 channel->ch_pfd[which].ch_poll_idx = nfd; | 1744 channel->ch_pfd[which].ch_poll_idx = nfd; |
1686 fds[nfd].fd = channel->ch_pfd[which].ch_fd; | 1745 fds[nfd].fd = channel->ch_pfd[which].ch_fd; |
1687 fds[nfd].events = POLLIN; | 1746 fds[nfd].events = POLLIN; |
1688 nfd++; | 1747 nfd++; |
1748 which = CHAN_SOCK; | 1807 which = CHAN_SOCK; |
1749 # endif | 1808 # endif |
1750 { | 1809 { |
1751 sock_T fd = channel->ch_pfd[which].ch_fd; | 1810 sock_T fd = channel->ch_pfd[which].ch_fd; |
1752 | 1811 |
1753 if (fd >= 0) | 1812 if (fd != CHAN_FD_INVALID) |
1754 { | 1813 { |
1755 FD_SET(fd, rfds); | 1814 FD_SET((int)fd, rfds); |
1756 if (maxfd < fd) | 1815 if (maxfd < (int)fd) |
1757 maxfd = fd; | 1816 maxfd = (int)fd; |
1758 } | 1817 } |
1759 } | 1818 } |
1760 } | 1819 } |
1761 | 1820 |
1762 return maxfd; | 1821 return maxfd; |
1781 which = CHAN_SOCK; | 1840 which = CHAN_SOCK; |
1782 # endif | 1841 # endif |
1783 { | 1842 { |
1784 sock_T fd = channel->ch_pfd[which].ch_fd; | 1843 sock_T fd = channel->ch_pfd[which].ch_fd; |
1785 | 1844 |
1786 if (ret > 0 && fd >= 0 && FD_ISSET(fd, rfds)) | 1845 if (ret > 0 && fd != CHAN_FD_INVALID && FD_ISSET(fd, rfds)) |
1787 { | 1846 { |
1788 channel_read(channel, which, "channel_select_check"); | 1847 channel_read(channel, which, "channel_select_check"); |
1789 --ret; | 1848 --ret; |
1790 } | 1849 } |
1791 } | 1850 } |