aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2011-05-27 11:13:53 +1000
committerSteve Bennett <steveb@workware.net.au>2013-12-21 01:30:02 +1000
commit63bc08c2ec6e1744eed22160f8b7fd1078a9b49f (patch)
tree3753c1dcb431c569dcc234d6a1740fb625cf90f7
parentcee11498057b7aa8045a50967c54e010e9a97cfe (diff)
downloadjimtcl-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.def3
-rw-r--r--jim-aio.c76
-rw-r--r--jim_tcl.txt5
3 files changed, 58 insertions, 26 deletions
diff --git a/auto.def b/auto.def
index 59baea0..974ecfe 100644
--- a/auto.def
+++ b/auto.def
@@ -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"
diff --git a/jim-aio.c b/jim-aio.c
index 4ccdae4..c73ecb4 100644
--- a/jim-aio.c
+++ b/jim-aio.c
@@ -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.