src: Add XSI-compliant version strerror_r
This commit is contained in:
parent
a5d66e71d0
commit
8b64e7b4e1
|
@ -112,6 +112,7 @@ if(ENABLE_APP)
|
|||
shrpx_api_downstream_connection.cc
|
||||
shrpx_health_monitor_downstream_connection.cc
|
||||
shrpx_exec.cc
|
||||
xsi_strerror.c
|
||||
)
|
||||
if(HAVE_SPDYLAY)
|
||||
list(APPEND NGHTTPX_SRCS
|
||||
|
|
|
@ -139,7 +139,8 @@ NGHTTPX_SRCS = \
|
|||
shrpx_health_monitor_downstream_connection.cc \
|
||||
shrpx_health_monitor_downstream_connection.h \
|
||||
shrpx_exec.cc shrpx_exec.h \
|
||||
buffer.h memchunk.h template.h allocator.h
|
||||
buffer.h memchunk.h template.h allocator.h \
|
||||
xsi_strerror.c xsi_strerror.h
|
||||
|
||||
if HAVE_SPDYLAY
|
||||
NGHTTPX_SRCS += shrpx_spdy_upstream.cc shrpx_spdy_upstream.h
|
||||
|
|
112
src/shrpx.cc
112
src/shrpx.cc
|
@ -88,6 +88,7 @@
|
|||
#include "template.h"
|
||||
#include "allocator.h"
|
||||
#include "ssl_compat.h"
|
||||
#include "xsi_strerror.h"
|
||||
|
||||
extern char **environ;
|
||||
|
||||
|
@ -298,6 +299,7 @@ int chown_to_running_user(const char *path) {
|
|||
|
||||
namespace {
|
||||
int save_pid() {
|
||||
std::array<char, STRERROR_BUFSIZE> errbuf;
|
||||
auto config = get_config();
|
||||
|
||||
constexpr auto SUFFIX = StringRef::from_lit(".XXXXXX");
|
||||
|
@ -317,7 +319,7 @@ int save_pid() {
|
|||
if (fd == -1) {
|
||||
auto error = errno;
|
||||
LOG(ERROR) << "Could not save PID to file " << pid_file << ": "
|
||||
<< strerror(error);
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -326,14 +328,14 @@ int save_pid() {
|
|||
if (write(fd, content.c_str(), content.size()) == -1) {
|
||||
auto error = errno;
|
||||
LOG(ERROR) << "Could not save PID to file " << pid_file << ": "
|
||||
<< strerror(error);
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fsync(fd) == -1) {
|
||||
auto error = errno;
|
||||
LOG(ERROR) << "Could not save PID to file " << pid_file << ": "
|
||||
<< strerror(error);
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -342,7 +344,7 @@ int save_pid() {
|
|||
if (rename(temp_path, pid_file.c_str()) == -1) {
|
||||
auto error = errno;
|
||||
LOG(ERROR) << "Could not save PID to file " << pid_file << ": "
|
||||
<< strerror(error);
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
|
||||
unlink(temp_path);
|
||||
|
||||
|
@ -352,8 +354,8 @@ int save_pid() {
|
|||
if (config->uid != 0) {
|
||||
if (chown_to_running_user(pid_file.c_str()) == -1) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "Changing owner of pid file " << pid_file
|
||||
<< " failed: " << strerror(error);
|
||||
LOG(WARN) << "Changing owner of pid file " << pid_file << " failed: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -365,13 +367,15 @@ namespace {
|
|||
void exec_binary() {
|
||||
int rv;
|
||||
sigset_t oldset;
|
||||
std::array<char, STRERROR_BUFSIZE> errbuf;
|
||||
|
||||
LOG(NOTICE) << "Executing new binary";
|
||||
|
||||
rv = shrpx_signal_block_all(&oldset);
|
||||
if (rv != 0) {
|
||||
auto error = errno;
|
||||
LOG(ERROR) << "Blocking all signals failed: " << strerror(error);
|
||||
LOG(ERROR) << "Blocking all signals failed: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -388,7 +392,8 @@ void exec_binary() {
|
|||
|
||||
if (rv != 0) {
|
||||
auto error = errno;
|
||||
LOG(FATAL) << "Restoring signal mask failed: " << strerror(error);
|
||||
LOG(FATAL) << "Restoring signal mask failed: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
@ -403,7 +408,8 @@ void exec_binary() {
|
|||
rv = shrpx_signal_unblock_all();
|
||||
if (rv != 0) {
|
||||
auto error = errno;
|
||||
LOG(ERROR) << "Unblocking all signals failed: " << strerror(error);
|
||||
LOG(ERROR) << "Unblocking all signals failed: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
|
||||
_Exit(EXIT_FAILURE);
|
||||
}
|
||||
|
@ -493,6 +499,7 @@ void exec_binary() {
|
|||
|
||||
namespace {
|
||||
void ipc_send(WorkerProcess *wp, uint8_t ipc_event) {
|
||||
std::array<char, STRERROR_BUFSIZE> errbuf;
|
||||
ssize_t nwrite;
|
||||
while ((nwrite = write(wp->ipc_fd, &ipc_event, 1)) == -1 && errno == EINTR)
|
||||
;
|
||||
|
@ -500,7 +507,7 @@ void ipc_send(WorkerProcess *wp, uint8_t ipc_event) {
|
|||
if (nwrite < 0) {
|
||||
auto error = errno;
|
||||
LOG(ERROR) << "Could not send IPC event to worker process: "
|
||||
<< strerror(error);
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -569,6 +576,7 @@ void worker_process_child_cb(struct ev_loop *loop, ev_child *w, int revents) {
|
|||
namespace {
|
||||
int create_unix_domain_server_socket(UpstreamAddr &faddr,
|
||||
std::vector<InheritedAddr> &iaddrs) {
|
||||
std::array<char, STRERROR_BUFSIZE> errbuf;
|
||||
auto found = std::find_if(
|
||||
std::begin(iaddrs), std::end(iaddrs), [&faddr](const InheritedAddr &ia) {
|
||||
return !ia.used && ia.host_unix && ia.host == faddr.host;
|
||||
|
@ -588,14 +596,16 @@ int create_unix_domain_server_socket(UpstreamAddr &faddr,
|
|||
auto fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
|
||||
if (fd == -1) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "socket() syscall failed: " << strerror(error);
|
||||
LOG(WARN) << "socket() syscall failed: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
return -1;
|
||||
}
|
||||
#else // !SOCK_NONBLOCK
|
||||
auto fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd == -1) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "socket() syscall failed: " << strerror(error);
|
||||
LOG(WARN) << "socket() syscall failed: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
return -1;
|
||||
}
|
||||
util::make_socket_nonblocking(fd);
|
||||
|
@ -605,7 +615,7 @@ int create_unix_domain_server_socket(UpstreamAddr &faddr,
|
|||
static_cast<socklen_t>(sizeof(val))) == -1) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "Failed to set SO_REUSEADDR option to listener socket: "
|
||||
<< strerror(error);
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
@ -626,7 +636,8 @@ int create_unix_domain_server_socket(UpstreamAddr &faddr,
|
|||
|
||||
if (bind(fd, &addr.sa, sizeof(addr.un)) != 0) {
|
||||
auto error = errno;
|
||||
LOG(FATAL) << "Failed to bind UNIX domain socket: " << strerror(error);
|
||||
LOG(FATAL) << "Failed to bind UNIX domain socket: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
@ -635,7 +646,8 @@ int create_unix_domain_server_socket(UpstreamAddr &faddr,
|
|||
|
||||
if (listen(fd, listenerconf.backlog) != 0) {
|
||||
auto error = errno;
|
||||
LOG(FATAL) << "Failed to listen to UNIX domain socket: " << strerror(error);
|
||||
LOG(FATAL) << "Failed to listen to UNIX domain socket: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
@ -653,6 +665,7 @@ int create_unix_domain_server_socket(UpstreamAddr &faddr,
|
|||
namespace {
|
||||
int create_tcp_server_socket(UpstreamAddr &faddr,
|
||||
std::vector<InheritedAddr> &iaddrs) {
|
||||
std::array<char, STRERROR_BUFSIZE> errbuf;
|
||||
int fd = -1;
|
||||
int rv;
|
||||
|
||||
|
@ -713,14 +726,16 @@ int create_tcp_server_socket(UpstreamAddr &faddr,
|
|||
socket(rp->ai_family, rp->ai_socktype | SOCK_NONBLOCK, rp->ai_protocol);
|
||||
if (fd == -1) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "socket() syscall failed: " << strerror(error);
|
||||
LOG(WARN) << "socket() syscall failed: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
continue;
|
||||
}
|
||||
#else // !SOCK_NONBLOCK
|
||||
fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||
if (fd == -1) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "socket() syscall failed: " << strerror(error);
|
||||
LOG(WARN) << "socket() syscall failed: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
continue;
|
||||
}
|
||||
util::make_socket_nonblocking(fd);
|
||||
|
@ -730,7 +745,7 @@ int create_tcp_server_socket(UpstreamAddr &faddr,
|
|||
static_cast<socklen_t>(sizeof(val))) == -1) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "Failed to set SO_REUSEADDR option to listener socket: "
|
||||
<< strerror(error);
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
|
@ -741,7 +756,7 @@ int create_tcp_server_socket(UpstreamAddr &faddr,
|
|||
static_cast<socklen_t>(sizeof(val))) == -1) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "Failed to set IPV6_V6ONLY option to listener socket: "
|
||||
<< strerror(error);
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
|
@ -754,7 +769,7 @@ int create_tcp_server_socket(UpstreamAddr &faddr,
|
|||
static_cast<socklen_t>(sizeof(val))) == -1) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "Failed to set TCP_DEFER_ACCEPT option to listener socket: "
|
||||
<< strerror(error);
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
}
|
||||
#endif // TCP_DEFER_ACCEPT
|
||||
|
||||
|
@ -763,7 +778,8 @@ int create_tcp_server_socket(UpstreamAddr &faddr,
|
|||
// ports will fail with permission denied error.
|
||||
if (bind(fd, rp->ai_addr, rp->ai_addrlen) == -1) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "bind() syscall failed: " << strerror(error);
|
||||
LOG(WARN) << "bind() syscall failed: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
|
@ -774,13 +790,14 @@ int create_tcp_server_socket(UpstreamAddr &faddr,
|
|||
static_cast<socklen_t>(sizeof(val))) == -1) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "Failed to set TCP_FASTOPEN option to listener socket: "
|
||||
<< strerror(error);
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
}
|
||||
}
|
||||
|
||||
if (listen(fd, listenerconf.backlog) == -1) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "listen() syscall failed: " << strerror(error);
|
||||
LOG(WARN) << "listen() syscall failed: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
|
@ -812,6 +829,7 @@ namespace {
|
|||
// |config| is usually a current configuration.
|
||||
std::vector<InheritedAddr>
|
||||
get_inherited_addr_from_config(BlockAllocator &balloc, Config *config) {
|
||||
std::array<char, STRERROR_BUFSIZE> errbuf;
|
||||
int rv;
|
||||
|
||||
auto &listenerconf = config->conn.listener;
|
||||
|
@ -848,7 +866,7 @@ get_inherited_addr_from_config(BlockAllocator &balloc, Config *config) {
|
|||
if (getsockname(addr.fd, &su.sa, &salen) != 0) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "getsockname() syscall failed (fd=" << addr.fd
|
||||
<< "): " << strerror(error);
|
||||
<< "): " << xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -873,6 +891,7 @@ namespace {
|
|||
// variables. This function handles the old environment variable
|
||||
// names used in 1.7.0 or earlier.
|
||||
std::vector<InheritedAddr> get_inherited_addr_from_env(Config *config) {
|
||||
std::array<char, STRERROR_BUFSIZE> errbuf;
|
||||
int rv;
|
||||
std::vector<InheritedAddr> iaddrs;
|
||||
|
||||
|
@ -971,7 +990,7 @@ std::vector<InheritedAddr> get_inherited_addr_from_env(Config *config) {
|
|||
if (getsockname(fd, &su.sa, &salen) != 0) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "getsockname() syscall failed (fd=" << fd
|
||||
<< "): " << strerror(error);
|
||||
<< "): " << xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
|
@ -1033,6 +1052,7 @@ void close_unused_inherited_addr(const std::vector<InheritedAddr> &iaddrs) {
|
|||
|
||||
namespace {
|
||||
int create_acceptor_socket(Config *config, std::vector<InheritedAddr> &iaddrs) {
|
||||
std::array<char, STRERROR_BUFSIZE> errbuf;
|
||||
auto &listenerconf = config->conn.listener;
|
||||
|
||||
for (auto &addr : listenerconf.addrs) {
|
||||
|
@ -1047,7 +1067,8 @@ int create_acceptor_socket(Config *config, std::vector<InheritedAddr> &iaddrs) {
|
|||
if (chown_to_running_user(addr.host.c_str()) == -1) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "Changing owner of UNIX domain socket " << addr.host
|
||||
<< " failed: " << strerror(error);
|
||||
<< " failed: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
@ -1078,13 +1099,14 @@ namespace {
|
|||
// messages to the worker process. On success, ipc_fd[0] is for
|
||||
// reading, and ipc_fd[1] for writing, just like pipe(2).
|
||||
int create_ipc_socket(std::array<int, 2> &ipc_fd) {
|
||||
std::array<char, STRERROR_BUFSIZE> errbuf;
|
||||
int rv;
|
||||
|
||||
rv = pipe(ipc_fd.data());
|
||||
if (rv == -1) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "Failed to create pipe to communicate worker process: "
|
||||
<< strerror(error);
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1106,6 +1128,7 @@ namespace {
|
|||
// used in the current configuration.
|
||||
pid_t fork_worker_process(int &main_ipc_fd,
|
||||
const std::vector<InheritedAddr> &iaddrs) {
|
||||
std::array<char, STRERROR_BUFSIZE> errbuf;
|
||||
int rv;
|
||||
sigset_t oldset;
|
||||
|
||||
|
@ -1119,7 +1142,8 @@ pid_t fork_worker_process(int &main_ipc_fd,
|
|||
rv = shrpx_signal_block_all(&oldset);
|
||||
if (rv != 0) {
|
||||
auto error = errno;
|
||||
LOG(ERROR) << "Blocking all signals failed: " << strerror(error);
|
||||
LOG(ERROR) << "Blocking all signals failed: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
|
||||
close(ipc_fd[0]);
|
||||
close(ipc_fd[1]);
|
||||
|
@ -1143,7 +1167,8 @@ pid_t fork_worker_process(int &main_ipc_fd,
|
|||
rv = shrpx_signal_unblock_all();
|
||||
if (rv != 0) {
|
||||
auto error = errno;
|
||||
LOG(FATAL) << "Unblocking all signals failed: " << strerror(error);
|
||||
LOG(FATAL) << "Unblocking all signals failed: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
|
||||
_Exit(EXIT_FAILURE);
|
||||
}
|
||||
|
@ -1166,13 +1191,15 @@ pid_t fork_worker_process(int &main_ipc_fd,
|
|||
// parent process
|
||||
if (pid == -1) {
|
||||
auto error = errno;
|
||||
LOG(ERROR) << "Could not spawn worker process: " << strerror(error);
|
||||
LOG(ERROR) << "Could not spawn worker process: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
}
|
||||
|
||||
rv = shrpx_signal_set(&oldset);
|
||||
if (rv != 0) {
|
||||
auto error = errno;
|
||||
LOG(FATAL) << "Restoring signal mask failed: " << strerror(error);
|
||||
LOG(FATAL) << "Restoring signal mask failed: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
@ -1196,6 +1223,8 @@ pid_t fork_worker_process(int &main_ipc_fd,
|
|||
|
||||
namespace {
|
||||
int event_loop() {
|
||||
std::array<char, STRERROR_BUFSIZE> errbuf;
|
||||
|
||||
shrpx_signal_set_master_proc_ign_handler();
|
||||
|
||||
auto config = mod_config();
|
||||
|
@ -1203,7 +1232,8 @@ int event_loop() {
|
|||
if (config->daemon) {
|
||||
if (call_daemon() == -1) {
|
||||
auto error = errno;
|
||||
LOG(FATAL) << "Failed to daemonize: " << strerror(error);
|
||||
LOG(FATAL) << "Failed to daemonize: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -2398,6 +2428,7 @@ Misc:
|
|||
namespace {
|
||||
int process_options(Config *config,
|
||||
std::vector<std::pair<StringRef, StringRef>> &cmdcfgs) {
|
||||
std::array<char, STRERROR_BUFSIZE> errbuf;
|
||||
if (conf_exists(config->conf_path.c_str())) {
|
||||
std::set<StringRef> include_set;
|
||||
if (load_config(config, config->conf_path.c_str(), include_set) == -1) {
|
||||
|
@ -2442,13 +2473,13 @@ int process_options(Config *config,
|
|||
fchown(log_config()->accesslog_fd, config->uid, config->gid) == -1) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "Changing owner of access log file failed: "
|
||||
<< strerror(error);
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
}
|
||||
if (log_config()->errorlog_fd != -1 &&
|
||||
fchown(log_config()->errorlog_fd, config->uid, config->gid) == -1) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "Changing owner of error log file failed: "
|
||||
<< strerror(error);
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2472,7 +2503,8 @@ int process_options(Config *config,
|
|||
if (chown_to_running_user(path) == -1) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "Changing owner of http2 upstream request header file "
|
||||
<< path << " failed: " << strerror(error);
|
||||
<< path << " failed: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2493,7 +2525,8 @@ int process_options(Config *config,
|
|||
if (chown_to_running_user(path) == -1) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "Changing owner of http2 upstream response header file"
|
||||
<< " " << path << " failed: " << strerror(error);
|
||||
<< " " << path << " failed: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2614,7 +2647,8 @@ int process_options(Config *config,
|
|||
static_cast<rlim_t>(config->rlimit_nofile)};
|
||||
if (setrlimit(RLIMIT_NOFILE, &lim) != 0) {
|
||||
auto error = errno;
|
||||
LOG(WARN) << "Setting rlimit-nofile failed: " << strerror(error);
|
||||
LOG(WARN) << "Setting rlimit-nofile failed: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2740,6 +2774,7 @@ void reload_config(WorkerProcess *wp) {
|
|||
|
||||
int main(int argc, char **argv) {
|
||||
int rv;
|
||||
std::array<char, STRERROR_BUFSIZE> errbuf;
|
||||
|
||||
nghttp2::ssl::libssl_init();
|
||||
|
||||
|
@ -2768,7 +2803,8 @@ int main(int argc, char **argv) {
|
|||
suconfig.argv[i] = strdup(argv[i]);
|
||||
if (suconfig.argv[i] == nullptr) {
|
||||
auto error = errno;
|
||||
LOG(FATAL) << "failed to copy argv: " << strerror(error);
|
||||
LOG(FATAL) << "failed to copy argv: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include "util.h"
|
||||
#include "base64.h"
|
||||
#include "ssl_compat.h"
|
||||
#include "xsi_strerror.h"
|
||||
|
||||
namespace shrpx {
|
||||
|
||||
|
@ -225,6 +226,8 @@ read_tls_ticket_key_file(const std::vector<StringRef> &files,
|
|||
}
|
||||
|
||||
FILE *open_file_for_write(const char *filename) {
|
||||
std::array<char, STRERROR_BUFSIZE> errbuf;
|
||||
|
||||
#if defined O_CLOEXEC
|
||||
auto fd = open(filename, O_WRONLY | O_CLOEXEC | O_CREAT | O_TRUNC,
|
||||
S_IRUSR | S_IWUSR);
|
||||
|
@ -237,14 +240,16 @@ FILE *open_file_for_write(const char *filename) {
|
|||
}
|
||||
#endif
|
||||
if (fd == -1) {
|
||||
LOG(ERROR) << "Failed to open " << filename
|
||||
<< " for writing. Cause: " << strerror(errno);
|
||||
auto error = errno;
|
||||
LOG(ERROR) << "Failed to open " << filename << " for writing. Cause: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
return nullptr;
|
||||
}
|
||||
auto f = fdopen(fd, "wb");
|
||||
if (f == nullptr) {
|
||||
LOG(ERROR) << "Failed to open " << filename
|
||||
<< " for writing. Cause: " << strerror(errno);
|
||||
auto error = errno;
|
||||
LOG(ERROR) << "Failed to open " << filename << " for writing. Cause: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -963,6 +968,8 @@ int parse_forwarded_node_type(const StringRef &optarg) {
|
|||
namespace {
|
||||
int parse_error_page(std::vector<ErrorPage> &error_pages, const StringRef &opt,
|
||||
const StringRef &optarg) {
|
||||
std::array<char, STRERROR_BUFSIZE> errbuf;
|
||||
|
||||
auto eq = std::find(std::begin(optarg), std::end(optarg), '=');
|
||||
if (eq == std::end(optarg) || eq + 1 == std::end(optarg)) {
|
||||
LOG(ERROR) << opt << ": bad value: '" << optarg << "'";
|
||||
|
@ -991,7 +998,8 @@ int parse_error_page(std::vector<ErrorPage> &error_pages, const StringRef &opt,
|
|||
auto fd = open(path.c_str(), O_RDONLY);
|
||||
if (fd == -1) {
|
||||
auto error = errno;
|
||||
LOG(ERROR) << opt << ": " << optarg << ": " << strerror(error);
|
||||
LOG(ERROR) << opt << ": " << optarg << ": "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1002,7 +1010,8 @@ int parse_error_page(std::vector<ErrorPage> &error_pages, const StringRef &opt,
|
|||
auto n = read(fd, buf.data(), buf.size());
|
||||
if (n == -1) {
|
||||
auto error = errno;
|
||||
LOG(ERROR) << opt << ": " << optarg << ": " << strerror(error);
|
||||
LOG(ERROR) << opt << ": " << optarg << ": "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
return -1;
|
||||
}
|
||||
if (n == 0) {
|
||||
|
@ -1068,10 +1077,13 @@ namespace {
|
|||
// must be NULL-terminated string.
|
||||
int read_tls_sct_from_dir(std::vector<uint8_t> &dst, const StringRef &opt,
|
||||
const StringRef &dir_path) {
|
||||
std::array<char, STRERROR_BUFSIZE> errbuf;
|
||||
|
||||
auto dir = opendir(dir_path.c_str());
|
||||
if (dir == nullptr) {
|
||||
auto error = errno;
|
||||
LOG(ERROR) << opt << ": " << dir_path << ": " << strerror(error);
|
||||
LOG(ERROR) << opt << ": " << dir_path << ": "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1088,7 +1100,7 @@ int read_tls_sct_from_dir(std::vector<uint8_t> &dst, const StringRef &opt,
|
|||
if (errno != 0) {
|
||||
auto error = errno;
|
||||
LOG(ERROR) << opt << ": failed to read directory " << dir_path << ": "
|
||||
<< strerror(error);
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
@ -1113,7 +1125,7 @@ int read_tls_sct_from_dir(std::vector<uint8_t> &dst, const StringRef &opt,
|
|||
if (fd == -1) {
|
||||
auto error = errno;
|
||||
LOG(ERROR) << opt << ": failed to read SCT from " << path << ": "
|
||||
<< strerror(error);
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1131,7 +1143,7 @@ int read_tls_sct_from_dir(std::vector<uint8_t> &dst, const StringRef &opt,
|
|||
if (nread == -1) {
|
||||
auto error = errno;
|
||||
LOG(ERROR) << opt << ": failed to read SCT data from " << path << ": "
|
||||
<< strerror(error);
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -2000,6 +2012,7 @@ int parse_config(Config *config, const StringRef &opt, const StringRef &optarg,
|
|||
|
||||
int parse_config(Config *config, int optid, const StringRef &opt,
|
||||
const StringRef &optarg, std::set<StringRef> &included_set) {
|
||||
std::array<char, STRERROR_BUFSIZE> errbuf;
|
||||
char host[NI_MAXHOST];
|
||||
uint16_t port;
|
||||
|
||||
|
@ -2304,7 +2317,7 @@ int parse_config(Config *config, int optid, const StringRef &opt,
|
|||
auto pwd = getpwnam(optarg.c_str());
|
||||
if (!pwd) {
|
||||
LOG(ERROR) << opt << ": failed to get uid from " << optarg << ": "
|
||||
<< strerror(errno);
|
||||
<< xsi_strerror(errno, errbuf.data(), errbuf.size());
|
||||
return -1;
|
||||
}
|
||||
config->user = make_string_ref(config->balloc, StringRef{pwd->pw_name});
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "util.h"
|
||||
#include "app_helper.h"
|
||||
#include "template.h"
|
||||
#include "xsi_strerror.h"
|
||||
|
||||
using namespace nghttp2;
|
||||
|
||||
|
@ -63,23 +64,26 @@ void drop_privileges(
|
|||
neverbleed_t *nb
|
||||
#endif // HAVE_NEVERBLEED
|
||||
) {
|
||||
std::array<char, STRERROR_BUFSIZE> errbuf;
|
||||
auto config = get_config();
|
||||
|
||||
if (getuid() == 0 && config->uid != 0) {
|
||||
if (initgroups(config->user.c_str(), config->gid) != 0) {
|
||||
auto error = errno;
|
||||
LOG(FATAL) << "Could not change supplementary groups: "
|
||||
<< strerror(error);
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (setgid(config->gid) != 0) {
|
||||
auto error = errno;
|
||||
LOG(FATAL) << "Could not change gid: " << strerror(error);
|
||||
LOG(FATAL) << "Could not change gid: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (setuid(config->uid) != 0) {
|
||||
auto error = errno;
|
||||
LOG(FATAL) << "Could not change uid: " << strerror(error);
|
||||
LOG(FATAL) << "Could not change uid: "
|
||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (setuid(0) != -1) {
|
||||
|
@ -387,6 +391,8 @@ std::random_device rd;
|
|||
} // namespace
|
||||
|
||||
int worker_process_event_loop(WorkerProcessConfig *wpconf) {
|
||||
std::array<char, STRERROR_BUFSIZE> errbuf;
|
||||
|
||||
if (reopen_log_files() != 0) {
|
||||
LOG(FATAL) << "Failed to open log file";
|
||||
return -1;
|
||||
|
@ -501,7 +507,8 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
|
|||
|
||||
rv = pthread_sigmask(SIG_BLOCK, &set, nullptr);
|
||||
if (rv != 0) {
|
||||
LOG(ERROR) << "Blocking SIGCHLD failed: " << strerror(rv);
|
||||
LOG(ERROR) << "Blocking SIGCHLD failed: "
|
||||
<< xsi_strerror(rv, errbuf.data(), errbuf.size());
|
||||
return -1;
|
||||
}
|
||||
#endif // !NOTHREADS
|
||||
|
@ -514,7 +521,8 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
|
|||
#ifndef NOTHREADS
|
||||
rv = pthread_sigmask(SIG_UNBLOCK, &set, nullptr);
|
||||
if (rv != 0) {
|
||||
LOG(ERROR) << "Unblocking SIGCHLD failed: " << strerror(rv);
|
||||
LOG(ERROR) << "Unblocking SIGCHLD failed: "
|
||||
<< xsi_strerror(rv, errbuf.data(), errbuf.size());
|
||||
return -1;
|
||||
}
|
||||
#endif // !NOTHREADS
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2016 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "xsi_strerror.h"
|
||||
|
||||
/* Make sure that we get XSI-compliant version of strerror_r */
|
||||
#ifdef _POSIX_C_SOURCE
|
||||
#undef _POSIX_C_SOURCE
|
||||
#endif /* _POSIX_C_SOURCE */
|
||||
|
||||
#ifdef _GNU_SOURCE
|
||||
#undef _GNU_SOURCE
|
||||
#endif /* _GNU_SOURCE */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
char *xsi_strerror(int errnum, char *buf, size_t buflen) {
|
||||
int rv;
|
||||
|
||||
rv = strerror_r(errnum, buf, buflen);
|
||||
|
||||
if (rv != 0) {
|
||||
if (buflen > 0) {
|
||||
buf[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2016 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef XSI_STRERROR_H
|
||||
#define XSI_STRERROR_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* Looks like error message is quite small, but we really don't know
|
||||
how much longer they become. */
|
||||
#define STRERROR_BUFSIZE 256
|
||||
|
||||
/*
|
||||
* Returns description of error denoted by |errnum|. The description
|
||||
* is written in |buf| of length |buflen| including terminal NULL. If
|
||||
* there is an error, including the case that buffer space is not
|
||||
* sufficient to include error message, and |buflen| > 0, empty string
|
||||
* is written to |buf|. This function returns |buf|.
|
||||
*/
|
||||
char *xsi_strerror(int errnum, char *buf, unsigned long buflen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* XSI_STRERROR_H */
|
Loading…
Reference in New Issue