diff -ur memcached-1.1.12-orig/memcached.c memcached-1.1.12/memcached.c --- memcached-1.1.12-orig/memcached.c 2005-04-04 19:10:26.000000000 -0500 +++ memcached-1.1.12/memcached.c 2006-07-26 12:00:12.000000000 -0500 @@ -21,6 +21,7 @@ #include #include #include +#include #include #include /* some POSIX systems need the following definition @@ -93,6 +94,7 @@ settings.verbose = 0; settings.oldest_live = 0; settings.evict_to_free = 1; /* push old items out of cache when memory runs out */ + settings.socketpath = NULL; /* by default, not using a unix socket */ } conn **freeconns; @@ -1172,6 +1174,64 @@ return sfd; } +int new_socket_unix(void) { + int sfd; + int flags; + + if ((sfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + perror("socket()"); + return -1; + } + + if ((flags = fcntl(sfd, F_GETFL, 0)) < 0 || + fcntl(sfd, F_SETFL, flags | O_NONBLOCK) < 0) { + perror("setting O_NONBLOCK"); + close(sfd); + return -1; + } + return sfd; +} + +int server_socket_unix(char *path) { + int sfd; + struct linger ling = {0, 0}; + struct sockaddr_un addr; + int flags =1; + + if (!path) { + return -1; + } + + if ((sfd = new_socket_unix()) == -1) { + return -1; + } + + setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags)); + setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, &flags, sizeof(flags)); + setsockopt(sfd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling)); + + /* + * the memset call clears nonstandard fields in some impementations + * that otherwise mess things up. + */ + memset(&addr, 0, sizeof(addr)); + + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, path); + if (bind(sfd, (struct sockaddr *) &addr, sizeof(addr)) == -1) { + perror("bind()"); + close(sfd); + return -1; + } + if (listen(sfd, 1024) == -1) { + perror("listen()"); + close(sfd); + return -1; + } + return sfd; +} + + /* invoke right before gdb is called, on assert */ void pre_gdb () { int i = 0; @@ -1221,6 +1281,7 @@ void usage(void) { printf(PACKAGE " " VERSION "\n"); printf("-p port number to listen on\n"); + printf("-s unix socket path to listen on (disables network support)\n"); printf("-l interface to listen on, default is INDRR_ANY\n"); printf("-d run as a daemon\n"); printf("-r maximize core file limit\n"); @@ -1354,11 +1415,14 @@ settings_init(); /* process arguments */ - while ((c = getopt(argc, argv, "p:m:Mc:khirvdl:u:P:")) != -1) { + while ((c = getopt(argc, argv, "p:s:m:Mc:khirvdl:u:P:")) != -1) { switch (c) { case 'p': settings.port = atoi(optarg); break; + case 's': + settings.socketpath = optarg; + break; case 'm': settings.maxbytes = atoi(optarg)*1024*1024; break; @@ -1461,7 +1525,11 @@ */ /* create the listening socket and bind it */ - l_socket = server_socket(settings.port); + if (settings.socketpath) { + l_socket = server_socket_unix(settings.socketpath); + } else { + l_socket = server_socket(settings.port); + } if (l_socket == -1) { fprintf(stderr, "failed to listen\n"); exit(1); diff -ur memcached-1.1.12-orig/memcached.h memcached-1.1.12/memcached.h --- memcached-1.1.12-orig/memcached.h 2005-04-04 19:14:55.000000000 -0500 +++ memcached-1.1.12/memcached.h 2006-07-26 11:50:36.000000000 -0500 @@ -31,6 +31,7 @@ int verbose; time_t oldest_live; /* ignore existing items older than this */ int evict_to_free; + char *socketpath; /* path to unix socket if using local socket */ }; extern struct stats stats;