diff options
author | Steve Bennett <steveb@workware.net.au> | 2011-05-27 11:13:53 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2013-12-21 01:30:02 +1000 |
commit | 63bc08c2ec6e1744eed22160f8b7fd1078a9b49f (patch) | |
tree | 3753c1dcb431c569dcc234d6a1740fb625cf90f7 | |
parent | cee11498057b7aa8045a50967c54e010e9a97cfe (diff) | |
download | jimtcl-63bc08c2ec6e1744eed22160f8b7fd1078a9b49f.zip jimtcl-63bc08c2ec6e1744eed22160f8b7fd1078a9b49f.tar.gz jimtcl-63bc08c2ec6e1744eed22160f8b7fd1078a9b49f.tar.bz2 |
Add support for 'socket pair'
Creates a pair of bidirectional sockets with socketpair(2)
Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r-- | auto.def | 3 | ||||
-rw-r--r-- | jim-aio.c | 76 | ||||
-rw-r--r-- | jim_tcl.txt | 5 |
3 files changed, 58 insertions, 26 deletions
@@ -87,7 +87,8 @@ cc-check-functions ualarm lstat fork vfork system select execvpe cc-check-functions backtrace geteuid mkstemp realpath strptime isatty cc-check-functions regcomp waitpid sigaction sys_signame sys_siglist isascii cc-check-functions syslog opendir readlink sleep usleep pipe getaddrinfo utimes -cc-check-functions shutdown +cc-check-functions shutdown socketpair + if {[cc-check-functions sysinfo]} { cc-with {-includes sys/sysinfo.h} { cc-check-members "struct sysinfo.uptime" @@ -1125,6 +1125,27 @@ static int JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *filenam return JIM_OK; } +static int JimMakeChannelPair(Jim_Interp *interp, int p[2], Jim_Obj *filename, + const char *hdlfmt, int family, const char *mode[2]) +{ + if (JimMakeChannel(interp, NULL, p[0], filename, hdlfmt, family, mode[0]) == JIM_OK) { + Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0); + Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp)); + + if (JimMakeChannel(interp, NULL, p[1], filename, hdlfmt, family, mode[1]) == JIM_OK) { + Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp)); + Jim_SetResult(interp, objPtr); + return JIM_OK; + } + } + + /* Can only be here if fdopen() failed */ + close(p[0]); + close(p[1]); + JimAioSetError(interp, NULL); + return JIM_ERR; +} + #if !defined(JIM_ANSIC) && !defined(JIM_BOOTSTRAP) static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -1138,6 +1159,7 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) "stream", "stream.server", "pipe", + "pair", NULL }; enum @@ -1149,10 +1171,7 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) SOCK_STREAM_CLIENT, SOCK_STREAM_SERVER, SOCK_STREAM_PIPE, - SOCK_DGRAM6_CLIENT, - SOCK_DGRAM6_SERVER, - SOCK_STREAM6_CLIENT, - SOCK_STREAM6_SERVER, + SOCK_STREAM_SOCKETPAIR, }; int socktype; int sock; @@ -1348,38 +1367,45 @@ static int JimAioSockCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } #endif -#ifdef HAVE_PIPE - case SOCK_STREAM_PIPE: - { +#if defined(HAVE_SOCKETPAIR) && defined(HAVE_SYS_UN_H) + case SOCK_STREAM_SOCKETPAIR: + { int p[2]; + static const char *mode[2] = { "r+", "r+" }; if (argc != 2 || ipv6) { goto wrongargs; } - if (pipe(p) < 0) { - JimAioSetError(interp, NULL); - return JIM_ERR; - } + if (socketpair(PF_UNIX, SOCK_STREAM, 0, p) < 0) { + JimAioSetError(interp, NULL); + return JIM_ERR; + } + return JimMakeChannelPair(interp, p, argv[1], "aio.sockpair%ld", PF_UNIX, mode); + } + break; +#endif - if (JimMakeChannel(interp, NULL, p[0], argv[1], "aio.pipe%ld", 0, "r") == JIM_OK) { - Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0); - Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp)); +#if defined(HAVE_PIPE) + case SOCK_STREAM_PIPE: + { + int p[2]; + static const char *mode[2] = { "r", "w" }; - if (JimMakeChannel(interp, NULL, p[1], argv[1], "aio.pipe%ld", 0, "w") == JIM_OK) { - Jim_ListAppendElement(interp, objPtr, Jim_GetResult(interp)); - Jim_SetResult(interp, objPtr); - return JIM_OK; - } + if (argc != 2 || ipv6) { + goto wrongargs; } - /* Can only be here if fdopen() failed */ - close(p[0]); - close(p[1]); - JimAioSetError(interp, NULL); - return JIM_ERR; - } + + if (pipe(p) < 0) { + JimAioSetError(interp, NULL); + return JIM_ERR; + } + + return JimMakeChannelPair(interp, p, argv[1], "aio.pipe%ld", 0, mode); + } break; #endif + default: Jim_SetResultString(interp, "Unsupported socket type", -1); return JIM_ERR; diff --git a/jim_tcl.txt b/jim_tcl.txt index 80e7673..19238b3 100644 --- a/jim_tcl.txt +++ b/jim_tcl.txt @@ -58,6 +58,7 @@ Changes between 0.74 and 0.75 3. `format` now supports +%b+ for binary conversion 4. `lsort` now supports '-unique' and '-real' 5. Add support for half-close with `aio close` ?r|w? +6. Add `socket pair` for a bidirectional pipe Changes between 0.73 and 0.74 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -4589,6 +4590,10 @@ Various socket types may be created. A pipe. Note that unlike all other socket types, this command returns a list of two channels: {read write} ++*socket pair*+:: + A socketpair (see socketpair(2)). Like `socket pipe`, this command returns + a list of two channels: {s1 s2}. These channels are both readable and writable. + This command creates a socket connected (client) or bound (server) to the given address. |