Skip to content

Commit 42b575c

Browse files
committed
Access errno only when on the error path.
1 parent e3ed5f0 commit 42b575c

File tree

5 files changed

+259
-328
lines changed

5 files changed

+259
-328
lines changed

include/boost/asio/detail/descriptor_ops.hpp

+11-6
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,18 @@ enum
5151

5252
typedef unsigned char state_type;
5353

54-
template <typename ReturnType>
55-
inline ReturnType error_wrapper(ReturnType return_value,
56-
boost::system::error_code& ec)
54+
inline void get_last_error(
55+
boost::system::error_code& ec, bool is_error_condition)
5756
{
58-
ec = boost::system::error_code(errno,
59-
boost::asio::error::get_system_category());
60-
return return_value;
57+
if (!is_error_condition)
58+
{
59+
ec = boost::system::error_code();
60+
}
61+
else
62+
{
63+
ec = boost::system::error_code(errno,
64+
boost::asio::error::get_system_category());
65+
}
6166
}
6267

6368
BOOST_ASIO_DECL int open(const char* path, int flags,

include/boost/asio/detail/impl/descriptor_ops.ipp

+44-64
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,8 @@ namespace descriptor_ops {
3333

3434
int open(const char* path, int flags, boost::system::error_code& ec)
3535
{
36-
errno = 0;
37-
int result = error_wrapper(::open(path, flags), ec);
38-
if (result >= 0)
39-
ec = boost::system::error_code();
36+
int result = ::open(path, flags);
37+
get_last_error(ec, result < 0);
4038
return result;
4139
}
4240

@@ -45,8 +43,8 @@ int close(int d, state_type& state, boost::system::error_code& ec)
4543
int result = 0;
4644
if (d != -1)
4745
{
48-
errno = 0;
49-
result = error_wrapper(::close(d), ec);
46+
result = ::close(d);
47+
get_last_error(ec, result < 0);
5048

5149
if (result != 0
5250
&& (ec == boost::asio::error::would_block
@@ -68,13 +66,11 @@ int close(int d, state_type& state, boost::system::error_code& ec)
6866
#endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
6967
state &= ~non_blocking;
7068

71-
errno = 0;
72-
result = error_wrapper(::close(d), ec);
69+
result = ::close(d);
70+
get_last_error(ec, result < 0);
7371
}
7472
}
7573

76-
if (result == 0)
77-
ec = boost::system::error_code();
7874
return result;
7975
}
8076

@@ -87,23 +83,23 @@ bool set_user_non_blocking(int d, state_type& state,
8783
return false;
8884
}
8985

90-
errno = 0;
9186
#if defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
92-
int result = error_wrapper(::fcntl(d, F_GETFL, 0), ec);
87+
int result = ::fcntl(d, F_GETFL, 0);
88+
get_last_error(ec, result < 0);
9389
if (result >= 0)
9490
{
95-
errno = 0;
9691
int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));
97-
result = error_wrapper(::fcntl(d, F_SETFL, flag), ec);
92+
result = ::fcntl(d, F_SETFL, flag);
93+
get_last_error(ec, result < 0);
9894
}
9995
#else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
10096
ioctl_arg_type arg = (value ? 1 : 0);
101-
int result = error_wrapper(::ioctl(d, FIONBIO, &arg), ec);
97+
int result = ::ioctl(d, FIONBIO, &arg);
98+
get_last_error(ec, result < 0);
10299
#endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
103100

104101
if (result >= 0)
105102
{
106-
ec = boost::system::error_code();
107103
if (value)
108104
state |= user_set_non_blocking;
109105
else
@@ -137,23 +133,23 @@ bool set_internal_non_blocking(int d, state_type& state,
137133
return false;
138134
}
139135

140-
errno = 0;
141136
#if defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
142-
int result = error_wrapper(::fcntl(d, F_GETFL, 0), ec);
137+
int result = ::fcntl(d, F_GETFL, 0);
138+
get_last_error(ec, result < 0);
143139
if (result >= 0)
144140
{
145-
errno = 0;
146141
int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));
147-
result = error_wrapper(::fcntl(d, F_SETFL, flag), ec);
142+
result = ::fcntl(d, F_SETFL, flag);
143+
get_last_error(ec, result < 0);
148144
}
149145
#else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
150146
ioctl_arg_type arg = (value ? 1 : 0);
151-
int result = error_wrapper(::ioctl(d, FIONBIO, &arg), ec);
147+
int result = ::ioctl(d, FIONBIO, &arg);
148+
get_last_error(ec, result < 0);
152149
#endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
153150

154151
if (result >= 0)
155152
{
156-
ec = boost::system::error_code();
157153
if (value)
158154
state |= internal_non_blocking;
159155
else
@@ -184,9 +180,8 @@ std::size_t sync_read(int d, state_type state, buf* bufs,
184180
for (;;)
185181
{
186182
// Try to complete the operation without blocking.
187-
errno = 0;
188-
signed_size_type bytes = error_wrapper(::readv(
189-
d, bufs, static_cast<int>(count)), ec);
183+
signed_size_type bytes = ::readv(d, bufs, static_cast<int>(count));
184+
get_last_error(ec, bytes < 0);
190185

191186
// Check if operation succeeded.
192187
if (bytes > 0)
@@ -217,9 +212,8 @@ bool non_blocking_read(int d, buf* bufs, std::size_t count,
217212
for (;;)
218213
{
219214
// Read some data.
220-
errno = 0;
221-
signed_size_type bytes = error_wrapper(::readv(
222-
d, bufs, static_cast<int>(count)), ec);
215+
signed_size_type bytes = ::readv(d, bufs, static_cast<int>(count));
216+
get_last_error(ec, bytes < 0);
223217

224218
// Check for end of stream.
225219
if (bytes == 0)
@@ -270,9 +264,8 @@ std::size_t sync_write(int d, state_type state, const buf* bufs,
270264
for (;;)
271265
{
272266
// Try to complete the operation without blocking.
273-
errno = 0;
274-
signed_size_type bytes = error_wrapper(::writev(
275-
d, bufs, static_cast<int>(count)), ec);
267+
signed_size_type bytes = ::writev(d, bufs, static_cast<int>(count));
268+
get_last_error(ec, bytes < 0);
276269

277270
// Check if operation succeeded.
278271
if (bytes > 0)
@@ -296,9 +289,8 @@ bool non_blocking_write(int d, const buf* bufs, std::size_t count,
296289
for (;;)
297290
{
298291
// Write some data.
299-
errno = 0;
300-
signed_size_type bytes = error_wrapper(::writev(
301-
d, bufs, static_cast<int>(count)), ec);
292+
signed_size_type bytes = ::writev(d, bufs, static_cast<int>(count));
293+
get_last_error(ec, bytes < 0);
302294

303295
// Retry operation if interrupted by signal.
304296
if (ec == boost::asio::error::interrupted)
@@ -331,13 +323,11 @@ int ioctl(int d, state_type& state, long cmd,
331323
return -1;
332324
}
333325

334-
errno = 0;
335-
int result = error_wrapper(::ioctl(d, cmd, arg), ec);
326+
int result = ::ioctl(d, cmd, arg);
327+
get_last_error(ec, result < 0);
336328

337329
if (result >= 0)
338330
{
339-
ec = boost::system::error_code();
340-
341331
// When updating the non-blocking mode we always perform the ioctl syscall,
342332
// even if the flags would otherwise indicate that the descriptor is
343333
// already in the correct state. This ensures that the underlying
@@ -371,10 +361,8 @@ int fcntl(int d, int cmd, boost::system::error_code& ec)
371361
return -1;
372362
}
373363

374-
errno = 0;
375-
int result = error_wrapper(::fcntl(d, cmd), ec);
376-
if (result != -1)
377-
ec = boost::system::error_code();
364+
int result = ::fcntl(d, cmd);
365+
get_last_error(ec, result < 0);
378366
return result;
379367
}
380368

@@ -386,10 +374,8 @@ int fcntl(int d, int cmd, long arg, boost::system::error_code& ec)
386374
return -1;
387375
}
388376

389-
errno = 0;
390-
int result = error_wrapper(::fcntl(d, cmd, arg), ec);
391-
if (result != -1)
392-
ec = boost::system::error_code();
377+
int result = ::fcntl(d, cmd, arg);
378+
get_last_error(ec, result < 0);
393379
return result;
394380
}
395381

@@ -406,13 +392,11 @@ int poll_read(int d, state_type state, boost::system::error_code& ec)
406392
fds.events = POLLIN;
407393
fds.revents = 0;
408394
int timeout = (state & user_set_non_blocking) ? 0 : -1;
409-
errno = 0;
410-
int result = error_wrapper(::poll(&fds, 1, timeout), ec);
395+
int result = ::poll(&fds, 1, timeout);
396+
get_last_error(ec, result < 0);
411397
if (result == 0)
412-
ec = (state & user_set_non_blocking)
413-
? boost::asio::error::would_block : boost::system::error_code();
414-
else if (result > 0)
415-
ec = boost::system::error_code();
398+
if (state & user_set_non_blocking)
399+
ec = boost::asio::error::would_block;
416400
return result;
417401
}
418402

@@ -429,13 +413,11 @@ int poll_write(int d, state_type state, boost::system::error_code& ec)
429413
fds.events = POLLOUT;
430414
fds.revents = 0;
431415
int timeout = (state & user_set_non_blocking) ? 0 : -1;
432-
errno = 0;
433-
int result = error_wrapper(::poll(&fds, 1, timeout), ec);
416+
int result = ::poll(&fds, 1, timeout);
417+
get_last_error(ec, result < 0);
434418
if (result == 0)
435-
ec = (state & user_set_non_blocking)
436-
? boost::asio::error::would_block : boost::system::error_code();
437-
else if (result > 0)
438-
ec = boost::system::error_code();
419+
if (state & user_set_non_blocking)
420+
ec = boost::asio::error::would_block;
439421
return result;
440422
}
441423

@@ -452,13 +434,11 @@ int poll_error(int d, state_type state, boost::system::error_code& ec)
452434
fds.events = POLLPRI | POLLERR | POLLHUP;
453435
fds.revents = 0;
454436
int timeout = (state & user_set_non_blocking) ? 0 : -1;
455-
errno = 0;
456-
int result = error_wrapper(::poll(&fds, 1, timeout), ec);
437+
int result = ::poll(&fds, 1, timeout);
438+
get_last_error(ec, result < 0);
457439
if (result == 0)
458-
ec = (state & user_set_non_blocking)
459-
? boost::asio::error::would_block : boost::system::error_code();
460-
else if (result > 0)
461-
ec = boost::system::error_code();
440+
if (state & user_set_non_blocking)
441+
ec = boost::asio::error::would_block;
462442
return result;
463443
}
464444

include/boost/asio/detail/impl/reactive_serial_port_service.ipp

+12-15
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ boost::system::error_code reactive_serial_port_service::open(
7070

7171
// Set up default serial port options.
7272
termios ios;
73-
errno = 0;
74-
s = descriptor_ops::error_wrapper(::tcgetattr(fd, &ios), ec);
73+
s = ::tcgetattr(fd, &ios);
74+
descriptor_ops::get_last_error(ec, s < 0);
7575
if (s >= 0)
7676
{
7777
#if defined(_BSD_SOURCE) || defined(_DEFAULT_SOURCE)
@@ -86,8 +86,8 @@ boost::system::error_code reactive_serial_port_service::open(
8686
#endif
8787
ios.c_iflag |= IGNPAR;
8888
ios.c_cflag |= CREAD | CLOCAL;
89-
errno = 0;
90-
s = descriptor_ops::error_wrapper(::tcsetattr(fd, TCSANOW, &ios), ec);
89+
s = ::tcsetattr(fd, TCSANOW, &ios);
90+
descriptor_ops::get_last_error(ec, s < 0);
9191
}
9292
if (s < 0)
9393
{
@@ -112,18 +112,16 @@ boost::system::error_code reactive_serial_port_service::do_set_option(
112112
const void* option, boost::system::error_code& ec)
113113
{
114114
termios ios;
115-
errno = 0;
116-
descriptor_ops::error_wrapper(::tcgetattr(
117-
descriptor_service_.native_handle(impl), &ios), ec);
118-
if (ec)
115+
int s = ::tcgetattr(descriptor_service_.native_handle(impl), &ios);
116+
descriptor_ops::get_last_error(ec, s < 0);
117+
if (s < 0)
119118
return ec;
120119

121120
if (store(option, ios, ec))
122121
return ec;
123122

124-
errno = 0;
125-
descriptor_ops::error_wrapper(::tcsetattr(
126-
descriptor_service_.native_handle(impl), TCSANOW, &ios), ec);
123+
s = ::tcsetattr(descriptor_service_.native_handle(impl), TCSANOW, &ios);
124+
descriptor_ops::get_last_error(ec, s < 0);
127125
return ec;
128126
}
129127

@@ -133,10 +131,9 @@ boost::system::error_code reactive_serial_port_service::do_get_option(
133131
void* option, boost::system::error_code& ec) const
134132
{
135133
termios ios;
136-
errno = 0;
137-
descriptor_ops::error_wrapper(::tcgetattr(
138-
descriptor_service_.native_handle(impl), &ios), ec);
139-
if (ec)
134+
int s = ::tcgetattr(descriptor_service_.native_handle(impl), &ios);
135+
descriptor_ops::get_last_error(ec, s < 0);
136+
if (s < 0)
140137
return ec;
141138

142139
return load(option, ios, ec);

0 commit comments

Comments
 (0)