I tried to give adding support for Unix domain sockets in pil a go, but
I couldn't make functional code yet because I don't really grasp
completely how the macro beast language pil32 is written in works (I
wrote all the docs though).
The changes would be basically to add a function called 'sock, which
will create a Unix socket at a given path, and modify 'connect and 'udp
to accept a Unix socket path in the position of the port/service if the
given host name is NIL.
The patch should be attached to this message, if it isn't I pasted a
copy here: http://2.71828.com.ar/p/c;QYLoXQ
I'd thank any help to get those functions working as I intend.
Cheers,
José
diff -r 425552fd43a8 doc/refA.html
--- a/doc/refA.html Fri Aug 03 09:10:32 2012 +0200
+++ b/doc/refA.html Sat Sep 01 16:58:35 2012 -0300
@@ -129,7 +129,8 @@
<dt><a name="accept"><code>(accept 'cnt) -> cnt | NIL</code></a>
<dd>Accepts a connection on descriptor <code>cnt</code> (as received by <code><a
-href="refP.html#port">port</a></code>), and returns the new socket descriptor
+href="refP.html#port">port</a></code> or <code><a
+href="refS.html#sock">sock</a></code>), and returns the new socket descriptor
<code>cnt</code>. The global variable <code>*Adr</code> is set to the IP address
of the client. See also <code><a href="refL.html#listen">listen</a></code>,
<code><a href="refC.html#connect">connect</a></code> and <code><a
diff -r 425552fd43a8 doc/refC.html
--- a/doc/refC.html Fri Aug 03 09:10:32 2012 +0200
+++ b/doc/refC.html Sat Sep 01 16:58:35 2012 -0300
@@ -536,21 +536,25 @@
-> 2
</code></pre>
-<dt><a name="connect"><code>(connect 'any1 'any2) -> cnt | NIL</code></a>
+<dt><a name="connect"><code>(connect ['any1|'NIL] 'any2) -> cnt | NIL</code></a>
<dd>Tries to establish a TCP/IP connection to a server listening at host
<code>any1</code>, port <code>any2</code>. <code>any1</code> may be either a
hostname or a standard internet address in numbers-and-dots/colons notation
(IPv4/IPv6). <code>any2</code> may be either a port number or a service name.
Returns a socket descriptor <code>cnt</code>, or <code>NIL</code> if the
-connection cannot be established. See also <code><a
-href="refL.html#listen">listen</a></code> and <code><a
-href="refU.html#udp">udp</a></code>.
+connection cannot be established. If the first argument
+is <code>NIL</code>, then it attempts to establish the connection with
+a unix domain socket located in <code>any2</code>. See
+also <code><a href="refL.html#listen">listen</a></code>
+and <code><a href="refU.html#udp">udp</a></code>.
<pre><code>
: (connect "localhost" 4444)
-> 3
: (connect "some.host.org" "http")
-> 4
+: (connect NIL (pil "foo.sock"))
+-> 5
</code></pre>
<dt><a name="cons"><code>(cons 'any ['any ..]) -> lst</code></a>
diff -r 425552fd43a8 doc/refL.html
--- a/doc/refL.html Fri Aug 03 09:10:32 2012 +0200
+++ b/doc/refL.html Sat Sep 01 16:58:35 2012 -0300
@@ -361,7 +361,9 @@
<dt><a name="listen"><code>(listen 'cnt1 ['cnt2]) -> cnt | NIL</code></a>
<dd>Listens at a socket descriptor <code>cnt1</code> (as received by <code><a
-href="refP.html#port">port</a></code>) for an incoming connection, and returns
+href="refP.html#port">port</a></code>
+or <code><a href="refS.html#sock">sock</a></code>) for an incoming
+connection, and returns
the new socket descriptor <code>cnt</code>. While waiting for a connection, a
<code>select</code> system call is executed for all file descriptors and timers
in the <code>VAL</code> of the global variable <code><a
diff -r 425552fd43a8 doc/refS.html
--- a/doc/refS.html Fri Aug 03 09:10:32 2012 +0200
+++ b/doc/refS.html Sat Sep 01 16:58:35 2012 -0300
@@ -325,7 +325,7 @@
: (?
@Nr (2 . 5) # Select all items with numbers between 2 and 5
@Sup "Active" # and suppliers matching "Active"
- (select (@Item) # Bind results to '@Item"
+ (select (@Item) # Bind results to '@Item
((nr +Item @Nr) (nm +CuSu @Sup (sup +Item))) # Generator clauses
(range @Nr @Item nr) # Filter clauses
(part @Sup @Item sup nm) ) )
@@ -508,6 +508,19 @@
-> "a"
</code></pre>
+<dt><a name="sock"><code>(sock ['T] 'any) -> cnt</code></a>
+<dd>Opens a TCP Unix domain socket at the path <code>any</code> (or a
+UDP socket if the first argument is <code>T</code>), and returns a
+socket descriptor suitable as an argument
+for <code><a href="refL.html#listen">listen</a></code>
+or <code><a href="refA.html#accept">accept</a></code>
+(or <code><a href="refU.html#udp">udp</a></code>, respectively).
+
+<pre><code>
+: (sock (pil "foo.sock")) # Open a socket in ~/.pil/foo.sock
+-> 4
+</code></pre>
+
<dt><a name="solve"><code>(solve 'lst [. prg]) -> lst</code></a>
<dd>Evaluates a <a href="ref.html#pilog">Pilog</a> query and, returns the list
of result sets. If <code>prg</code> is given, it is executed for each result
diff -r 425552fd43a8 doc/refU.html
--- a/doc/refU.html Fri Aug 03 09:10:32 2012 +0200
+++ b/doc/refU.html Sat Sep 01 16:58:35 2012 -0300
@@ -93,15 +93,18 @@
-> T
</code></pre>
-<dt><a name="udp"><code>(udp 'any1 'any2 'any3) -> any</code></a>
+<dt><a name="udp"><code>(udp ['any1|'NIL] 'any2 'any3) -> any</code></a>
<dt><code>(udp 'cnt) -> any</code>
<dd>Simple unidirectional sending/receiving of UDP packets. In the first form,
<code>any3</code> is sent to a UDP server listening at host <code>any1</code>,
-port <code>any2</code>. In the second form, one item is received from a UDP
-socket <code>cnt</code>, established with <code><a
-href="refP.html#port">port</a></code>. See also <code><a
-href="refL.html#listen">listen</a></code> and <code><a
-href="refC.html#connect">connect</a></code>.
+port <code>any2</code>. If the first parameter is <code>NIL</code>,
+the data will be sent to a unix socket located
+in <code>any2</code>. In the second form, one item is received from a
+UDP socket <code>cnt</code>, established
+with <code><a href="refP.html#port">port</a></code>
+or <code><a href="refS.html#sock">sock</a></code>. See
+also <code><a href="refL.html#listen">listen</a></code>
+and <code><a href="refC.html#connect">connect</a></code>.
<pre><code>
# First session
diff -r 425552fd43a8 src/net.c
--- a/src/net.c Fri Aug 03 09:10:32 2012 +0200
+++ b/src/net.c Sat Sep 01 16:58:35 2012 -0300
@@ -62,6 +62,31 @@
return boxCnt(sd);
}
+// (sock ['T] 'any) -> cnt
+any doSock(any ex) {
+ any x, y;
+ int type, sd, n;
+ unsigned short port;
+ char* nm;
+ struct sockaddr_un addr;
+ x = cdr(ex);
+ type = SOCK_STREAM;
+ if ((y = EVAL(car(x))) == T)
+ type = SOCK_DGRAM, x = cdr(x), y = EVAL(car(x));
+ if ((sd = socket(AF_UNIX, type, 0)) < 0)
+ ipErr(ex, "socket");
+ closeOnExec(ex, sd);
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ // nm = /* A WAY TO GET THE PARAM'S SYMBOL NAME */
+ strncpy(addr.sun_path, nm, sizeof(addr.sun_path)-1);
+ if (bind(sd, (struct sockaddr*)&addr, sizeof(addr)) < 0)
+ close(sd), ipErr(ex, "bind");
+ if (type == SOCK_STREAM && listen(sd,5) < 0)
+ close(sd), ipErr(ex, "listen");
+ return boxCnt(sd);
+}
+
static any tcpAccept(int sd) {
int i, f, sd2;
char s[INET6_ADDRSTRLEN];
@@ -139,13 +164,13 @@
return getaddrinfo(nd, sv, &hints, &lst)? NULL : lst;
}
-// (connect 'any1 'any2) -> cnt | NIL
+// (connect ['any1|'NIL] 'any2) -> cnt | NIL
any doConnect(any ex) {
struct addrinfo *lst, *p;
any port;
int sd;
cell c1;
-
+ /* MAKE IT SO IF FIRST PARAM IS NIL 'any2 IS SUN_PATH */
Push(c1, evSym(cdr(ex)));
port = evSym(cddr(ex));
for (p = lst = server(SOCK_STREAM, Pop(c1), port); p; p = p->ai_next) {
@@ -179,7 +204,7 @@
return *UdpPtr++;
}
-// (udp 'any1 'any2 'any3) -> any
+// (udp ['any1|'NIL] 'any2 'any3) -> any
// (udp 'cnt) -> any
any doUdp(any ex) {
any x, y;
@@ -187,7 +212,7 @@
struct addrinfo *lst, *p;
int sd;
byte buf[UDPMAX];
-
+ /* ALSO MAKE IT SO IF FIRST PARAM IS NIL, 'any2 IS SUN_PATH */
x = cdr(ex), data(c1) = EVAL(car(x));
if (!isCell(x = cdr(x))) {
if (recv((int)xCnt(ex, data(c1)), buf, UDPMAX, 0) < 0)