From: Andre Noll Date: Mon, 30 Apr 2018 18:31:05 +0000 (+0200) Subject: Check for abstract sockets only once. X-Git-Tag: v0.6.3~84 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=52cb435d3d628d27fa781b31519470eb5ef70a4a Check for abstract sockets only once. In net.c there is a static variable which is supposed to cache whether the abstract local socket namespace is supported. This variable is pointless because it is only ever set by command handlers, which exit after the command completed. Hence the command handler process of each subsequent afs command checks again. To make the caching work as intended we must initialize the variable in the *parent* process. The parent process, however, does not create any local sockets. This patch changes init_unix_addr() to initialize the variable without creating a socket when NULL is passed as the name parameter. The server process passes NULL to initialize the static variable while command handlers pass non NULL. --- diff --git a/net.c b/net.c index ba19408e..d1dcba0a 100644 --- a/net.c +++ b/net.c @@ -886,14 +886,13 @@ int dccp_available_ccids(uint8_t **ccid_array) * The first call to this function tries to bind a socket to the abstract name * space. The result of this test is stored in a static variable. Subsequent * calls read this variable and create abstract sockets on systems that support - * them. + * them. If a NULL pointer is passed as the name, the function only + * initializes the static variable. */ static int init_unix_addr(struct sockaddr_un *u, const char *name) { static int use_abstract; - if (strlen(name) + 1 >= UNIX_PATH_MAX) - return -E_NAME_TOO_LONG; memset(u->sun_path, 0, UNIX_PATH_MAX); u->sun_family = PF_UNIX; if (use_abstract == 0) { /* executed only once */ @@ -907,6 +906,10 @@ static int init_unix_addr(struct sockaddr_un *u, const char *name) PARA_NOTICE_LOG("%susing abstract socket namespace\n", use_abstract == 1? "" : "not "); } + if (!name) + return 0; + if (strlen(name) + 1 >= UNIX_PATH_MAX) + return -E_NAME_TOO_LONG; strcpy(u->sun_path + (use_abstract == 1? 1 : 0), name); return 1; } @@ -931,7 +934,7 @@ int create_local_socket(const char *name) int fd, ret; ret = init_unix_addr(&unix_addr, name); - if (ret < 0) + if (ret <= 0) /* error, or name was NULL */ return ret; ret = socket(PF_UNIX, SOCK_STREAM, 0); if (ret < 0) diff --git a/server.c b/server.c index eee0a412..6370cefd 100644 --- a/server.c +++ b/server.c @@ -488,6 +488,13 @@ static void init_server_command_task(struct server_command_task *sct, .post_select = command_post_select, .context = sct, }, &sched); + /* + * Detect whether the abstract Unix domain socket space is supported, + * but do not create the socket. We check this once in server context + * so that the command handlers inherit this bit of information and + * don't need to check again. + */ + create_local_socket(NULL); return; err: PARA_EMERG_LOG("%s\n", para_strerror(-ret));