zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: Unix domain socket module
@ 2002-08-18  2:09 Clint Adams
  2002-08-22 11:54 ` Peter Stephenson
  0 siblings, 1 reply; 3+ messages in thread
From: Clint Adams @ 2002-08-18  2:09 UTC (permalink / raw)
  To: zsh-workers

This implements the zsocket builtin for IPC via local Unix domain
sockets.  Omitted is the ability to do SOCK_DGRAM.

Index: Src/Modules/.distfiles
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/.distfiles,v
retrieving revision 1.6
diff -u -r1.6 .distfiles
--- Src/Modules/.distfiles	6 Jun 2002 04:54:50 -0000	1.6
+++ Src/Modules/.distfiles	18 Aug 2002 02:01:55 -0000
@@ -10,6 +10,7 @@
     mathfunc.mdd mathfunc.c
     parameter.mdd parameter.c
     pcre.mdd pcre.c
+    socket.mdd socket.c
     stat.mdd stat.c
     tcp.mdd tcp.c tcp.h
     termcap.mdd termcap.c
Index: Src/Modules/socket.c
===================================================================
RCS file: Src/Modules/socket.c
diff -N Src/Modules/socket.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Src/Modules/socket.c	18 Aug 2002 02:01:56 -0000
@@ -0,0 +1,286 @@
+/*
+ * socket.c - Unix domain socket module
+ *
+ * This file is part of zsh, the Z shell.
+ *
+ * Copyright (c) 2002 Peter Stephenson
+ * All rights reserved.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and to distribute modified versions of this software for any
+ * purpose, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * In no event shall Peter Stephenson or the Zsh Development
+ * Group be liable to any party for direct, indirect, special, incidental,
+ * or consequential damages arising out of the use of this software and
+ * its documentation, even if Peter Stephenson, and the Zsh
+ * Development Group have been advised of the possibility of such damage.
+ *
+ * Peter Stephenson and the Zsh Development Group specifically
+ * disclaim any warranties, including, but not limited to, the implied
+ * warranties of merchantability and fitness for a particular purpose.  The
+ * software provided hereunder is on an "as is" basis, and Peter Stephenson
+ * and the Zsh Development Group have no obligation to provide maintenance,
+ * support, updates, enhancements, or modifications.
+ *
+ */
+
+#include "socket.mdh"
+#include "socket.pro"
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#ifndef UNIX_PATH_MAX
+# define UNIX_PATH_MAX 108
+#endif
+
+/*
+ * We need to include the zsh headers later to avoid clashes with
+ * the definitions on some systems, however we need the configuration
+ * file to decide whether we can include netinet/in_systm.h, which
+ * doesn't exist on cygwin.
+ */
+
+/*
+ * We use poll() in preference to select because some subset of manuals says
+ * that's the thing to do, plus it's a bit less fiddly.  I don't actually
+ * have access to a system with poll but not select, however, though
+ * both bits of the code have been tested on a machine with both.
+ */
+#ifdef HAVE_POLL_H
+# include <poll.h>
+#endif
+#if defined(HAVE_POLL) && !defined(POLLIN) && !defined(POLLNORM)
+# undef HAVE_POLL
+#endif
+
+static int
+bin_zsocket(char *nam, char **args, char *ops, int func)
+{
+    int err=1, verbose=0, test=0, targetfd=0;
+    SOCKLEN_T len;
+    char **dargs;
+    struct sockaddr_un sun;
+    int sfd;
+
+    if (ops['v'])
+	verbose = 1;
+
+    if (ops['t'])
+	test = 1;
+
+    if (ops['d']) {
+	targetfd = atoi(args[0]);
+	dargs = args + 1;
+	if (!targetfd) {
+	    zwarnnam(nam, "%s is an invalid argument to -d", args[0], 0);
+	    return 1;
+	}
+    }
+    else
+	dargs = args;
+
+
+    if (ops['l']) {
+	char *localfn;
+
+	if (!dargs[0]) {
+	    zwarnnam(nam, "-l requires an argument", NULL, 0);
+	    return 1;
+	}
+
+	localfn = dargs[0];
+
+	sfd = socket(PF_UNIX, SOCK_STREAM, 0);
+
+	if (sfd == -1) {
+	    zwarnnam(nam, "socket error: %e ", NULL, errno);
+	    return 1;
+	}
+
+	sun.sun_family = AF_UNIX;
+	strncpy(sun.sun_path, localfn, UNIX_PATH_MAX);
+
+	if (bind(sfd, (struct sockaddr *)&sun, sizeof(struct sockaddr_un)))
+	{
+	    zwarnnam(nam, "could not bind to %s: %e", sun.sun_path, errno);
+	    close(sfd);
+	    return 1;
+	}
+
+	if (listen(sfd, 1))
+	{
+	    zwarnnam(nam, "could not listen on socket: %e", NULL, errno);
+	    close(sfd);
+	    return 1;
+	}
+
+	if (targetfd) {
+	    redup(sfd, targetfd);
+	    sfd = targetfd;
+	}
+	else {
+	    /* move the fd since no one will want to read from it */
+	    sfd = movefd(sfd);
+	}
+
+	setiparam("REPLY", sfd);
+
+	if (verbose)
+	    printf("%s listener is on fd %d\n", sun.sun_path, sfd);
+
+	return 0;
+
+    }
+    else if (ops['a'])
+    {
+	int lfd, rfd;
+
+	if (!dargs[0]) {
+	    zwarnnam(nam, "-a requires an argument", NULL, 0);
+	    return 1;
+	}
+
+	lfd = atoi(dargs[0]);
+
+	if (!lfd) {
+	    zwarnnam(nam, "invalid numerical argument", NULL, 0);
+	    return 1;
+	}
+
+	if (test) {
+#if defined(HAVE_POLL) || defined(HAVE_SELECT)
+# ifdef HAVE_POLL
+	    struct pollfd pfd;
+	    int ret;
+
+	    pfd.fd = lfd;
+	    pfd.events = POLLIN;
+	    if ((ret = poll(&pfd, 1, 0)) == 0) return 1;
+	    else if (ret == -1)
+	    {
+		zwarnnam(nam, "poll error: %e", NULL, errno);
+		return 1;
+	    }
+# else
+	    fd_set rfds;
+	    struct timeval tv;
+	    int ret;
+	    
+	    FD_ZERO(&rfds);
+	    FD_SET(lfd, &rfds);
+	    tv.tv_sec = 0;
+	    tv.tv_usec = 0;
+	    
+	    if (ret = select(lfd+1, &rfds, NULL, NULL, &tv)) return 1;
+	    else if (ret == -1)
+	    {
+		zwarnnam(nam, "select error: %e", NULL, errno);
+		return 1;
+	    }
+	    
+# endif
+	    
+#else
+	    zwarnnam(nam, "not currently supported", NULL, 0);
+	    return 1;
+#endif
+	}
+
+	if ((rfd = accept(lfd, (struct sockaddr *)&sun, &len)) == -1)
+	{
+	    zwarnnam(nam, "could not accept connection: %e", NULL, errno);
+	    return 1;
+	}
+
+	if (targetfd) {
+	    redup(rfd, targetfd);
+	    sfd = targetfd;
+	}
+	else {
+	    sfd = rfd;
+	}
+
+	setiparam("REPLY", sfd);
+
+	if (verbose)
+	    printf("new connection from %s is on fd %d\n", sun.sun_path, sfd);
+    }
+    else
+    {
+	if (!dargs[0]) {
+	    zwarnnam(nam, "zsocket requires an argument", NULL, 0);
+	    return 1;
+	}
+
+	sfd = socket(PF_UNIX, SOCK_STREAM, 0);
+
+	if (sfd == -1) {
+	    zwarnnam(nam, "socket creation failed: %e", NULL, errno);
+	    return 1;
+	}
+
+	sun.sun_family = AF_UNIX;
+	strncpy(sun.sun_path, dargs[0], UNIX_PATH_MAX);
+	
+	if ((err = connect(sfd, (struct sockaddr *)&sun, sizeof(struct sockaddr_un)))) {
+	    zwarnnam(nam, "connection failed: %e", NULL, errno);
+	    close(sfd);
+	    return 1;
+	}
+	else
+	{
+	    if (targetfd) {
+		redup(sfd, targetfd);
+		sfd = targetfd;
+	    }
+
+	    setiparam("REPLY", sfd);
+
+	    if (verbose)
+		printf("%s is now on fd %d\n", sun.sun_path, sfd);
+	}
+	
+    }
+
+    return 0;
+}
+
+static struct builtin bintab[] = {
+    BUILTIN("zsocket", 0, bin_zsocket, 0, 3, 0, "adltv", NULL),
+};
+
+/* The load/unload routines required by the zsh library interface */
+
+/**/
+int
+setup_(Module m)
+{
+    return 0;
+}
+
+/**/
+int
+boot_(Module m)
+{
+    return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
+}
+
+
+/**/
+int
+cleanup_(Module m)
+{
+    deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
+    return 0;
+}
+
+/**/
+int
+finish_(Module m)
+{
+    return 0;
+}
Index: Src/Modules/socket.mdd
===================================================================
RCS file: Src/Modules/socket.mdd
diff -N Src/Modules/socket.mdd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Src/Modules/socket.mdd	18 Aug 2002 02:01:56 -0000
@@ -0,0 +1,6 @@
+name=zsh/net/socket
+link=dynamic
+load=no
+
+objects="socket.o"
+autobins="zsocket"
Index: Doc/Zsh/.distfiles
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/.distfiles,v
retrieving revision 1.9
diff -u -r1.9 .distfiles
--- Doc/Zsh/.distfiles	17 Jun 2002 13:29:24 -0000	1.9
+++ Doc/Zsh/.distfiles	18 Aug 2002 02:01:56 -0000
@@ -6,7 +6,8 @@
     mod_clone.yo mod_compctl.yo mod_complete.yo mod_complist.yo
     mod_computil.yo mod_deltochar.yo mod_example.yo mod_files.yo mod_langinfo.yo
     mod_mapfile.yo mod_mathfunc.yo mod_parameter.yo mod_pcre.yo mod_sched.yo
-    mod_stat.yo mod_tcp.yo mod_termcap.yo mod_terminfo.yo mod_zftp.yo mod_zle.yo
+    mod_socket.yo mod_stat.yo mod_tcp.yo mod_termcap.yo mod_terminfo.yo
+    mod_zftp.yo mod_zle.yo
     mod_zleparameter.yo mod_zselect.yo mod_zutil.yo mod_zprof.yo mod_zpty.yo
     modules.yo modlist.yo modmenu.yo manmodmenu.yo
     options.yo params.yo prompt.yo redirect.yo restricted.yo seealso.yo
Index: Doc/Zsh/builtins.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/builtins.yo,v
retrieving revision 1.48
diff -u -r1.48 builtins.yo
--- Doc/Zsh/builtins.yo	6 Aug 2002 13:05:51 -0000	1.48
+++ Doc/Zsh/builtins.yo	18 Aug 2002 02:02:00 -0000
@@ -1733,6 +1733,7 @@
 module(zprof)(zsh/zprof)
 module(zpty)(zsh/zpty)
 module(zregexparse)(zsh/zutil)
+module(zsocket)(zsh/net/socket)
 module(zstyle)(zsh/zutil)
 module(ztcp)(zsh/net/tcp)
 enditem()
Index: Doc/Zsh/mod_socket.yo
===================================================================
RCS file: Doc/Zsh/mod_socket.yo
diff -N Doc/Zsh/mod_socket.yo
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Doc/Zsh/mod_socket.yo	18 Aug 2002 02:02:00 -0000
@@ -0,0 +1,64 @@
+COMMENT(!MOD!zsh/net/socket
+Manipulation of Unix domain sockets
+!MOD!)
+The tt(zsh/net/socket) module makes available one builtin command:
+
+startitem()
+findex(zsocket)
+cindex(sockets)
+cindex(sockets, Unix domain)
+item(tt(zsocket) [ tt(-adltv) ] [ var(args) ])(
+tt(zsocket) is implemented as a builtin to allow full use of shell
+command line editing, file I/O, and job control mechanisms.
+
+subsect(Outbound Connections)
+cindex(sockets, outbound Unix domain)
+
+startitem()
+item(tt(zsocket) [ tt(-v) ] [ tt(-d) var(fd) ] var(filename))(
+Open a new Unix domain connection to var(filename).
+The shell parameter tt(REPLY) will be set to the file descriptor
+associated with that connection.  Currently, only stream connections
+are supported.
+
+If tt(-d) is specified, the first non-option argument
+will be taken as the target file descriptor for the
+connection.
+
+In order to elicit more verbose output, use tt(-v).
+)
+enditem()
+
+subsect(Inbound Connections)
+cindex(sockets, inbound Unix domain)
+
+startitem()
+item(tt(zsocket) tt(-l) [ tt(-v) ] [ tt(-d) var(fd) ] var(filename))(
+tt(zsocket -l) will open a socket listening on var(filename).
+The shell parameter tt(REPLY) will be set to the file descriptor
+associated with that listener.
+
+If tt(-d) is specified, the first non-option argument
+will be taken as the target file descriptor for
+the connection.
+
+In order to elicit more verbose output, use tt(-v).
+)
+item(tt(zsocket) tt(-a) [ tt(-tv) ] [ tt(-d) var(targetfd) ] var(listenfd))(
+tt(zsocket -a) will accept an incoming connection
+to the socket associated with var(listenfd).
+The shell parameter tt(REPLY) will
+be set to the file descriptor associated with
+the inbound connection.
+
+If tt(-d) is specified, the first non-option argument
+will be taken as the target file descriptor for the
+connection.
+
+If tt(-t) is specified, tt(zsocket) will return
+if no incoming connection is pending.  Otherwise
+it will wait for one.
+
+In order to elicit more verbose output, use tt(-v).
+)
+enditem()


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: PATCH: Unix domain socket module
  2002-08-18  2:09 PATCH: Unix domain socket module Clint Adams
@ 2002-08-22 11:54 ` Peter Stephenson
  2002-08-22 15:54   ` Clint Adams
  0 siblings, 1 reply; 3+ messages in thread
From: Peter Stephenson @ 2002-08-22 11:54 UTC (permalink / raw)
  To: Zsh hackers list

Clint Adams wrote:
> This implements the zsocket builtin for IPC via local Unix domain
> sockets.  Omitted is the ability to do SOCK_DGRAM.

Minor tweaks.  `sun' is predefined on hardware from a certain vendor.
The compiler didn't like the declaration `sockaddr_un 1'.

Looks like there's no way to close an fd opened for listening since this
is beyond 9?  We could add an EXTENDED_FD option to allow `11>&-', but I
suspect the parser is going to fight this all the way.  A quick and
dirty hack (not implemented) would be to allow `zsocket -c fd' to close
any old fd.

Are you going to commit the terminfo fix for 4.0?  That looks quite
serious.

Index: Src/Modules/socket.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/socket.c,v
retrieving revision 1.1
diff -u -r1.1 socket.c
--- Src/Modules/socket.c	18 Aug 2002 02:12:39 -0000	1.1
+++ Src/Modules/socket.c	22 Aug 2002 11:25:49 -0000
@@ -63,7 +63,7 @@
     int err=1, verbose=0, test=0, targetfd=0;
     SOCKLEN_T len;
     char **dargs;
-    struct sockaddr_un sun;
+    struct sockaddr_un soun;
     int sfd;
 
     if (ops['v'])
@@ -101,12 +101,12 @@
 	    return 1;
 	}
 
-	sun.sun_family = AF_UNIX;
-	strncpy(sun.sun_path, localfn, UNIX_PATH_MAX);
+	soun.sun_family = AF_UNIX;
+	strncpy(soun.sun_path, localfn, UNIX_PATH_MAX);
 
-	if (bind(sfd, (struct sockaddr *)&sun, sizeof(struct sockaddr_un)))
+	if (bind(sfd, (struct sockaddr *)&soun, sizeof(struct sockaddr_un)))
 	{
-	    zwarnnam(nam, "could not bind to %s: %e", sun.sun_path, errno);
+	    zwarnnam(nam, "could not bind to %s: %e", soun.sun_path, errno);
 	    close(sfd);
 	    return 1;
 	}
@@ -130,7 +130,7 @@
 	setiparam("REPLY", sfd);
 
 	if (verbose)
-	    printf("%s listener is on fd %d\n", sun.sun_path, sfd);
+	    printf("%s listener is on fd %d\n", soun.sun_path, sfd);
 
 	return 0;
 
@@ -190,7 +190,8 @@
 #endif
 	}
 
-	if ((rfd = accept(lfd, (struct sockaddr *)&sun, &len)) == -1)
+	len = sizeof(soun);
+	if ((rfd = accept(lfd, (struct sockaddr *)&soun, &len)) == -1)
 	{
 	    zwarnnam(nam, "could not accept connection: %e", NULL, errno);
 	    return 1;
@@ -207,7 +208,7 @@
 	setiparam("REPLY", sfd);
 
 	if (verbose)
-	    printf("new connection from %s is on fd %d\n", sun.sun_path, sfd);
+	    printf("new connection from %s is on fd %d\n", soun.sun_path, sfd);
     }
     else
     {
@@ -223,10 +224,10 @@
 	    return 1;
 	}
 
-	sun.sun_family = AF_UNIX;
-	strncpy(sun.sun_path, dargs[0], UNIX_PATH_MAX);
+	soun.sun_family = AF_UNIX;
+	strncpy(soun.sun_path, dargs[0], UNIX_PATH_MAX);
 	
-	if ((err = connect(sfd, (struct sockaddr *)&sun, sizeof(struct sockaddr_un)))) {
+	if ((err = connect(sfd, (struct sockaddr *)&soun, sizeof(struct sockaddr_un)))) {
 	    zwarnnam(nam, "connection failed: %e", NULL, errno);
 	    close(sfd);
 	    return 1;
@@ -241,7 +242,7 @@
 	    setiparam("REPLY", sfd);
 
 	    if (verbose)
-		printf("%s is now on fd %d\n", sun.sun_path, sfd);
+		printf("%s is now on fd %d\n", soun.sun_path, sfd);
 	}
 	
     }
Index: Doc/Makefile.in
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Makefile.in,v
retrieving revision 1.15
diff -u -r1.15 Makefile.in
--- Doc/Makefile.in	12 May 2002 18:51:47 -0000	1.15
+++ Doc/Makefile.in	22 Aug 2002 11:25:49 -0000
@@ -59,7 +59,8 @@
 Zsh/mod_computil.yo \
 Zsh/mod_deltochar.yo Zsh/mod_example.yo Zsh/mod_files.yo \
 Zsh/mod_mapfile.yo Zsh/mod_mathfunc.yo Zsh/mod_parameter.yo Zsh/mod_pcre.yo \
-Zsh/mod_sched.yo Zsh/mod_stat.yo Zsh/mod_termcap.yo Zsh/mod_terminfo.yo \
+Zsh/mod_sched.yo Zsh/mod_socket.yo \
+Zsh/mod_stat.yo Zsh/mod_termcap.yo Zsh/mod_terminfo.yo \
 Zsh/mod_zftp.yo Zsh/mod_zle.yo Zsh/mod_zleparameter.yo \
 Zsh/mod_zprof.yo Zsh/mod_zpty.yo Zsh/mod_zselect.yo \
 Zsh/mod_zutil.yo Zsh/mod_tcp.yo
Index: Doc/Zsh/mod_socket.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/mod_socket.yo,v
retrieving revision 1.1
diff -u -r1.1 mod_socket.yo
--- Doc/Zsh/mod_socket.yo	18 Aug 2002 02:12:40 -0000	1.1
+++ Doc/Zsh/mod_socket.yo	22 Aug 2002 11:25:49 -0000
@@ -62,3 +62,4 @@
 In order to elicit more verbose output, use tt(-v).
 )
 enditem()
+)


**********************************************************************
The information transmitted is intended only for the person or
entity to which it is addressed and may contain confidential 
and/or privileged material. 
Any review, retransmission, dissemination or other use of, or
taking of any action in reliance upon, this information by 
persons or entities other than the intended recipient is 
prohibited.  
If you received this in error, please contact the sender and 
delete the material from any computer.
**********************************************************************


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: PATCH: Unix domain socket module
  2002-08-22 11:54 ` Peter Stephenson
@ 2002-08-22 15:54   ` Clint Adams
  0 siblings, 0 replies; 3+ messages in thread
From: Clint Adams @ 2002-08-22 15:54 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: Zsh hackers list

> Minor tweaks.  `sun' is predefined on hardware from a certain vendor.
> The compiler didn't like the declaration `sockaddr_un 1'.

I should have expected that.

> Are you going to commit the terminfo fix for 4.0?  That looks quite
> serious.

I could have sworn that I did, but since CVS knows better, here's the
4.0 version I used.

--- tmp/zsh4.0/Src/Modules/terminfo.c	2002-08-15 17:29:00.000000000 -0400
+++ /tmp/zsh/Src/Modules/terminfo.c	2002-08-15 18:02:47.000000000 -0400
@@ -198,6 +198,8 @@
     {
 	pm->u.str = dupstring(tistr);
 	pm->flags |= PM_SCALAR;
+	pm->sets.cfn = NULL;
+	pm->gets.cfn = strgetfn;
     }
     else
     {


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2002-08-22 15:55 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-08-18  2:09 PATCH: Unix domain socket module Clint Adams
2002-08-22 11:54 ` Peter Stephenson
2002-08-22 15:54   ` Clint Adams

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).