Here are a couple of patches to implement the described fallback logic.

Right now we query HOME, TMPDIR and /tmp, in that order. However its trivial
to add more fallbacks (either from environment variables or fixed strings).

Cheers,

Alex


On Thu, Mar 19, 2009 at 1:09 PM, Julien Danjou <[email protected]> wrote:

> At 1237473819 time_t, Alex Cornejo wrote:
> > That function would then take care of all the fallback logic and print
> out
> > any warning/error messages. What do you think?
>
> Seems ok to me.
>
> Cheers,
> --
> Julien Danjou
> // ᐰ <[email protected]>   http://julien.danjou.info
> // 9A0D 5FD9 EB42 22F6 8974  C95C A462 B51E C2FE E5CD
> // When I get sad, I stop being sad and be awesome instead. True story.
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.9 (GNU/Linux)
>
> iEYEARECAAYFAknCfEEACgkQpGK1HsL+5c2XvQCdFT5rsskvLs35NIDX/ebPiofr
> WpwAoKvoLKxh2dGoUeATdo3QKBD00njT
> =BwEH
> -----END PGP SIGNATURE-----
>
>
From 37326fef6f997cc8da577e347bba6a09be34465a Mon Sep 17 00:00:00 2001
From: Alex Cornejo <[email protected]>
Date: Thu, 19 Mar 2009 18:39:53 -0400
Subject: [PATCH] Changed socket interface to support fallbacks.

Now we support a list of fallback targets when opening the socket, and
socket binding/connect is done inside socket.* instead of luaa.c or
awesome-client.c

Signed-off-by: Alex Cornejo <[email protected]>
---
 common/socket.c |   74 +++++++++++++++++++++++++++++++++++++++++-------------
 common/socket.h |    8 +++++-
 2 files changed, 63 insertions(+), 19 deletions(-)

diff --git a/common/socket.c b/common/socket.c
index 3fb9b68..f21eebb 100644
--- a/common/socket.c
+++ b/common/socket.c
@@ -24,6 +24,7 @@
 #include <errno.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#include <unistd.h>
 
 #include <xcb/xcb.h>
 
@@ -32,42 +33,79 @@
 
 #define CONTROL_UNIX_SOCKET_PATH ".awesome_ctl."
 
-/** Get a sockaddr_un struct with information feeded for opening a
- * communication to the awesome socket for given display
- * \param directory Where socket is created.
+/** Open a communication socket with awesome for a given display
+ * \param csfd the socket file descriptor
  * \param display the display number
- * \return sockaddr_un struct ready to be used or NULL if a problem occured
+ * \param mode the open mode, either Bind or Connect
+ * \return sockaddr_un struct ready to be used or NULL if a problem ocurred
  */
-struct sockaddr_un *
-socket_getaddr(const char *directory, const char *display)
+struct sockaddr_un *socket_open(int csfd, const char *display, const socket_mode_t mode)
 {
     char *host = NULL;
-    int screenp = 0, displayp = 0;
+    int screenp = 0, displayp = 0, i=0, status=-1;
     ssize_t path_len, len;
     struct sockaddr_un *addr;
+    const char *fallback[]={":HOME",":TMPDIR","/tmp",NULL}, *directory;
 
     addr = p_new(struct sockaddr_un, 1);
+    addr->sun_family = AF_UNIX;
 
     xcb_parse_display(NULL, &host, &displayp, &screenp);
-
     len = a_strlen(host);
 
-    /* + 2 for / and . and \0 */
-    path_len = snprintf(addr->sun_path, sizeof(addr->sun_path),
-                        "%s/" CONTROL_UNIX_SOCKET_PATH "%s%s%d",
-                        directory, len ? host : "", len ? "." : "",
-                        displayp);
+    while(fallback[i] != NULL && status == -1)
+    {
+        if(fallback[i][0] == ':')
+        {
+            directory = getenv(fallback[i]+1);
+            if(directory == NULL)
+            {
+                i++;
+                continue;
+            }
+        }
+        else
+            directory = fallback[i];
+        i++;
+
+        /* + 2 for / and . and \0 */
+        path_len = snprintf(addr->sun_path, sizeof(addr->sun_path),
+                            "%s/" CONTROL_UNIX_SOCKET_PATH "%s%s%d",
+                            directory, len ? host : "", len ? "." : "",
+                            displayp);
+        if(path_len < ssizeof(addr->sun_path))
+        {
+            if (mode == Bind)
+            {
+                if(!bind(csfd, (const struct sockaddr *) addr, SUN_LEN(addr)))
+                    status = 0;
+                else if(errno == EADDRINUSE)
+                {
+                    if(unlink(addr->sun_path))
+                        warn("error unlinking existing file: %s", strerror(errno));
+                    if(bind(csfd, (const struct sockaddr *) addr, SUN_LEN(addr)))
+                    {
+                        warn("error binding UNIX domain socket: %s", strerror(errno));
+                        break;
+                    }
+                }
+                else continue;
+            }
+            else if(!connect(csfd, (const struct sockaddr *)addr, sizeof(struct sockaddr_un)))
+                status = 0;
+        }
+        else
+            warn("error: path (using %s) of control UNIX domain socket is too long",directory);
+    }
 
     p_delete(&host);
 
-    if(path_len >= ssizeof(addr->sun_path))
+    if (status == -1)
     {
-        fprintf(stderr, "error: path of control UNIX domain socket is too long");
-        return NULL;
+        p_delete(&addr);
+        addr=NULL;
     }
 
-    addr->sun_family = AF_UNIX;
-
     return addr;
 }
 
diff --git a/common/socket.h b/common/socket.h
index 55e1127..29159bc 100644
--- a/common/socket.h
+++ b/common/socket.h
@@ -22,7 +22,13 @@
 #ifndef AWESOME_COMMON_SOCKET_H
 #define AWESOME_COMMON_SOCKET_H
 
-struct sockaddr_un * socket_getaddr(const char *, const char *);
+typedef enum
+{
+    Bind,
+    Connect
+} socket_mode_t;
+
+struct sockaddr_un *socket_open(const int, const char *, const socket_mode_t);
 int socket_getclient(void);
 
 #endif
-- 
1.5.6.3

From 9234eb63f6810c87133268997d13539496a2ce3e Mon Sep 17 00:00:00 2001
From: Alex Cornejo <[email protected]>
Date: Thu, 19 Mar 2009 18:40:44 -0400
Subject: [PATCH] Modified awesome-client and awesome to use new socket interface.


Signed-off-by: Alex Cornejo <[email protected]>
---
 awesome-client.c |   10 +---------
 luaa.c           |   22 +++-------------------
 2 files changed, 4 insertions(+), 28 deletions(-)

diff --git a/awesome-client.c b/awesome-client.c
index b2282a0..fcc7847 100644
--- a/awesome-client.c
+++ b/awesome-client.c
@@ -56,17 +56,9 @@ sockets_init(void)
     if((csfd = socket_getclient()) < 0)
         return false;
 
-    if(!(addr = socket_getaddr(getenv("HOME"), display)))
+    if(!(addr = socket_open(csfd, display, Connect)))
         return false;
 
-    if(connect(csfd, addr, sizeof(struct sockaddr_un)) == -1)
-    {
-        if(!(addr = socket_getaddr("/tmp", display)))
-            return false;
-        if(connect(csfd, addr, sizeof(struct sockaddr_un)) == -1)
-            return false;
-    }
-
     return true;
 }
 
diff --git a/luaa.c b/luaa.c
index 87df9f2..421041c 100644
--- a/luaa.c
+++ b/luaa.c
@@ -1115,31 +1115,15 @@ luaA_cs_init(void)
     if (csfd < 0 || fcntl(csfd, F_SETFD, FD_CLOEXEC) == -1)
         return;
 
-    addr = socket_getaddr(getenv("HOME"), getenv("DISPLAY"));
-
 /* Needed for some OSes like Solaris */
 #ifndef SUN_LEN
 #define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) + strlen ((ptr)->sun_path))
 #endif
 
-    if(bind(csfd, (const struct sockaddr *) addr, SUN_LEN(addr)))
-    {
-        if(errno == EADDRINUSE)
-        {
-            if(unlink(addr->sun_path))
-                warn("error unlinking existing file: %s", strerror(errno));
-            if(bind(csfd, (const struct sockaddr *) addr, SUN_LEN(addr)))
-                return warn("error binding UNIX domain socket: %s", strerror(errno));
-        }
-        else
-        {
-            addr = socket_getaddr("/tmp", getenv("DISPLAY"));
-            if (bind(csfd, (const struct sockaddr *) addr, SUN_LEN(addr)))
-                return warn("error binding UNIX domain socket: %s", strerror(errno));
-        }
-    }
-    listen(csfd, 10);
+    if(!(addr = socket_open(csfd, getenv("DISPLAY"), Bind)))
+        return;
 
+    listen(csfd, 10);
     ev_io_init(&csio, &luaA_conn_cb, csfd, EV_READ);
     ev_io_start(EV_DEFAULT_UC_ &csio);
     ev_unref(EV_DEFAULT_UC);
-- 
1.5.6.3

Reply via email to