script: fix ECHO use, improve shell exec

For tools like su(1) is ECHO flag unexpected for use-case like

	echo 'date' | su - user

but script(1) need the echo to keep input recorded.

The patch also return execlp() use to script(1) code.

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2019-11-21 12:28:51 +01:00
parent 241f3f014e
commit 4169bcb766
3 changed files with 31 additions and 7 deletions

View File

@ -75,13 +75,15 @@ struct ul_pty {
struct timeval next_callback_time;
unsigned int isterm:1; /* is stdin terminal? */
unsigned int isterm:1, /* is stdin terminal? */
keep_slave_echo:1; /* keep ECHO on stdin */
};
void ul_pty_init_debug(int mask);
struct ul_pty *ul_new_pty(int is_stdin_tty);
void ul_free_pty(struct ul_pty *pty);
void ul_pty_keep_slave_echo(struct ul_pty *pty, int enable);
int ul_pty_get_delivered_signal(struct ul_pty *pty);
void ul_pty_set_callback_data(struct ul_pty *pty, void *data);

View File

@ -71,6 +71,11 @@ void ul_free_pty(struct ul_pty *pty)
free(pty);
}
void ul_pty_keep_slave_echo(struct ul_pty *pty, int enable)
{
assert(pty);
pty->keep_slave_echo = enable ? 1 : 0;
}
int ul_pty_get_delivered_signal(struct ul_pty *pty)
{
@ -175,8 +180,10 @@ int ul_pty_setup(struct ul_pty *pty)
if (!rc) {
tcgetattr(pty->slave, &slave_attrs);
slave_attrs.c_lflag &= ~ECHO;
tcsetattr(pty->slave, TCSANOW, &slave_attrs);
if (!pty->keep_slave_echo) {
slave_attrs.c_lflag &= ~ECHO;
tcsetattr(pty->slave, TCSANOW, &slave_attrs);
}
} else
goto done;
}

View File

@ -875,6 +875,13 @@ int main(int argc, char **argv)
if (!ctl.pty)
err(EXIT_FAILURE, "failed to allocate PTY handler");
if (!ctl.isterm)
/* We keep ECHO flag for 'echo "date" | script' otherwise the
* input is no visible (output is completely comtroled by
* shell/command, we do not write anything there).
*/
ul_pty_keep_slave_echo(ctl.pty, 1);
ul_pty_set_callback_data(ctl.pty, (void *) &ctl);
cb = ul_pty_get_callbacks(ctl.pty);
cb->child_die = callback_child_die;
@ -923,10 +930,18 @@ int main(int argc, char **argv)
shname = strrchr(shell, '/');
shname = shname ? shname + 1 : shell;
if (command)
execl(shell, shname, "-c", command, NULL);
else
execl(shell, shname, "-i", NULL);
if (access(shell, X_OK) == 0) {
if (command)
execl(shell, shname, "-c", command, NULL);
else
execl(shell, shname, "-i", NULL);
} else {
if (command)
execlp(shname, "-c", command, NULL);
else
execlp(shname, "-i", NULL);
}
err(EXIT_FAILURE, "failed to execute %s", shell);
break;
}