author | Olivier Brunel
<jjk@jjacky.com> 2023-04-23 08:46:29 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-05-20 18:06:37 UTC |
parent | a688eae8f3121d037b522d25f579b0bd7892be5f |
src/doc/term.h.0.md | +3 | -0 |
src/doc/term.h/ask_password.3.md | +9 | -6 |
src/doc/term.h/term_ensurefg.3.md | +36 | -0 |
src/liblimb/include/limb/term.h | +1 | -0 |
src/liblimb/term.h/ask_password.c | +3 | -0 |
src/liblimb/term.h/term_ensurefg.c | +20 | -0 |
diff --git a/src/doc/term.h.0.md b/src/doc/term.h.0.md index 7e3e94e..0ed77f8 100644 --- a/src/doc/term.h.0.md +++ b/src/doc/term.h.0.md @@ -24,3 +24,6 @@ The following functions are defined : : [term_echo](3) :: To enable/disable echoing of input characters from a terminal. + +: [term_ensurefg](3) +:: To ensure current process is in the foreground job if needed. diff --git a/src/doc/term.h/ask_password.3.md b/src/doc/term.h/ask_password.3.md index 0bbeb3f..e7718c4 100644 --- a/src/doc/term.h/ask_password.3.md +++ b/src/doc/term.h/ask_password.3.md @@ -18,8 +18,11 @@ ssize_t ask_password(char *<em>dst</em>, size_t <em>dlen</em>, const char *<em>p The `ask_password`() function will read data from *stdin* up to a newline (`\n`) and store it into the memory area pointed by `dst`, up to `dlen` bytes. -First, it will ensure input character echoing is disabled for *stdin*, then drop -any data that might remain in `buffer_0`. +First, it will ensure that the current process is in the foreground process +group of its controlling terminal /if/ said terminal is referred to by *stdin*, +then make sure input character echoing is disabled for *stdin* for the duration +on the password input, and finally drop any data that might remain in +`buffer_0`. If `prompt` is not NULL, it will be written to *stderr* before attempting to read from *stdin*, unless it begins with `>` in which case it is written (past @@ -54,15 +57,15 @@ Otherwise it returns -1 and sets `errno` to indicate the error. # ERRORS The `ask_password`() function may fail and set `errno` for any of the errors -described for [term_echo](3) and [buffer_getuptoc](3), with the following -exceptions : +described for [term_ensurefg](3), [term_echo](3) and [buffer_getuptoc](3), with +the following exceptions : : *EINVAL* :: The argument for [buffer_getuptoc](3) cannot be invalid. : *ENOTTY* -:: If [term_echo](3) fails with *ENOTTY* when disabling input character echoing, -:: `ask_password`() simply ignores it and attempts to proceed as normal. +:: If [term_ensurefg](3) or [term_echo](3) fails with *ENOTTY* `ask_password`() +:: simply ignores it and attempts to proceed as normal. : *EPIPE* :: If [buffer_getuptoc](3) fails with *EPIPE* it means end of file was reached, diff --git a/src/doc/term.h/term_ensurefg.3.md b/src/doc/term.h/term_ensurefg.3.md new file mode 100644 index 0000000..4cb0160 --- /dev/null +++ b/src/doc/term.h/term_ensurefg.3.md @@ -0,0 +1,36 @@ +% limb manual +% term_ensurefg(3) + +# NAME + +term\_ensurefg - ensure current process is in the foreground job if needed + +# SYNOPSIS + + #include <limb/term.h> + +```pre hl +int term_ensurefg(int <em>fd</em>) +``` + +# DESCRIPTION + +The `term_ensurefg`() function will make sure the current process is in the +foreground process group of its controlling terminal, which must be referred to +by `fd`. + +! NOTE: +! To do so, the *SIGTTOU* signal will be ignored during the execution of the +! function (so it doesn't get send and blocks the process whilst setting the +! terminal foreground process group) then restored to its original handling +! state. + +# RETURN VALUE + +The `term_ensurefg`() function returns 1 on success, otherwise it returns 0 and +sets `errno` to indicate the error. + +# ERRORS + +The `term_ensurefg`() function may fail and set `errno` for any of the errors +described for [tcsetpgrp](3) except *EINVAL* and *EPERM*. diff --git a/src/liblimb/include/limb/term.h b/src/liblimb/include/limb/term.h index f948d93..4b1be45 100644 --- a/src/liblimb/include/limb/term.h +++ b/src/liblimb/include/limb/term.h @@ -6,6 +6,7 @@ #include <sys/types.h> /* {,s}size_t */ +extern int term_ensurefg(int fd); extern int term_echo(int fd, int want); extern ssize_t ask_password(char *dst, size_t dlen, const char *prompt); diff --git a/src/liblimb/term.h/ask_password.c b/src/liblimb/term.h/ask_password.c index 8a2afe6..fa2fbd2 100644 --- a/src/liblimb/term.h/ask_password.c +++ b/src/liblimb/term.h/ask_password.c @@ -9,6 +9,9 @@ ssize_t ask_password(char *dst, size_t dlen, const char *prompt) { + if (!term_ensurefg(buffer_fd(buffer_0)) && errno != ENOTTY) + return -1; + int echo = term_echo(buffer_fd(buffer_0), 0); if (echo < 0) { if (errno != ENOTTY) return -1; diff --git a/src/liblimb/term.h/term_ensurefg.c b/src/liblimb/term.h/term_ensurefg.c new file mode 100644 index 0000000..b59dca8 --- /dev/null +++ b/src/liblimb/term.h/term_ensurefg.c @@ -0,0 +1,20 @@ +/* This file is part of limb https://lila.oss/limb + * Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include <signal.h> +#include <unistd.h> +#include <limb/term.h> + +int +term_ensurefg(int fd) +{ + struct sigaction oact; + struct sigaction act = { .sa_handler = SIG_IGN, .sa_flags = SA_RESTART }; + int r; + + sigaction(SIGTTOU, &act, &oact); + r = tcsetpgrp(fd, getpgid(0)); + sigaction(SIGTTOU, &oact, NULL); + + return !r; +}