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)
147 ERR("local connection failed: %s", strerror(errno));
151 svr->path = strdup(buf);
155 if (svr->type & ECORE_CON_SSL)
156 ecore_con_ssl_server_init(svr);
159 ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
160 cb_done, svr, NULL, NULL);
161 if (!svr->fd_handler)
164 if (!svr->delete_me) ecore_con_event_server_add(svr);
171 ecore_con_local_listen(
172 Ecore_Con_Server *svr,
174 cb_listen)(void *data,
180 #ifdef HAVE_LOCAL_SOCKETS
182 struct sockaddr_un socket_unix;
190 mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
192 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
194 homedir = getenv("HOME");
196 homedir = getenv("TMP");
201 mask = S_IRUSR | S_IWUSR | S_IXUSR;
202 snprintf(buf, sizeof(buf), "%s/.ecore", homedir);
203 if (stat(buf, &st) < 0)
206 snprintf(buf, sizeof(buf), "%s/.ecore/%s", homedir, svr->name);
207 if (stat(buf, &st) < 0)
216 mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
218 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
221 if (svr->name[0] == '/')
238 "/tmp/.ecore_service|%s|%i",
242 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
243 strncpy(buf, svr->name,
248 svr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
252 if (fcntl(svr->fd, F_SETFL, O_NONBLOCK) < 0)
255 if (fcntl(svr->fd, F_SETFD, FD_CLOEXEC) < 0)
260 if (setsockopt(svr->fd, SOL_SOCKET, SO_LINGER, (const void *)&lin,
261 sizeof(struct linger)) < 0)
264 socket_unix.sun_family = AF_UNIX;
265 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
267 #ifdef HAVE_ABSTRACT_SOCKETS
268 /* . is a placeholder */
269 snprintf(socket_unix.sun_path, sizeof(socket_unix.sun_path), ".%s",
271 /* first char null indicates abstract namespace */
272 socket_unix.sun_path[0] = '\0';
273 socket_unix_len = LENGTH_OF_ABSTRACT_SOCKADDR_UN(&socket_unix,
276 ERR("Your system does not support abstract sockets!");
282 strncpy(socket_unix.sun_path, buf, sizeof(socket_unix.sun_path));
283 socket_unix_len = LENGTH_OF_SOCKADDR_UN(&socket_unix);
286 if (bind(svr->fd, (struct sockaddr *)&socket_unix, socket_unix_len) < 0)
288 if ((((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) ||
289 ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)) &&
290 (connect(svr->fd, (struct sockaddr *)&socket_unix,
291 socket_unix_len) < 0) &&
298 if (listen(svr->fd, 4096) < 0)
301 svr->path = strdup(buf);
306 ecore_main_fd_handler_add(svr->fd, ECORE_FD_READ,
307 cb_listen, svr, NULL, NULL);
309 if (!svr->fd_handler)
317 #endif /* HAVE_LOCAL_SOCKETS */