Merge pull request #12034 from poettering/stdio-bridge-fixes

small stdio-bridge and errno-util.h improvements and fixes
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2019-03-20 10:46:32 +01:00
committed by GitHub
7 changed files with 46 additions and 40 deletions
+14
View File
@@ -27,3 +27,17 @@ static inline int negative_errno(void) {
assert_return(errno > 0, -EINVAL);
return -errno;
}
/* Hint #1: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5.
*
* Hint #2: The kernel sends e.g., EHOSTUNREACH or ENONET to userspace in some ICMP error cases. See the
* icmp_err_convert[] in net/ipv4/icmp.c in the kernel sources */
#define ERRNO_IS_DISCONNECT(r) \
IN_SET(abs(r), \
ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, \
ENETUNREACH, EHOSTUNREACH, ENOPROTOOPT, EHOSTDOWN, \
ENONET, ESHUTDOWN)
/* Resource exhaustion, could be our fault or general system trouble */
#define ERRNO_IS_RESOURCE(r) \
IN_SET(abs(r), ENOMEM, EMFILE, ENFILE)
-12
View File
@@ -77,18 +77,6 @@ int acquire_data_fd(const void *data, size_t size, unsigned flags);
int fd_duplicate_data_fd(int fd);
/* Hint: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5 */
/* The kernel sends e.g., EHOSTUNREACH or ENONET to userspace in some ICMP error cases.
* See the icmp_err_convert[] in net/ipv4/icmp.c in the kernel sources */
#define ERRNO_IS_DISCONNECT(r) \
IN_SET(r, \
ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, \
ENETUNREACH, EHOSTUNREACH, ENOPROTOOPT, EHOSTDOWN, ENONET)
/* Resource exhaustion, could be our fault or general system trouble */
#define ERRNO_IS_RESOURCE(r) \
IN_SET(r, ENOMEM, EMFILE, ENFILE)
int fd_move_above_stdio(int fd);
int rearrange_stdio(int original_input_fd, int original_output_fd, int original_error_fd);
+2 -2
View File
@@ -3056,7 +3056,7 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
}
if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
if (!IN_SET(errno, EPIPE, EAGAIN, ENOENT, ECONNREFUSED, ECONNRESET, ECONNABORTED))
if (!IN_SET(errno, EAGAIN, ENOENT) && !ERRNO_IS_DISCONNECT(errno))
log_error_errno(errno, "connect() failed: %m");
return;
}
@@ -3068,7 +3068,7 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
errno = 0;
if (write(fd, message, n + 1) != n + 1)
if (!IN_SET(errno, EPIPE, EAGAIN, ENOENT, ECONNREFUSED, ECONNRESET, ECONNABORTED))
if (!IN_SET(errno, EAGAIN, ENOENT) && !ERRNO_IS_DISCONNECT(errno))
log_error_errno(errno, "Failed to write Plymouth message: %m");
}
+6 -5
View File
@@ -28,6 +28,7 @@
#include "bus-util.h"
#include "cgroup-util.h"
#include "def.h"
#include "errno-util.h"
#include "fd-util.h"
#include "hexdecoct.h"
#include "hostname-util.h"
@@ -1928,7 +1929,7 @@ _public_ int sd_bus_send(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie) {
r = bus_write_message(bus, m, &idx);
if (r < 0) {
if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
if (ERRNO_IS_DISCONNECT(r)) {
bus_enter_closing(bus);
return -ECONNRESET;
}
@@ -2224,7 +2225,7 @@ _public_ int sd_bus_call(
r = bus_read_message(bus, false, 0);
if (r < 0) {
if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
if (ERRNO_IS_DISCONNECT(r)) {
bus_enter_closing(bus);
r = -ECONNRESET;
}
@@ -2257,7 +2258,7 @@ _public_ int sd_bus_call(
r = dispatch_wqueue(bus);
if (r < 0) {
if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
if (ERRNO_IS_DISCONNECT(r)) {
bus_enter_closing(bus);
r = -ECONNRESET;
}
@@ -3015,7 +3016,7 @@ static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priorit
assert_not_reached("Unknown state");
}
if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
if (ERRNO_IS_DISCONNECT(r)) {
bus_enter_closing(bus);
r = 1;
} else if (r < 0)
@@ -3146,7 +3147,7 @@ _public_ int sd_bus_flush(sd_bus *bus) {
for (;;) {
r = dispatch_wqueue(bus);
if (r < 0) {
if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
if (ERRNO_IS_DISCONNECT(r)) {
bus_enter_closing(bus);
return -ECONNRESET;
}
+1
View File
@@ -6,6 +6,7 @@
#include "alloc-util.h"
#include "dns-domain.h"
#include "errno-list.h"
#include "errno-util.h"
#include "fd-util.h"
#include "random-util.h"
#include "resolved-dns-cache.h"
+4 -3
View File
@@ -16,6 +16,7 @@
#include "sd-resolve.h"
#include "alloc-util.h"
#include "errno-util.h"
#include "fd-util.h"
#include "log.h"
#include "main-func.h"
@@ -29,8 +30,8 @@
#include "util.h"
#define BUFFER_SIZE (256 * 1024)
static unsigned arg_connections_max = 256;
static unsigned arg_connections_max = 256;
static const char *arg_remote_host = NULL;
typedef struct Context {
@@ -141,7 +142,7 @@ static int connection_shovel(
if (z > 0) {
*full += z;
shoveled = true;
} else if (z == 0 || IN_SET(errno, EPIPE, ECONNRESET)) {
} else if (z == 0 || ERRNO_IS_DISCONNECT(errno)) {
*from_source = sd_event_source_unref(*from_source);
*from = safe_close(*from);
} else if (!IN_SET(errno, EAGAIN, EINTR))
@@ -153,7 +154,7 @@ static int connection_shovel(
if (z > 0) {
*full -= z;
shoveled = true;
} else if (z == 0 || IN_SET(errno, EPIPE, ECONNRESET)) {
} else if (z == 0 || ERRNO_IS_DISCONNECT(errno)) {
*to_source = sd_event_source_unref(*to_source);
*to = safe_close(*to);
} else if (!IN_SET(errno, EAGAIN, EINTR))
+19 -18
View File
@@ -14,6 +14,7 @@
#include "build.h"
#include "bus-internal.h"
#include "bus-util.h"
#include "errno-util.h"
#include "log.h"
#include "main-func.h"
#include "util.h"
@@ -56,31 +57,28 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
while ((c = getopt_long(argc, argv, "hsup:", options, NULL)) >= 0) {
while ((c = getopt_long(argc, argv, "hp:M:", options, NULL)) >= 0) {
switch (c) {
case 'h':
help();
return 0;
return help();
case ARG_VERSION:
return version();
case '?':
return -EINVAL;
case 'p':
arg_bus_path = optarg;
break;
case 'M':
arg_bus_path = optarg;
arg_transport = BUS_TRANSPORT_MACHINE;
break;
case '?':
return -EINVAL;
default:
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Unknown option code %c", c);
@@ -111,10 +109,8 @@ static int run(int argc, char *argv[]) {
} else if (r == 1) {
in_fd = SD_LISTEN_FDS_START;
out_fd = SD_LISTEN_FDS_START;
} else {
log_error("Illegal number of file descriptors passed.");
return -EINVAL;
}
} else
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Illegal number of file descriptors passed.");
is_unix =
sd_is_socket(in_fd, AF_UNIX, 0, 0) > 0 &&
@@ -187,9 +183,13 @@ static int run(int argc, char *argv[]) {
continue;
r = sd_bus_process(b, &m);
if (r < 0)
if (r < 0) {
/* treat 'connection reset by peer' as clean exit condition */
return r == -ECONNRESET ? 0 : r;
if (ERRNO_IS_DISCONNECT(r))
return 0;
return log_error_errno(r, "Failed to process bus: %m");
}
if (m) {
r = sd_bus_send(a, m, NULL);
@@ -240,9 +240,10 @@ static int run(int argc, char *argv[]) {
{
struct pollfd p[3] = {
{.fd = fd, .events = events_a, },
{.fd = STDIN_FILENO, .events = events_b & POLLIN, },
{.fd = STDOUT_FILENO, .events = events_b & POLLOUT, }};
{.fd = fd, .events = events_a },
{.fd = STDIN_FILENO, .events = events_b & POLLIN },
{.fd = STDOUT_FILENO, .events = events_b & POLLOUT },
};
r = ppoll(p, ELEMENTSOF(p), ts, NULL);
}