aboutsummaryrefslogtreecommitdiff
path: root/jim-aio.c
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2022-08-04 11:13:39 +1000
committerSteve Bennett <steveb@workware.net.au>2022-08-20 15:27:19 +1000
commit6e1d4cc163dc37f0ea5cdae8b3e2b9e4b0a73254 (patch)
tree9596172bde8edbcf87bcdb1d9012fa6d0a948167 /jim-aio.c
parent5af9d6a919b83e28a37ade2db8090a375a93ba53 (diff)
downloadjimtcl-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.c71
1 files changed, 51 insertions, 20 deletions
diff --git a/jim-aio.c b/jim-aio.c
index 5769f78..f9f3de9 100644
--- a/jim-aio.c
+++ b/jim-aio.c
@@ -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) {