12 #ifdef HAVE_SYS_SOCKET_H
13 # include <sys/socket.h>
20 #ifdef HAVE_WS2TCPIP_H
21 # include <ws2tcpip.h>
25 #include <ecore_private.h>
27 #include "Ecore_Con.h"
28 #include "ecore_con_private.h"
30 #define LENGTH_OF_SOCKADDR_UN(s) (strlen((s)->sun_path) + \
31 (size_t)(((struct sockaddr_un *)NULL)-> \
33 #define LENGTH_OF_ABSTRACT_SOCKADDR_UN(s, path) (strlen(path) + 1 + \
34 (size_t)(((struct sockaddr_un \
37 static int _ecore_con_local_init_count = 0;
40 ecore_con_local_init(void)
42 if (++_ecore_con_local_init_count != 1)
43 return _ecore_con_local_init_count;
45 return _ecore_con_local_init_count;
49 ecore_con_local_shutdown(void)
51 if (--_ecore_con_local_init_count != 0)
52 return _ecore_con_local_init_count;
54 return _ecore_con_local_init_count;
58 ecore_con_local_connect(Ecore_Con_Server *svr,
59 Eina_Bool (*cb_done)(void *data, Ecore_Fd_Handler *fd_handler),
60 void *data __UNUSED__)
62 #ifndef HAVE_LOCAL_SOCKETS
66 struct sockaddr_un socket_unix;
71 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
73 homedir = getenv("HOME");
75 homedir = getenv("TMP");
80 snprintf(buf, sizeof(buf), "%s/.ecore/%s/%i", homedir, svr->name,
83 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
87 if (svr->name[0] == '/')
88 strncpy(buf, svr->name, sizeof(buf));
90 snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s", svr->name);
96 snprintf(buf, sizeof(buf), "%s|%i", svr->name,
99 snprintf(buf, sizeof(buf), "/tmp/.ecore_service|%s|%i",
104 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
105 strncpy(buf, svr->name,
108 svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
112 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
115 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0)
118 if (setsockopt(svr->fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&curstate,
119 sizeof(curstate)) < 0)
122 socket_unix.sun_family = AF_UNIX;
124 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
126 #ifdef HAVE_ABSTRACT_SOCKETS
127 /* copy name insto sun_path, prefixed by null to indicate abstract namespace */
128 snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s",
130 socket_unix.sun_path[0] = '\0';
131 socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix,
134 WRN("Your system does not support abstract sockets!");
140 strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
141 socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
144 if (connect(svr->fd, (struct sockaddr *)&socket_unix,
145 socket_unix_len) < 0)
148 svr->path = strdup(buf);
152 if (svr->type & ECORE_CON_SSL)
153 ecore_con_ssl_server_init(svr);
156 ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
157 cb_done, svr, NULL, NULL);
158 if (!svr->fd_handler)
161 if (!svr->delete_me) ecore_con_event_server_add(svr);
168 ecore_con_local_listen(
169 Ecore_Con_Server *svr,
171 cb_listen)(void *data,
177 #ifdef HAVE_LOCAL_SOCKETS
179 struct sockaddr_un socket_unix;
187 mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
189 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
191 homedir = getenv("HOME");
193 homedir = getenv("TMP");
198 mask = S_IRUSR | S_IWUSR | S_IXUSR;
199 snprintf(buf, sizeof(buf), "%s/.ecore", homedir);
200 if (stat(buf, &st) < 0)
203 snprintf(buf, sizeof(buf), "%s/.ecore/%s", homedir, svr->name);
204 if (stat(buf, &st) < 0)
213 mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
215 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
218 if (svr->name[0] == '/')
235 "/tmp/.ecore_service|%s|%i",
239 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
240 strncpy(buf, svr->name,
245 svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
249 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
252 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0)
257 if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin,
258 sizeof(struct linger)) < 0)
261 socket_unix.sun_family = AF_UNIX;
262 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
264 #ifdef HAVE_ABSTRACT_SOCKETS
265 /* . is a placeholder */
266 snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s",
268 /* first char null indicates abstract namespace */
269 socket_unix.sun_path[0] = '\0';
270 socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix,
273 ERR("Your system does not support abstract sockets!");
279 strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
280 socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
283 if (bind(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
285 if ((((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) ||
286 ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)) &&
287 (connect(svr->fd, (struct sockaddr *)&socket_unix,
288 socket_unix_len) < 0) &&
295 if (listen(svr->fd, 4096) < 0)
298 svr->path = strdup(buf);
303 ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
304 cb_listen, svr, NULL, NULL);
306 if (!svr->fd_handler)
314 #endif /* HAVE_LOCAL_SOCKETS */