mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-30 05:48:18 +00:00
Merge sudo 1.9.11p3 from tip.
--HG-- branch : 1.9
This commit is contained in:
commit
b9dab8cdad
11
NEWS
11
NEWS
@ -1,3 +1,14 @@
|
|||||||
|
What's new in Sudo 1.9.11p3
|
||||||
|
|
||||||
|
* Fixed "connection reset" errors on AIX when running shell scripts
|
||||||
|
with the "intercept" or "log_subcmds" sudoers options enabled.
|
||||||
|
Bug #1034.
|
||||||
|
|
||||||
|
* Fixed very slow execution of shell scripts when the "intercept"
|
||||||
|
or "log_subcmds" sudoers options are set on systems that enable
|
||||||
|
Nagle's algorithm on the loopback device, such as AIX.
|
||||||
|
Bug #1034.
|
||||||
|
|
||||||
What's new in Sudo 1.9.11p2
|
What's new in Sudo 1.9.11p2
|
||||||
|
|
||||||
* Fixed a compilation error on Linux/x86_64 with the x32 ABI.
|
* Fixed a compilation error on Linux/x86_64 with the x32 ABI.
|
||||||
|
18
configure
vendored
18
configure
vendored
@ -1,6 +1,6 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.71 for sudo 1.9.11p2.
|
# Generated by GNU Autoconf 2.71 for sudo 1.9.11p3.
|
||||||
#
|
#
|
||||||
# Report bugs to <https://bugzilla.sudo.ws/>.
|
# Report bugs to <https://bugzilla.sudo.ws/>.
|
||||||
#
|
#
|
||||||
@ -621,8 +621,8 @@ MAKEFLAGS=
|
|||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='sudo'
|
PACKAGE_NAME='sudo'
|
||||||
PACKAGE_TARNAME='sudo'
|
PACKAGE_TARNAME='sudo'
|
||||||
PACKAGE_VERSION='1.9.11p2'
|
PACKAGE_VERSION='1.9.11p3'
|
||||||
PACKAGE_STRING='sudo 1.9.11p2'
|
PACKAGE_STRING='sudo 1.9.11p3'
|
||||||
PACKAGE_BUGREPORT='https://bugzilla.sudo.ws/'
|
PACKAGE_BUGREPORT='https://bugzilla.sudo.ws/'
|
||||||
PACKAGE_URL=''
|
PACKAGE_URL=''
|
||||||
|
|
||||||
@ -1640,7 +1640,7 @@ if test "$ac_init_help" = "long"; then
|
|||||||
# Omit some internal or obsolete options to make the list less imposing.
|
# Omit some internal or obsolete options to make the list less imposing.
|
||||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||||
cat <<_ACEOF
|
cat <<_ACEOF
|
||||||
\`configure' configures sudo 1.9.11p2 to adapt to many kinds of systems.
|
\`configure' configures sudo 1.9.11p3 to adapt to many kinds of systems.
|
||||||
|
|
||||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
@ -1706,7 +1706,7 @@ fi
|
|||||||
|
|
||||||
if test -n "$ac_init_help"; then
|
if test -n "$ac_init_help"; then
|
||||||
case $ac_init_help in
|
case $ac_init_help in
|
||||||
short | recursive ) echo "Configuration of sudo 1.9.11p2:";;
|
short | recursive ) echo "Configuration of sudo 1.9.11p3:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
@ -1996,7 +1996,7 @@ fi
|
|||||||
test -n "$ac_init_help" && exit $ac_status
|
test -n "$ac_init_help" && exit $ac_status
|
||||||
if $ac_init_version; then
|
if $ac_init_version; then
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
sudo configure 1.9.11p2
|
sudo configure 1.9.11p3
|
||||||
generated by GNU Autoconf 2.71
|
generated by GNU Autoconf 2.71
|
||||||
|
|
||||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
@ -2653,7 +2653,7 @@ cat >config.log <<_ACEOF
|
|||||||
This file contains any messages produced by compilers while
|
This file contains any messages produced by compilers while
|
||||||
running configure, to aid debugging if configure makes a mistake.
|
running configure, to aid debugging if configure makes a mistake.
|
||||||
|
|
||||||
It was created by sudo $as_me 1.9.11p2, which was
|
It was created by sudo $as_me 1.9.11p3, which was
|
||||||
generated by GNU Autoconf 2.71. Invocation command line was
|
generated by GNU Autoconf 2.71. Invocation command line was
|
||||||
|
|
||||||
$ $0$ac_configure_args_raw
|
$ $0$ac_configure_args_raw
|
||||||
@ -33050,7 +33050,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||||||
# report actual input values of CONFIG_FILES etc. instead of their
|
# report actual input values of CONFIG_FILES etc. instead of their
|
||||||
# values after options handling.
|
# values after options handling.
|
||||||
ac_log="
|
ac_log="
|
||||||
This file was extended by sudo $as_me 1.9.11p2, which was
|
This file was extended by sudo $as_me 1.9.11p3, which was
|
||||||
generated by GNU Autoconf 2.71. Invocation command line was
|
generated by GNU Autoconf 2.71. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
@ -33118,7 +33118,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
|
|||||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||||
ac_cs_config='$ac_cs_config_escaped'
|
ac_cs_config='$ac_cs_config_escaped'
|
||||||
ac_cs_version="\\
|
ac_cs_version="\\
|
||||||
sudo config.status 1.9.11p2
|
sudo config.status 1.9.11p3
|
||||||
configured by $0, generated by GNU Autoconf 2.71,
|
configured by $0, generated by GNU Autoconf 2.71,
|
||||||
with options \\"\$ac_cs_config\\"
|
with options \\"\$ac_cs_config\\"
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ dnl ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|||||||
dnl OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
dnl OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
dnl
|
dnl
|
||||||
AC_PREREQ([2.70])
|
AC_PREREQ([2.70])
|
||||||
AC_INIT([sudo], [1.9.11p2], [https://bugzilla.sudo.ws/], [sudo])
|
AC_INIT([sudo], [1.9.11p3], [https://bugzilla.sudo.ws/], [sudo])
|
||||||
AC_CONFIG_HEADERS([config.h pathnames.h])
|
AC_CONFIG_HEADERS([config.h pathnames.h])
|
||||||
AC_CONFIG_SRCDIR([src/sudo.c])
|
AC_CONFIG_SRCDIR([src/sudo.c])
|
||||||
AC_CONFIG_AUX_DIR([scripts])
|
AC_CONFIG_AUX_DIR([scripts])
|
||||||
|
@ -66,7 +66,11 @@ int
|
|||||||
sudo_getgrouplist2_v1(const char *name, GETGROUPS_T basegid,
|
sudo_getgrouplist2_v1(const char *name, GETGROUPS_T basegid,
|
||||||
GETGROUPS_T **groupsp, int *ngroupsp)
|
GETGROUPS_T **groupsp, int *ngroupsp)
|
||||||
{
|
{
|
||||||
|
#ifdef __APPLE__
|
||||||
|
int *groups = (int *)*groupsp;
|
||||||
|
#else
|
||||||
GETGROUPS_T *groups = *groupsp;
|
GETGROUPS_T *groups = *groupsp;
|
||||||
|
#endif
|
||||||
int ngroups;
|
int ngroups;
|
||||||
#ifndef HAVE_GETGROUPLIST_2
|
#ifndef HAVE_GETGROUPLIST_2
|
||||||
int grpsize, tries;
|
int grpsize, tries;
|
||||||
|
@ -573,15 +573,15 @@ log_allowed(struct eventlog *evlog)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
log_exit_status(int exit_status)
|
log_exit_status(int status)
|
||||||
{
|
{
|
||||||
struct eventlog evlog;
|
struct eventlog evlog;
|
||||||
int evl_flags = 0;
|
int evl_flags = 0;
|
||||||
int ecode = 0;
|
int exit_value = 0;
|
||||||
int oldlocale;
|
int oldlocale;
|
||||||
struct timespec run_time;
|
struct timespec run_time;
|
||||||
char sigbuf[SIG2STR_MAX];
|
char sigbuf[SIG2STR_MAX];
|
||||||
char *signame = NULL;
|
char *signal_name = NULL;
|
||||||
bool dumped_core = false;
|
bool dumped_core = false;
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
debug_decl(log_exit_status, SUDOERS_DEBUG_LOGGING);
|
debug_decl(log_exit_status, SUDOERS_DEBUG_LOGGING);
|
||||||
@ -594,17 +594,17 @@ log_exit_status(int exit_status)
|
|||||||
}
|
}
|
||||||
sudo_timespecsub(&run_time, &sudo_user.submit_time, &run_time);
|
sudo_timespecsub(&run_time, &sudo_user.submit_time, &run_time);
|
||||||
|
|
||||||
if (WIFEXITED(exit_status)) {
|
if (WIFEXITED(status)) {
|
||||||
ecode = WEXITSTATUS(exit_status);
|
exit_value = WEXITSTATUS(status);
|
||||||
} else if (WIFSIGNALED(exit_status)) {
|
} else if (WIFSIGNALED(status)) {
|
||||||
int signo = WTERMSIG(exit_status);
|
int signo = WTERMSIG(status);
|
||||||
if (signo <= 0 || sig2str(signo, sigbuf) == -1)
|
if (signo <= 0 || sig2str(signo, sigbuf) == -1)
|
||||||
(void)snprintf(sigbuf, sizeof(sigbuf), "%d", signo);
|
(void)snprintf(sigbuf, sizeof(sigbuf), "%d", signo);
|
||||||
signame = sigbuf;
|
signal_name = sigbuf;
|
||||||
ecode = signo | 128;
|
exit_value = signo | 128;
|
||||||
dumped_core = WCOREDUMP(exit_status);
|
dumped_core = WCOREDUMP(status);
|
||||||
} else {
|
} else {
|
||||||
sudo_warnx("invalid exit status 0x%x", exit_status);
|
sudo_warnx("invalid exit status 0x%x", status);
|
||||||
ret = false;
|
ret = false;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -619,8 +619,8 @@ log_exit_status(int exit_status)
|
|||||||
SET(evl_flags, EVLOG_MAIL_ONLY);
|
SET(evl_flags, EVLOG_MAIL_ONLY);
|
||||||
}
|
}
|
||||||
evlog.run_time = run_time;
|
evlog.run_time = run_time;
|
||||||
evlog.exit_value = ecode;
|
evlog.exit_value = exit_value;
|
||||||
evlog.signal_name = signame;
|
evlog.signal_name = signal_name;
|
||||||
evlog.dumped_core = dumped_core;
|
evlog.dumped_core = dumped_core;
|
||||||
if (!eventlog_exit(&evlog, evl_flags))
|
if (!eventlog_exit(&evlog, evl_flags))
|
||||||
ret = false;
|
ret = false;
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
|
||||||
#if defined(HAVE_STDINT_H)
|
#if defined(HAVE_STDINT_H)
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
@ -560,8 +561,12 @@ intercept_read(int fd, struct intercept_closure *closure)
|
|||||||
case false:
|
case false:
|
||||||
goto done;
|
goto done;
|
||||||
default:
|
default:
|
||||||
if (errno == EINTR || errno == EAGAIN)
|
if (errno == EINTR || errno == EAGAIN) {
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
|
sudo_debug_printf(
|
||||||
|
SUDO_DEBUG_WARN|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
|
||||||
|
"reading intercept token");
|
||||||
|
}
|
||||||
sudo_warn("recv");
|
sudo_warn("recv");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -574,8 +579,12 @@ intercept_read(int fd, struct intercept_closure *closure)
|
|||||||
nread = recv(fd, &req_len, sizeof(req_len), 0);
|
nread = recv(fd, &req_len, sizeof(req_len), 0);
|
||||||
if (nread != sizeof(req_len)) {
|
if (nread != sizeof(req_len)) {
|
||||||
if (nread == -1) {
|
if (nread == -1) {
|
||||||
if (errno == EINTR || errno == EAGAIN)
|
if (errno == EINTR || errno == EAGAIN) {
|
||||||
|
sudo_debug_printf(
|
||||||
|
SUDO_DEBUG_WARN|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
|
||||||
|
"reading intercept message size");
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
|
}
|
||||||
sudo_warn("recv");
|
sudo_warn("recv");
|
||||||
}
|
}
|
||||||
goto done;
|
goto done;
|
||||||
@ -605,8 +614,12 @@ intercept_read(int fd, struct intercept_closure *closure)
|
|||||||
/* EOF, other side must have exited. */
|
/* EOF, other side must have exited. */
|
||||||
goto done;
|
goto done;
|
||||||
case -1:
|
case -1:
|
||||||
if (errno == EINTR || errno == EAGAIN)
|
if (errno == EINTR || errno == EAGAIN) {
|
||||||
|
sudo_debug_printf(
|
||||||
|
SUDO_DEBUG_WARN|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
|
||||||
|
"reading intercept message");
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
|
}
|
||||||
sudo_warn("recv");
|
sudo_warn("recv");
|
||||||
goto done;
|
goto done;
|
||||||
default:
|
default:
|
||||||
@ -835,8 +848,12 @@ intercept_write(int fd, struct intercept_closure *closure)
|
|||||||
nwritten = send(fd, closure->buf + closure->off,
|
nwritten = send(fd, closure->buf + closure->off,
|
||||||
closure->len - closure->off, 0);
|
closure->len - closure->off, 0);
|
||||||
if (nwritten == -1) {
|
if (nwritten == -1) {
|
||||||
if (errno == EINTR || errno == EAGAIN)
|
if (errno == EINTR || errno == EAGAIN) {
|
||||||
|
sudo_debug_printf(
|
||||||
|
SUDO_DEBUG_WARN|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
|
||||||
|
"writing intercept message");
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
|
}
|
||||||
sudo_warn("send");
|
sudo_warn("send");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -930,7 +947,7 @@ intercept_accept_cb(int fd, int what, void *v)
|
|||||||
struct sudo_event_base *evbase = sudo_ev_get_base(&closure->ev);
|
struct sudo_event_base *evbase = sudo_ev_get_base(&closure->ev);
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
socklen_t sin_len = sizeof(sin);
|
socklen_t sin_len = sizeof(sin);
|
||||||
int client_sock, flags;
|
int client_sock, flags, on = 1;
|
||||||
debug_decl(intercept_accept_cb, SUDO_DEBUG_EXEC);
|
debug_decl(intercept_accept_cb, SUDO_DEBUG_EXEC);
|
||||||
|
|
||||||
if (closure->state != RECV_CONNECTION) {
|
if (closure->state != RECV_CONNECTION) {
|
||||||
@ -951,6 +968,9 @@ intercept_accept_cb(int fd, int what, void *v)
|
|||||||
if (flags != -1)
|
if (flags != -1)
|
||||||
(void)fcntl(client_sock, F_SETFL, flags | O_NONBLOCK);
|
(void)fcntl(client_sock, F_SETFL, flags | O_NONBLOCK);
|
||||||
|
|
||||||
|
/* Send data immediately, we need low latency IPC. */
|
||||||
|
(void)setsockopt(client_sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a new intercept closure and register an event for client_sock.
|
* Create a new intercept closure and register an event for client_sock.
|
||||||
*/
|
*/
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
|
||||||
#if defined(HAVE_STDINT_H)
|
#if defined(HAVE_STDINT_H)
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
@ -136,16 +137,29 @@ recv_intercept_response(int fd)
|
|||||||
debug_decl(recv_intercept_response, SUDO_DEBUG_EXEC);
|
debug_decl(recv_intercept_response, SUDO_DEBUG_EXEC);
|
||||||
|
|
||||||
/* Read message size (uint32_t in host byte order). */
|
/* Read message size (uint32_t in host byte order). */
|
||||||
nread = recv(fd, &res_len, sizeof(res_len), 0);
|
for (;;) {
|
||||||
if ((size_t)nread != sizeof(res_len)) {
|
nread = recv(fd, &res_len, sizeof(res_len), 0);
|
||||||
if (nread == 0) {
|
if (nread == ssizeof(res_len))
|
||||||
|
break;
|
||||||
|
switch (nread) {
|
||||||
|
case 0:
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"unexpected EOF reading response size");
|
"unexpected EOF reading response size");
|
||||||
} else {
|
break;
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
case -1:
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
|
sudo_debug_printf(
|
||||||
|
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
"error reading response size");
|
"error reading response size");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sudo_debug_printf(
|
||||||
|
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"error reading response size: short read");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (res_len > MESSAGE_SIZE_MAX) {
|
if (res_len > MESSAGE_SIZE_MAX) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
@ -169,7 +183,8 @@ recv_intercept_response(int fd)
|
|||||||
case -1:
|
case -1:
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
sudo_debug_printf(
|
||||||
|
SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
"error reading response");
|
"error reading response");
|
||||||
goto done;
|
goto done;
|
||||||
default:
|
default:
|
||||||
@ -199,7 +214,7 @@ sudo_interposer_init(void)
|
|||||||
{
|
{
|
||||||
InterceptResponse *res = NULL;
|
InterceptResponse *res = NULL;
|
||||||
static bool initialized;
|
static bool initialized;
|
||||||
int fd = -1;
|
int flags, fd = -1;
|
||||||
char **p;
|
char **p;
|
||||||
debug_decl(sudo_interposer_init, SUDO_DEBUG_EXEC);
|
debug_decl(sudo_interposer_init, SUDO_DEBUG_EXEC);
|
||||||
|
|
||||||
@ -239,6 +254,13 @@ sudo_interposer_init(void)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We don't want to use non-blocking I/O.
|
||||||
|
*/
|
||||||
|
flags = fcntl(fd, F_GETFL, 0);
|
||||||
|
if (flags != -1)
|
||||||
|
(void)fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send InterceptHello message to over the fd.
|
* Send InterceptHello message to over the fd.
|
||||||
*/
|
*/
|
||||||
@ -334,6 +356,7 @@ static int
|
|||||||
intercept_connect(void)
|
intercept_connect(void)
|
||||||
{
|
{
|
||||||
int sock = -1;
|
int sock = -1;
|
||||||
|
int on = 1;
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
debug_decl(command_allowed, SUDO_DEBUG_EXEC);
|
debug_decl(command_allowed, SUDO_DEBUG_EXEC);
|
||||||
|
|
||||||
@ -353,6 +376,9 @@ intercept_connect(void)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Send data immediately, we need low latency IPC. */
|
||||||
|
(void)setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
|
||||||
|
|
||||||
if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
|
if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
|
||||||
sudo_warn("connect");
|
sudo_warn("connect");
|
||||||
close(sock);
|
close(sock);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user