summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGustavo Sverzut Barbieri <barbieri@profusion.mobi>2016-08-24 12:34:59 -0300
committerGustavo Sverzut Barbieri <barbieri@profusion.mobi>2016-08-24 12:34:59 -0300
commite3ee477140bb760dfffc8e32c0a3e9a961664c3d (patch)
tree242f5cfd393e9550a9de2f8c4fec5e360ce95035 /src
parent164d9ddfde00800ce5d68c22b581ffc5add91bbc (diff)
efl_net: better handling for SOCK_CLOEXEC.
On systems where SOCK_CLOEXEC is supported, give it to socket() and if accept4() is supported, then use it as well. Otherwise revert to fcntl().
Diffstat (limited to 'src')
-rw-r--r--src/lib/ecore_con/ecore_con.c29
-rw-r--r--src/lib/ecore_con/ecore_con_private.h2
-rw-r--r--src/lib/ecore_con/efl_net_dialer_tcp.c11
-rw-r--r--src/lib/ecore_con/efl_net_server_fd.c43
-rw-r--r--src/lib/ecore_con/efl_net_server_tcp.c12
5 files changed, 69 insertions, 28 deletions
diff --git a/src/lib/ecore_con/ecore_con.c b/src/lib/ecore_con/ecore_con.c
index e040a71..8340c3d 100644
--- a/src/lib/ecore_con/ecore_con.c
+++ b/src/lib/ecore_con/ecore_con.c
@@ -3036,3 +3036,32 @@ efl_net_ip_port_fmt(char *buf, int buflen, const struct sockaddr *addr)
3036 3036
3037 return EINA_TRUE; 3037 return EINA_TRUE;
3038} 3038}
3039
3040int
3041efl_net_socket4(int domain, int type, int protocol, Eina_Bool close_on_exec)
3042{
3043 int fd;
3044
3045#ifdef SOCK_CLOEXEC
3046 if (close_on_exec) type |= SOCK_CLOEXEC;
3047#endif
3048
3049 fd = socket(domain, type, protocol);
3050 if (fd < 0) return fd;
3051
3052#ifndef SOCK_CLOEXEC
3053 if (close_on_exec)
3054 {
3055 if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
3056 {
3057 int errno_bkp = errno;
3058 ERR("fcntl(%d, F_SETFD, FD_CLOEXEC): %s", fd, strerror(errno));
3059 close(fd);
3060 errno = errno_bkp;
3061 return -1;
3062 }
3063 }
3064#endif
3065
3066 return fd;
3067}
diff --git a/src/lib/ecore_con/ecore_con_private.h b/src/lib/ecore_con/ecore_con_private.h
index 089f864..e2fab7a 100644
--- a/src/lib/ecore_con/ecore_con_private.h
+++ b/src/lib/ecore_con/ecore_con_private.h
@@ -375,4 +375,6 @@ void ecore_con_mempool_shutdown(void);
375 375
376Eina_Bool efl_net_ip_port_fmt(char *buf, int buflen, const struct sockaddr *addr); 376Eina_Bool efl_net_ip_port_fmt(char *buf, int buflen, const struct sockaddr *addr);
377 377
378int efl_net_socket4(int domain, int type, int protocol, Eina_Bool close_on_exec);
379
378#endif 380#endif
diff --git a/src/lib/ecore_con/efl_net_dialer_tcp.c b/src/lib/ecore_con/efl_net_dialer_tcp.c
index b835d93..88f78fe 100644
--- a/src/lib/ecore_con/efl_net_dialer_tcp.c
+++ b/src/lib/ecore_con/efl_net_dialer_tcp.c
@@ -51,7 +51,7 @@ _efl_net_dialer_tcp_efl_net_dialer_dial(Eo *o, Efl_Net_Dialer_Tcp_Data *pd EINA_
51{ 51{
52 struct sockaddr_storage addr = {}; 52 struct sockaddr_storage addr = {};
53 char *str, *host, *port; 53 char *str, *host, *port;
54 int r, fd, extra_flags = 0; 54 int r, fd;
55 socklen_t addrlen; 55 socklen_t addrlen;
56 char buf[INET6_ADDRSTRLEN + sizeof("[]:65536")]; 56 char buf[INET6_ADDRSTRLEN + sizeof("[]:65536")];
57 57
@@ -118,14 +118,11 @@ _efl_net_dialer_tcp_efl_net_dialer_dial(Eo *o, Efl_Net_Dialer_Tcp_Data *pd EINA_
118 efl_event_callback_call(o, EFL_NET_DIALER_EVENT_RESOLVED, NULL); 118 efl_event_callback_call(o, EFL_NET_DIALER_EVENT_RESOLVED, NULL);
119 } 119 }
120 120
121 if (efl_net_socket_fd_close_on_exec_get(o)) 121 fd = efl_net_socket4(addr.ss_family, SOCK_STREAM, IPPROTO_TCP, efl_net_socket_fd_close_on_exec_get(o));
122 extra_flags |= SOCK_CLOEXEC;
123
124 fd = socket(addr.ss_family, SOCK_STREAM | extra_flags, IPPROTO_TCP);
125 if (fd < 0) 122 if (fd < 0)
126 { 123 {
127 ERR("socket(%d, SOCK_STREAM | %#x, IPPROTO_TCP): %s", 124 ERR("socket(%d, SOCK_STREAM, IPPROTO_TCP): %s",
128 addr.ss_family, extra_flags, strerror(errno)); 125 addr.ss_family, strerror(errno));
129 return errno; 126 return errno;
130 } 127 }
131 128
diff --git a/src/lib/ecore_con/efl_net_server_fd.c b/src/lib/ecore_con/efl_net_server_fd.c
index 06af641..0365669 100644
--- a/src/lib/ecore_con/efl_net_server_fd.c
+++ b/src/lib/ecore_con/efl_net_server_fd.c
@@ -32,6 +32,32 @@ typedef struct _Efl_Net_Server_Fd_Data
32 Eina_Bool reuse_port; 32 Eina_Bool reuse_port;
33} Efl_Net_Server_Fd_Data; 33} Efl_Net_Server_Fd_Data;
34 34
35static int
36efl_net_accept4(int fd, struct sockaddr *addr, socklen_t *addrlen, Eina_Bool close_on_exec)
37{
38#ifdef HAVE_ACCEPT4
39 int flags = 0;
40 if (close_on_exec) flags |= SOCK_CLOEXEC;
41 return accept4(fd, addr, addrlen, flags);
42#else
43 int client = accept(fd, addr, addrlen);
44 if (client < 0) return client;
45
46 if (close_on_exec)
47 {
48 if (fcntl(client, F_SETFD, FD_CLOEXEC) < 0)
49 {
50 int errno_bkp = errno;
51 ERR("fcntl(%d, F_SETFD, FD_CLOEXEC): %s", client, strerror(errno));
52 close(client);
53 errno = errno_bkp;
54 return -1;
55 }
56 }
57 return client;
58#endif
59}
60
35static void 61static void
36_efl_net_server_fd_event_read(void *data EINA_UNUSED, const Eo_Event *event) 62_efl_net_server_fd_event_read(void *data EINA_UNUSED, const Eo_Event *event)
37{ 63{
@@ -39,7 +65,7 @@ _efl_net_server_fd_event_read(void *data EINA_UNUSED, const Eo_Event *event)
39 unsigned int count, limit; 65 unsigned int count, limit;
40 Eina_Bool reject_excess, do_reject = EINA_FALSE; 66 Eina_Bool reject_excess, do_reject = EINA_FALSE;
41 struct sockaddr_storage addr; 67 struct sockaddr_storage addr;
42 int client, fd, flags = 0; 68 int client, fd;
43 socklen_t addrlen; 69 socklen_t addrlen;
44 70
45 count = efl_net_server_clients_count_get(o); 71 count = efl_net_server_clients_count_get(o);
@@ -57,15 +83,9 @@ _efl_net_server_fd_event_read(void *data EINA_UNUSED, const Eo_Event *event)
57 83
58 fd = efl_loop_fd_get(o); 84 fd = efl_loop_fd_get(o);
59 85
60 if (efl_net_server_fd_close_on_exec_get(o))
61 flags |= SOCK_CLOEXEC;
62
63 addrlen = sizeof(addr); 86 addrlen = sizeof(addr);
64#ifdef HAVE_ACCEPT4 87 client = efl_net_accept4(fd, (struct sockaddr *)&addr, &addrlen,
65 client = accept4(fd, (struct sockaddr *)&addr, &addrlen, flags); 88 efl_net_server_fd_close_on_exec_get(o));
66#else
67 client = accept(fd, (struct sockaddr *)&addr, &addrlen);
68#endif
69 if (client < 0) 89 if (client < 0)
70 { 90 {
71 Eina_Error err = errno; 91 Eina_Error err = errno;
@@ -74,11 +94,6 @@ _efl_net_server_fd_event_read(void *data EINA_UNUSED, const Eo_Event *event)
74 return; 94 return;
75 } 95 }
76 96
77#ifndef HAVE_ACCEPT4
78 if (fcntl(fd, F_SETFD, flags) < 0)
79 ERR("fcntl(%d, F_SETFD, %#x): %s", fd, flags, strerror(errno));
80#endif
81
82 if (do_reject) 97 if (do_reject)
83 efl_net_server_fd_client_reject(o, client); 98 efl_net_server_fd_client_reject(o, client);
84 else 99 else
diff --git a/src/lib/ecore_con/efl_net_server_tcp.c b/src/lib/ecore_con/efl_net_server_tcp.c
index 25bfb01..b904cbb 100644
--- a/src/lib/ecore_con/efl_net_server_tcp.c
+++ b/src/lib/ecore_con/efl_net_server_tcp.c
@@ -34,7 +34,7 @@ _efl_net_server_tcp_efl_net_server_serve(Eo *o, void *pd EINA_UNUSED, const char
34{ 34{
35 struct sockaddr_storage addr = {}; 35 struct sockaddr_storage addr = {};
36 char *str, *host, *port; 36 char *str, *host, *port;
37 int r, fd, extra_flags = 0; 37 int r, fd;
38 socklen_t addrlen; 38 socklen_t addrlen;
39 char buf[INET6_ADDRSTRLEN + sizeof("[]:65536")]; 39 char buf[INET6_ADDRSTRLEN + sizeof("[]:65536")];
40 Eina_Error err = 0; 40 Eina_Error err = 0;
@@ -97,15 +97,13 @@ _efl_net_server_tcp_efl_net_server_serve(Eo *o, void *pd EINA_UNUSED, const char
97 if (efl_net_ip_port_fmt(buf, sizeof(buf), (struct sockaddr *)&addr)) 97 if (efl_net_ip_port_fmt(buf, sizeof(buf), (struct sockaddr *)&addr))
98 efl_net_server_address_set(o, buf); 98 efl_net_server_address_set(o, buf);
99 99
100 if (efl_net_server_fd_close_on_exec_get(o)) 100 fd = efl_net_socket4(addr.ss_family, SOCK_STREAM, IPPROTO_TCP,
101 extra_flags |= SOCK_CLOEXEC; 101 efl_net_server_fd_close_on_exec_get(o));
102
103 fd = socket(addr.ss_family, SOCK_STREAM | extra_flags, IPPROTO_TCP);
104 if (fd < 0) 102 if (fd < 0)
105 { 103 {
106 err = errno; 104 err = errno;
107 ERR("socket(%d, SOCK_STREAM | %#x, IPPROTO_TCP): %s", 105 ERR("socket(%d, SOCK_STREAM, IPPROTO_TCP): %s",
108 addr.ss_family, extra_flags, strerror(errno)); 106 addr.ss_family, strerror(errno));
109 goto error_socket; 107 goto error_socket;
110 } 108 }
111 109