aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2026-09-11 13:13:33 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2026-09-11 13:13:33 +0000
commit612edc04f50526ba4e21e4e65142a34f964f95ef (patch)
tree5a7e7386e679cf95dccb581362fafcbe4b5cc0b0 /src
parent4344d34242c27734a2940ab5f995c7b9fb4803e2 (diff)
downloads6-main.tar.gz
s6-sudod: fix client error reporting missing in several placesHEADmain
Diffstat (limited to 'src')
-rw-r--r--src/conn-tools/s6-sudod.c96
1 files changed, 63 insertions, 33 deletions
diff --git a/src/conn-tools/s6-sudod.c b/src/conn-tools/s6-sudod.c
index c455c32..bc82917 100644
--- a/src/conn-tools/s6-sudod.c
+++ b/src/conn-tools/s6-sudod.c
@@ -58,16 +58,33 @@ static int handle_signals (pid_t pid, int *wstat)
}
}
+static void fail (int e)
+{
+ tain deadline ;
+ char c = e ;
+ buffer_putnoflush(buffer_1small, &c, 1) ;
+ tain_addsec_g(&deadline, 1) ;
+ if (!buffer_timed_flush_g(buffer_1small, &deadline))
+ strerr_diefusys(111, "send error code to client") ;
+}
+
+static void faile (void)
+{
+ int e = errno ;
+ fail(e) ;
+ errno = e ;
+}
+
int main (int argc, char const *const *argv, char const *const *envp)
{
iopause_fd x[2] = { { .events = IOPAUSE_READ }, { .fd = 0, .events = 0, .revents = 0 } } ;
unixmessage m ;
+ tain deadline = TAIN_INFINITE_RELATIVE ;
unsigned int nullfds = 0 ;
pid_t pid ;
int wstat ;
size_t envc = env_len(envp) ;
uint32_t cargc, cenvc, carglen, cenvlen ;
- tain deadline = TAIN_INFINITE_RELATIVE ;
PROG = "s6-sudod" ;
{
@@ -91,42 +108,51 @@ int main (int argc, char const *const *argv, char const *const *envp)
if (t) tain_from_millisecs(&deadline, t) ;
}
- if ((ndelay_on(0) < 0) || (ndelay_on(1) < 0))
- strerr_diefu1sys(111, "make socket non-blocking") ;
+ if ((ndelay_on(0) == -1) || (ndelay_on(1) == -1))
+ strerr_diefusys(111, "make socket non-blocking") ;
tain_now_set_stopwatch_g() ;
tain_add_g(&deadline, &deadline) ;
buffer_putnoflush(buffer_1small, S6_SUDO_BANNERB, S6_SUDO_BANNERB_LEN) ;
if (!buffer_timed_flush_g(buffer_1small, &deadline))
- strerr_diefu1sys(111, "write banner to client") ;
+ strerr_diefusys(111, "write banner to client") ;
+
if (unixmessage_timed_receive_g(unixmessage_receiver_0, &m, &deadline) <= 0)
- strerr_diefu1sys(111, "read message from client") ;
+ strerr_diefusys(111, "read message from client") ;
if (m.nfds != 3)
- strerr_dief1x(100, "client did not send 3 fds") ;
+ strerr_dief(100, "client did not send 3 fds") ;
if (m.len < 16 + S6_SUDO_BANNERA_LEN)
- strerr_dief1x(100, "wrong client message") ;
+ strerr_dief(100, "wrong client message") ;
if (strncmp(m.s, S6_SUDO_BANNERA, S6_SUDO_BANNERA_LEN))
- strerr_dief1x(100, "wrong client banner") ;
+ strerr_dief(100, "wrong client banner") ;
uint32_unpack_big(m.s + S6_SUDO_BANNERA_LEN, &cargc) ;
uint32_unpack_big(m.s + S6_SUDO_BANNERA_LEN + 4, &cenvc) ;
uint32_unpack_big(m.s + S6_SUDO_BANNERA_LEN + 8, &carglen) ;
uint32_unpack_big(m.s + S6_SUDO_BANNERA_LEN + 12, &cenvlen) ;
if (S6_SUDO_BANNERA_LEN + 16 + carglen + cenvlen != m.len)
- strerr_dief1x(100, "wrong client argc/envlen") ;
+ strerr_dief(100, "wrong client argc/envlen") ;
if ((cargc > 131072) || (cenvc > 131072))
- strerr_dief1x(100, "too many args/envvars from client") ;
- if (argc + cargc == 0) strerr_dief1x(100, "client and server args both empty") ;
+ strerr_dief(100, "too many args/envvars from client") ;
+ if (argc + cargc == 0) strerr_dief(100, "client and server args both empty") ;
if (nullfds & 1)
{
close(m.fds[0]) ;
m.fds[0] = open2("/dev/null", O_RDONLY) ;
- if (m.fds[0] < 0) strerr_diefu2sys(111, "open /dev/null for ", "reading") ;
+ if (m.fds[0] < 0)
+ {
+ faile() ;
+ strerr_diefusys(111, "open /dev/null for ", "reading") ;
+ }
}
if (nullfds & 2)
{
close(m.fds[1]) ;
m.fds[1] = open2("/dev/null", O_WRONLY) ;
- if (m.fds[1] < 0) strerr_diefu2sys(111, "open /dev/null for ", "writing") ;
+ if (m.fds[1] < 0)
+ {
+ faile() ;
+ strerr_diefusys(111, "open /dev/null for ", "writing") ;
+ }
}
if (nullfds & 4)
{
@@ -148,18 +174,12 @@ int main (int argc, char const *const *argv, char const *const *envp)
for (i = 0 ; i <= envc ; i++) tenvp[i] = envp[i] ;
if (!env_make(targv + argc, cargc, m.s + S6_SUDO_BANNERA_LEN + 16, carglen))
{
- char c = errno ;
- buffer_putnoflush(buffer_1small, &c, 1) ;
- buffer_timed_flush_g(buffer_1small, &deadline) ;
- errno = c ;
+ faile() ;
strerr_diefu1sys(111, "make child argv") ;
}
if (!env_make(tenvp + envc + 1, cenvc, m.s + S6_SUDO_BANNERA_LEN + 16 + carglen, cenvlen))
{
- char c = errno ;
- buffer_putnoflush(buffer_1small, &c, 1) ;
- buffer_timed_flush_g(buffer_1small, &deadline) ;
- errno = c ;
+ faile() ;
strerr_diefu1sys(111, "make child envp") ;
}
targv[argc + cargc] = 0 ;
@@ -171,21 +191,31 @@ int main (int argc, char const *const *argv, char const *const *envp)
size_t len = str_chr(var, '=') ;
if (!var[len])
{
- char c = EINVAL ;
- buffer_putnoflush(buffer_1small, &c, 1) ;
- buffer_timed_flush_g(buffer_1small, &deadline) ;
- strerr_dief1x(100, "bad environment from client") ;
+ fail(EINVAL) ;
+ strerr_dief(100, "bad environment from client") ;
}
for (; j < envc ; j++) if (!strncmp(var, tenvp[j], len+1)) break ;
if ((j < envc) && !tenvp[j][len+1]) tenvp[j] = var ;
}
x[0].fd = selfpipe_init() ;
- if (x[0].fd < 0) strerr_diefu1sys(111, "selfpipe_init") ;
- if (!selfpipe_trap(SIGCHLD)) strerr_diefu1sys(111, "trap SIGCHLD") ;
+ if (x[0].fd == -1)
+ {
+ faile() ;
+ strerr_diefusys(111, "selfpipe_init") ;
+ }
+ if (!selfpipe_trap(SIGCHLD))
+ {
+ faile() ;
+ strerr_diefusys(111, "trap SIGCHLD") ;
+ }
pid = cspawn(targv[0], targv, tenvp, CSPAWN_FLAGS_SELFPIPE_FINISH, fa, 3) ;
- if (!pid) strerr_diefu2sys(111, "spawn ", targv[0]) ;
+ if (!pid)
+ {
+ faile() ;
+ strerr_diefusys(111, "spawn ", targv[0]) ;
+ }
}
fd_close(m.fds[0]) ;
@@ -194,11 +224,11 @@ int main (int argc, char const *const *argv, char const *const *envp)
unixmessage_receiver_free(unixmessage_receiver_0) ;
buffer_putnoflush(buffer_1small, "", 1) ;
if (!buffer_timed_flush_g(buffer_1small, &deadline))
- strerr_diefu1sys(111, "send confirmation to client") ;
+ strerr_diefusys(111, "send confirmation to client") ;
for (;;)
{
- if (iopause_g(x, 1 + !x[1].revents, 0) < 0) strerr_diefu1sys(111, "iopause") ;
+ if (iopause_g(x, 1 + !x[1].revents, 0) == -1) strerr_diefusys(111, "iopause") ;
if (x[0].revents && handle_signals(pid, &wstat)) break ;
if (x[1].revents && !(nullfds & 8))
{
@@ -213,10 +243,10 @@ int main (int argc, char const *const *argv, char const *const *envp)
char pack[UINT_PACK] ;
uint_pack_big(pack, (unsigned int)wstat) ;
buffer_putnoflush(buffer_1small, pack, UINT_PACK) ;
- if (ndelay_off(1) < 0)
- strerr_diefu1sys(111, "set stdout blocking") ;
+ if (ndelay_off(1) == -1)
+ strerr_diefusys(111, "set stdout blocking") ;
if (!buffer_flush(buffer_1small))
- strerr_diefu1sys(111, "write status to client") ;
+ strerr_diefusys(111, "write status to client") ;
}
return 0 ;
}