fix(db-tool): prevent fd leak from logger to long-running daemons
The hectic logger opens fd 3 as a dup of stderr. Child processes inherit this fd, and daemonized PostgreSQL/PostgREST keeping it open prevents the terminal from returning to the prompt after the spawning script exits. - Add with_closed_fds helper that runs commands in a subshell with fds 3-9 redirected to /dev/null - Inline the helper into both database and postgres-init builds - Wrap pg_ctl start and postgrest with the helper
This commit is contained in:
@@ -21,4 +21,7 @@ in {
|
|||||||
pager_or_cat = hectic.writeDash "pager_or_cat.sh" ''
|
pager_or_cat = hectic.writeDash "pager_or_cat.sh" ''
|
||||||
${builtins.readFile ./pager_or_cat.sh}
|
${builtins.readFile ./pager_or_cat.sh}
|
||||||
'';
|
'';
|
||||||
|
with_closed_fds = hectic.writeDash "with_closed_fds.sh" ''
|
||||||
|
${builtins.readFile ./with_closed_fds.sh}
|
||||||
|
'';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ log() {
|
|||||||
''
|
''
|
||||||
|
|
||||||
# shellcheck disable=SC1003
|
# shellcheck disable=SC1003
|
||||||
fmt="$(printf "%s$delimetr" "$@" | sed 's/\\033\[0m/''\'"$color"'/g')"
|
fmt="$(printf "%s$delimetr" "$@" | sed 's/\\033\[0m/'\'"$color"'/g')"
|
||||||
shift
|
shift
|
||||||
# shellcheck disable=SC1003
|
# shellcheck disable=SC1003
|
||||||
printf "${BBLACK}${HECTIC_NAMESPACE}> %b\n" "$color$fmt$NC" >&3
|
printf "${BBLACK}${HECTIC_NAMESPACE}> %b\n" "$color$fmt$NC" >&3
|
||||||
|
|||||||
22
legacy/helper/posix-shell/with_closed_fds.sh
Normal file
22
legacy/helper/posix-shell/with_closed_fds.sh
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/dash
|
||||||
|
|
||||||
|
# with_closed_fds -- run command with leaked file descriptors closed
|
||||||
|
#
|
||||||
|
# Shell libraries (e.g. hectic logger) may open extra file descriptors
|
||||||
|
# (like fd 3 as a dup of stderr). Child processes inherit these fds.
|
||||||
|
# Long-running daemons (postgres, postgrest) that keep fd 3 open can
|
||||||
|
# prevent the terminal from returning to the prompt even after the
|
||||||
|
# spawning script exits.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# with_closed_fds pg_ctl -D "$data" -w start
|
||||||
|
# with_closed_fds postgrest "$config" > "$log" 2>&1 &
|
||||||
|
#
|
||||||
|
# Runs the command in a subshell where fds 3-9 are redirected to
|
||||||
|
# /dev/null. The parent shell's fd table is untouched.
|
||||||
|
with_closed_fds() {
|
||||||
|
(
|
||||||
|
exec 3>/dev/null 4>/dev/null 5>/dev/null 6>/dev/null 7>/dev/null 8>/dev/null 9>/dev/null
|
||||||
|
"$@"
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -43,6 +43,7 @@ let
|
|||||||
${builtins.readFile hectic.helpers.posix-shell.change_namespace}
|
${builtins.readFile hectic.helpers.posix-shell.change_namespace}
|
||||||
${builtins.readFile hectic.helpers.posix-shell.quote}
|
${builtins.readFile hectic.helpers.posix-shell.quote}
|
||||||
${builtins.readFile hectic.helpers.posix-shell.pager_or_cat}
|
${builtins.readFile hectic.helpers.posix-shell.pager_or_cat}
|
||||||
|
${builtins.readFile hectic.helpers.posix-shell.with_closed_fds}
|
||||||
${hecticEnv}
|
${hecticEnv}
|
||||||
${applyBundle}
|
${applyBundle}
|
||||||
${builtins.readFile ./database.sh}
|
${builtins.readFile ./database.sh}
|
||||||
@@ -62,7 +63,11 @@ let
|
|||||||
name = "postgres-init";
|
name = "postgres-init";
|
||||||
runtimeInputs = [ postgresql coreutils ];
|
runtimeInputs = [ postgresql coreutils ];
|
||||||
|
|
||||||
text = builtins.readFile ./postgres-init.sh;
|
text = ''
|
||||||
|
${builtins.readFile hectic.helpers.posix-shell.with_closed_fds}
|
||||||
|
${builtins.readFile ./postgres-init.sh}
|
||||||
|
'';
|
||||||
|
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
description = "Initialize local PostgreSQL instance";
|
description = "Initialize local PostgreSQL instance";
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ postgres_init_main() {
|
|||||||
sed -i '/^[[:space:]]*port[[:space:]]*=/d' "$data/postgresql.conf" || return 1
|
sed -i '/^[[:space:]]*port[[:space:]]*=/d' "$data/postgresql.conf" || return 1
|
||||||
sed -i '/^[[:space:]]*unix_socket_directories[[:space:]]*=/d' "$data/postgresql.conf" || return 1
|
sed -i '/^[[:space:]]*unix_socket_directories[[:space:]]*=/d' "$data/postgresql.conf" || return 1
|
||||||
{ printf '%s\n' "port = $PG_PORT"; printf '%s\n' "unix_socket_directories = '$sockdir'"; } >> "$data/postgresql.conf" || return 1
|
{ printf '%s\n' "port = $PG_PORT"; printf '%s\n' "unix_socket_directories = '$sockdir'"; } >> "$data/postgresql.conf" || return 1
|
||||||
pg_ctl -D "$data" -o "-F" -w start || return 2
|
with_closed_fds pg_ctl -D "$data" -o "-F" -w start || return 2
|
||||||
|
|
||||||
user="$(id -un)" || return 1
|
user="$(id -un)" || return 1
|
||||||
if [ "$PG_REUSE" -eq 0 ]; then
|
if [ "$PG_REUSE" -eq 0 ]; then
|
||||||
|
|||||||
Reference in New Issue
Block a user