diff options
author | Steve Bennett <steveb@workware.net.au> | 2022-08-04 11:13:39 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2022-08-20 15:27:19 +1000 |
commit | 6e1d4cc163dc37f0ea5cdae8b3e2b9e4b0a73254 (patch) | |
tree | 9596172bde8edbcf87bcdb1d9012fa6d0a948167 /jim-aio.c | |
parent | 5af9d6a919b83e28a37ade2db8090a375a93ba53 (diff) | |
download | jimtcl-6e1d4cc163dc37f0ea5cdae8b3e2b9e4b0a73254.zip jimtcl-6e1d4cc163dc37f0ea5cdae8b3e2b9e4b0a73254.tar.gz jimtcl-6e1d4cc163dc37f0ea5cdae8b3e2b9e4b0a73254.tar.bz2 |
socket: add support for -async
Very similar to Tcl except that read/write can't be done until
writable indicates the socket is connected.
Signed-off-by: Steve Bennett <steveb@workware.net.au>
Documentation fixes -
Co-authored-by: Adrian Ho <the.gromgit@gmail.com>
Diffstat (limited to 'jim-aio.c')
-rw-r--r-- | jim-aio.c | 71 |
1 files changed, 51 insertions, 20 deletions
@@ -1209,26 +1209,32 @@ static int aio_cmd_filename(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } #ifdef O_NDELAY +static int aio_set_nonblocking(int fd, int nb) +{ + int fmode = fcntl(fd, F_GETFL); + if (nb) { + fmode |= O_NDELAY; + } + else { + fmode &= ~O_NDELAY; + } + (void)fcntl(fd, F_SETFL, fmode); + return fmode; +} + static int aio_cmd_ndelay(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { AioFile *af = Jim_CmdPrivData(interp); - int fmode = fcntl(af->fd, F_GETFL); - if (argc) { long nb; if (Jim_GetLong(interp, argv[0], &nb) != JIM_OK) { return JIM_ERR; } - if (nb) { - fmode |= O_NDELAY; - } - else { - fmode &= ~O_NDELAY; - } - (void)fcntl(af->fd, F_SETFL, fmode); + aio_set_nonblocking(af->fd, nb); } + int fmode = fcntl(af->fd, F_GETFL); Jim_SetResultInt(interp, (fmode & O_NONBLOCK) ? 1 : 0); return JIM_OK; } @@ -2197,21 +2203,38 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) int type = SOCK_STREAM; Jim_Obj *argv0 = argv[0]; int ipv6 = 0; + int async = 0; - if (argc > 1 && Jim_CompareStringImmediate(interp, argv[1], "-ipv6")) { - if (!IPV6) { - Jim_SetResultString(interp, "ipv6 not supported", -1); + + while (argc > 1 && Jim_String(argv[1])[0] == '-') { + static const char * const options[] = { "-async", "-ipv6", NULL }; + enum { OPT_ASYNC, OPT_IPV6 }; + int option; + + if (Jim_GetEnum(interp, argv[1], options, &option, NULL, JIM_ERRMSG) != JIM_OK) { return JIM_ERR; } - ipv6 = 1; - family = PF_INET6; + switch (option) { + case OPT_ASYNC: + async = 1; + break; + + case OPT_IPV6: + if (!IPV6) { + Jim_SetResultString(interp, "ipv6 not supported", -1); + return JIM_ERR; + } + ipv6 = 1; + family = PF_INET6; + break; + } + argc--; + argv++; } - argc -= ipv6; - argv += ipv6; if (argc < 2) { wrongargs: - Jim_WrongNumArgs(interp, 1, &argv0, "?-ipv6? type ?address?"); + Jim_WrongNumArgs(interp, 1, &argv0, "?-async? ?-ipv6? type ?address?"); return JIM_ERR; } @@ -2347,6 +2370,9 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) JimAioSetError(interp, NULL); return JIM_ERR; } + if (async) { + aio_set_nonblocking(sock, 1); + } if (bind_addr) { if (JimParseSocketAddress(interp, family, type, bind_addr, &sa, &salen) != JIM_OK) { close(sock); @@ -2367,9 +2393,14 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_ERR; } if (connect(sock, &sa.sa, salen)) { - Jim_SetResultFormatted(interp, "%s: connect: %s", connect_addr, strerror(errno)); - close(sock); - return JIM_ERR; + if (async && errno == EINPROGRESS) { + /* OK */ + } + else { + Jim_SetResultFormatted(interp, "%s: connect: %s", connect_addr, strerror(errno)); + close(sock); + return JIM_ERR; + } } } if (do_listen) { |