Merge lp:~brianaker/libdrizzle/less-fcntl into lp:libdrizzle

Proposed by Brian Aker
Status: Merged
Approved by: Andrew Hutchings
Approved revision: 78
Merged at revision: 78
Proposed branch: lp:~brianaker/libdrizzle/less-fcntl
Merge into: lp:libdrizzle
Diff against target: 207 lines (+111/-47)
1 file modified
libdrizzle/conn.cc (+111/-47)
To merge this branch: bzr merge lp:~brianaker/libdrizzle/less-fcntl
Reviewer Review Type Date Requested Status
Andrew Hutchings Approve
Review via email: mp+141883@code.launchpad.net

Description of the change

We don't need to call fcntl quite as often as we are.

To post a comment you must log in.
Revision history for this message
Andrew Hutchings (linuxjedi) wrote :

Looks good to me. Sent a note on Skype with an answer to the @todo and will file a bug

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'libdrizzle/conn.cc'
2--- libdrizzle/conn.cc 2012-12-31 00:06:53 +0000
3+++ libdrizzle/conn.cc 2013-01-04 10:25:23 +0000
4@@ -44,8 +44,20 @@
5 #include "config.h"
6 #include "libdrizzle/common.h"
7
8-#ifndef MSG_NOSIGNAL
9-# define MSG_NOSIGNAL 0
10+#ifndef SOCK_CLOEXEC
11+# define SOCK_CLOEXEC 0
12+#endif
13+
14+#ifndef SOCK_NONBLOCK
15+# define SOCK_NONBLOCK 0
16+#endif
17+
18+#ifndef FD_CLOEXEC
19+# define FD_CLOEXEC 0
20+#endif
21+
22+#ifndef MSG_DONTWAIT
23+# define MSG_DONTWAIT 0
24 #endif
25
26 /**
27@@ -73,6 +85,43 @@
28 }
29 }
30
31+#ifdef WIN32
32+static void translate_windows_error()
33+{
34+ errno= WSAGetLastError();
35+ switch(errno) {
36+ case WSAEINVAL:
37+ case WSAEALREADY:
38+ case WSAEWOULDBLOCK:
39+ errno= EINPROGRESS;
40+ break;
41+ case WSAECONNREFUSED:
42+ errno= ECONNREFUSED;
43+ break;
44+ case WSAENETUNREACH:
45+ errno= ENETUNREACH;
46+ break;
47+ case WSAETIMEDOUT:
48+ errno= ETIMEDOUT;
49+ break;
50+ case WSAECONNRESET:
51+ errno= ECONNRESET;
52+ break;
53+ case WSAEADDRINUSE:
54+ errno= EADDRINUSE;
55+ break;
56+ case WSAEOPNOTSUPP:
57+ errno= EOPNOTSUPP;
58+ break;
59+ case WSAENOPROTOOPT:
60+ errno= ENOPROTOOPT;
61+ break;
62+ default:
63+ break;
64+ }
65+}
66+#endif
67+
68 static bool connect_poll(drizzle_st *con)
69 {
70 struct pollfd fds[1];
71@@ -933,10 +982,24 @@
72 return DRIZZLE_RETURN_COULD_NOT_CONNECT;
73 }
74
75- con->fd= socket(con->addrinfo_next->ai_family,
76- con->addrinfo_next->ai_socktype,
77- con->addrinfo_next->ai_protocol);
78- if (con->fd == -1)
79+ {
80+ int type= con->addrinfo_next->ai_socktype;
81+ if (SOCK_CLOEXEC)
82+ {
83+ type|= SOCK_CLOEXEC;
84+ }
85+
86+ if (SOCK_NONBLOCK)
87+ {
88+ type|= SOCK_NONBLOCK;
89+ }
90+
91+ con->fd= socket(con->addrinfo_next->ai_family,
92+ type,
93+ con->addrinfo_next->ai_protocol);
94+ }
95+
96+ if (con->fd == INVALID_SOCKET)
97 {
98 drizzle_set_error(con, __func__, "socket:%s", strerror(errno));
99 con->last_errno= errno;
100@@ -955,37 +1018,7 @@
101 int ret= connect(con->fd, con->addrinfo_next->ai_addr, con->addrinfo_next->ai_addrlen);
102
103 #ifdef _WIN32
104- errno = WSAGetLastError();
105- switch(errno) {
106- case WSAEINVAL:
107- case WSAEALREADY:
108- case WSAEWOULDBLOCK:
109- errno= EINPROGRESS;
110- break;
111- case WSAECONNREFUSED:
112- errno= ECONNREFUSED;
113- break;
114- case WSAENETUNREACH:
115- errno= ENETUNREACH;
116- break;
117- case WSAETIMEDOUT:
118- errno= ETIMEDOUT;
119- break;
120- case WSAECONNRESET:
121- errno= ECONNRESET;
122- break;
123- case WSAEADDRINUSE:
124- errno= EADDRINUSE;
125- break;
126- case WSAEOPNOTSUPP:
127- errno= EOPNOTSUPP;
128- break;
129- case WSAENOPROTOOPT:
130- errno= ENOPROTOOPT;
131- break;
132- default:
133- break;
134- }
135+ translate_windows_error();
136 #endif /* _WIN32 */
137
138 drizzle_log_crazy(con, "connect return=%d errno=%s", ret, strerror(errno));
139@@ -1407,6 +1440,33 @@
140 struct timeval waittime;
141
142 assert(con);
143+ if (con == NULL)
144+ {
145+ return DRIZZLE_RETURN_INVALID_ARGUMENT;
146+ }
147+
148+ if (SOCK_CLOEXEC == 0)
149+ {
150+ if (FD_CLOEXEC)
151+ {
152+ int flags;
153+ do
154+ {
155+ flags= fcntl(con->fd, F_GETFD, 0);
156+ } while (flags == -1 and (errno == EINTR or errno == EAGAIN));
157+
158+ if (flags != -1)
159+ {
160+ int rval;
161+ do
162+ {
163+ rval= fcntl (con->fd, F_SETFD, flags | FD_CLOEXEC);
164+ } while (rval == -1 && (errno == EINTR or errno == EAGAIN));
165+ // we currently ignore the case where rval is -1
166+ }
167+ }
168+ }
169+
170
171 int ret= 1;
172
173@@ -1516,20 +1576,24 @@
174 ioctlsocket(con->fd, FIONBIO, &asyncmode);
175 }
176 #else
177+ // @todo find out why this can't be non-blocking for SSL
178 if (!con->ssl)
179 {
180- ret= fcntl(con->fd, F_GETFL, 0);
181- if (ret == -1)
182+ if (SOCK_NONBLOCK == 0)
183 {
184- drizzle_set_error(con, __func__, "fcntl:F_GETFL:%s", strerror(errno));
185- return DRIZZLE_RETURN_ERRNO;
186- }
187+ ret= fcntl(con->fd, F_GETFL, 0);
188+ if (ret == -1)
189+ {
190+ drizzle_set_error(con, __func__, "fcntl:F_GETFL:%s", strerror(errno));
191+ return DRIZZLE_RETURN_ERRNO;
192+ }
193
194- ret= fcntl(con->fd, F_SETFL, ret | O_NONBLOCK);
195- if (ret == -1)
196- {
197- drizzle_set_error(con, __func__, "fcntl:F_SETFL:%s", strerror(errno));
198- return DRIZZLE_RETURN_ERRNO;
199+ ret= fcntl(con->fd, F_SETFL, ret | O_NONBLOCK);
200+ if (ret == -1)
201+ {
202+ drizzle_set_error(con, __func__, "fcntl:F_SETFL:%s", strerror(errno));
203+ return DRIZZLE_RETURN_ERRNO;
204+ }
205 }
206 }
207 #endif

Subscribers

People subscribed via source and target branches

to all changes:
to status/vote changes: