Code

added support for unix domain sockets
authorMax Kellermann <max@duempel.org>
Mon, 15 Sep 2008 11:27:33 +0000 (13:27 +0200)
committerMax Kellermann <max@duempel.org>
Mon, 15 Sep 2008 11:27:33 +0000 (13:27 +0200)
If a host name starts with a slash, it is assumed to be a unix domain
socket path.  The port is ignored.  This code is disabled on WIN32,
until someone tests it.

src/libmpdclient.c

index a52ce23ca1e4c177ea901288ce744f2b2a8f97ed..48d7d4f5f71d6f99b59f508121fde22578b6b0ed 100644 (file)
 #  include <netdb.h>
 #endif
 
+#ifndef WIN32
+#include <sys/un.h>
+#endif
+
 #ifndef MSG_DONTWAIT
 #  define MSG_DONTWAIT 0
 #endif
@@ -328,6 +332,53 @@ static int mpd_parseWelcome(mpd_Connection * connection, const char * host, int
        return 0;
 }
 
+#ifndef WIN32
+static int mpd_connect_un(mpd_Connection * connection,
+                         const char * host, float timeout)
+{
+       int error, flags;
+       size_t path_length;
+       struct sockaddr_un sun;
+
+       path_length = strlen(host);
+       if (path_length >= sizeof(sun.sun_path)) {
+               strcpy(connection->errorStr, "unix socket path is too long");
+               connection->error = MPD_ERROR_UNKHOST;
+               return -1;
+       }
+
+       sun.sun_family = AF_UNIX;
+       memcpy(sun.sun_path, host, path_length + 1);
+
+       connection->sock = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (connection->sock < 0) {
+               strcpy(connection->errorStr, "problems creating socket");
+               connection->error = MPD_ERROR_SYSTEM;
+               return -1;
+       }
+
+       mpd_setConnectionTimeout(connection, timeout);
+
+       flags = fcntl(connection->sock, F_GETFL, 0);
+       fcntl(connection->sock, F_SETFL, flags | O_NONBLOCK);
+
+       error = connect(connection->sock, (struct sockaddr*)&sun, sizeof(sun));
+       if (error < 0) {
+               /* try the next address family */
+               close(connection->sock);
+               connection->sock = 0;
+
+               snprintf(connection->errorStr,MPD_BUFFER_MAX_LENGTH,
+                        "problems connecting to \"%s\": %s",
+                        host, strerror(errno));
+               connection->error = MPD_ERROR_CONNPORT;
+               return -1;
+       }
+
+       return 0;
+}
+#endif /* WIN32 */
+
 mpd_Connection * mpd_newConnection(const char * host, int port, float timeout) {
        int err;
        char * rt;
@@ -350,7 +401,13 @@ mpd_Connection * mpd_newConnection(const char * host, int port, float timeout) {
        if (winsock_dll_error(connection))
                return connection;
 
-       if (mpd_connect(connection, host, port, timeout) < 0)
+#ifndef WIN32
+       if (host[0] == '/')
+               err = mpd_connect_un(connection, host, timeout);
+       else
+#endif
+               err = mpd_connect(connection, host, port, timeout);
+       if (err < 0)
                return connection;
 
        while(!(rt = strstr(connection->buffer,"\n"))) {