diff -Nru util-linux-2.27.1/debian/changelog util-linux-2.27.1/debian/changelog --- util-linux-2.27.1/debian/changelog 2016-03-30 21:11:01.000000000 +0000 +++ util-linux-2.27.1/debian/changelog 2016-04-13 15:04:59.000000000 +0000 @@ -1,3 +1,10 @@ +util-linux (2.27.1-6ubuntu3) xenial; urgency=medium + + * Add debian/patches/script-use-empty-slave.patch taken from + upstream git (LP: #1553353, Closes: #820843) + + -- Simon Deziel Wed, 13 Apr 2016 15:01:21 +0000 + util-linux (2.27.1-6ubuntu2) xenial; urgency=medium * Add upstream-lscpu-powerpc.patch: lscpu: Fix model and model name on Power diff -Nru util-linux-2.27.1/debian/patches/script-use-empty-slave.patch util-linux-2.27.1/debian/patches/script-use-empty-slave.patch --- util-linux-2.27.1/debian/patches/script-use-empty-slave.patch 1970-01-01 00:00:00.000000000 +0000 +++ util-linux-2.27.1/debian/patches/script-use-empty-slave.patch 2016-04-13 14:59:53.000000000 +0000 @@ -0,0 +1,142 @@ +From b2bff0666101213d5ce9fc4166d8fc5b17581f57 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Wed, 13 Apr 2016 11:52:43 +0200 +Subject: script: use empty-slave heuristic more carefully + +script(1) waits for empty slave FD (shell stdin) before it writes to +master. This feature has been intorduiced by 54c6611d6f7b73609a5331f4d0bcf63c4af6429e +to avoid misbehavior when we need to send EOF to the shell. + +Unfortunately, this feature has been used all time for all messages. +This is wrong because command in the session (or shell) may ignore +stdin at all and wait forever in busy loop is really bad idea. Test +case: + + script /dev/null + tailf /etc/passwd + + + +... script process taking 100% CPU. + +This patch forces script to use empty-stave detection only when we +need to write EOF. The busy loop has been modified to use nanosleep +and it does not wait forever... + +Addresses: http://bugs.debian.org/820843 +Signed-off-by: Karel Zak +--- + term-utils/script.c | 52 ++++++++++++++++++++++++++++------------------------ + 1 file changed, 28 insertions(+), 24 deletions(-) + +diff --git a/term-utils/script.c b/term-utils/script.c +index 23ca89c..1199742 100644 +--- a/term-utils/script.c ++++ b/term-utils/script.c +@@ -122,7 +122,6 @@ struct script_control { + timing:1, /* include timing file */ + force:1, /* write output to links */ + isterm:1, /* is child process running as terminal */ +- data_on_way:1, /* sent data to master */ + die:1; /* terminate program */ + + sigset_t sigset; /* catch SIGCHLD and SIGWINCH with signalfd() */ +@@ -276,15 +275,10 @@ static void write_output(struct script_control *ctl, char *obuf, + DBG(IO, ul_debug(" writing output *done*")); + } + +-static void wait_for_empty_fd(int fd) ++static int write_to_shell(struct script_control *ctl, ++ char *buf, size_t bufsz) + { +- struct pollfd fds[] = { +- { .fd = fd, .events = POLLIN } +- }; +- +- while (poll(fds, 1, 10) == 1) { +- DBG(IO, ul_debug(" data to read")); +- } ++ return write_all(ctl->master, buf, bufsz); + } + + /* +@@ -295,26 +289,32 @@ static void wait_for_empty_fd(int fd) + * problem we wait until slave is empty. For example: + * + * echo "date" | script ++ * ++ * Unfortunately, the child (usually shell) can ignore stdin at all, so we ++ * don't wait forever to avoid dead locks... ++ * ++ * Note that script is primarily designed for interactive sessions as it ++ * maintains master+slave tty stuff within the session. Use pipe to write to ++ * script(1) and assume non-interactive (tee-like) behavior is NOT well ++ * supported. + */ +-static int write_to_shell(struct script_control *ctl, char *buf, size_t bufsz) +-{ +- int rc; +- +- if (ctl->data_on_way) { +- wait_for_empty_fd(ctl->slave); +- ctl->data_on_way = 0; +- } +- rc = write_all(ctl->master, buf, bufsz); +- if (rc == 0) +- ctl->data_on_way = 1; +- return rc; +- +-} +- + static void write_eof_to_shell(struct script_control *ctl) + { ++ unsigned int tries = 0; ++ struct pollfd fds[] = { ++ { .fd = ctl->slave, .events = POLLIN } ++ }; + char c = DEF_EOF; + ++ DBG(IO, ul_debug(" waiting for empty slave")); ++ while (poll(fds, 1, 10) == 1 && tries < 8) { ++ DBG(IO, ul_debug(" slave is not empty")); ++ xusleep(250000); ++ tries++; ++ } ++ if (tries < 8) ++ DBG(IO, ul_debug(" slave is empty now")); ++ + DBG(IO, ul_debug(" sending EOF to master")); + write_to_shell(ctl, &c, sizeof(char)); + } +@@ -375,10 +375,12 @@ static void handle_signal(struct script_control *ctl, int fd) + + switch (info.ssi_signo) { + case SIGCHLD: ++ DBG(SIGNAL, ul_debug(" get signal SIGCHLD")); + wait_for_child(ctl, 0); + ctl->poll_timeout = 10; + return; + case SIGWINCH: ++ DBG(SIGNAL, ul_debug(" get signal SIGWINCH")); + if (ctl->isterm) { + ioctl(STDIN_FILENO, TIOCGWINSZ, (char *)&ctl->win); + ioctl(ctl->slave, TIOCSWINSZ, (char *)&ctl->win); +@@ -389,6 +391,7 @@ static void handle_signal(struct script_control *ctl, int fd) + case SIGINT: + /* fallthrough */ + case SIGQUIT: ++ DBG(SIGNAL, ul_debug(" get signal SIG{TERM,INT,QUIT}")); + fprintf(stderr, _("\nSession terminated.\n")); + /* Child termination is going to generate SIGCHILD (see above) */ + kill(ctl->child, SIGTERM); +@@ -485,6 +488,7 @@ static void do_io(struct script_control *ctl) + if (i == POLLFD_STDIN) { + ignore_stdin = 1; + write_eof_to_shell(ctl); ++ DBG(POLL, ul_debug(" ignore STDIN")); + } + } + continue; +-- +cgit v0.12 + diff -Nru util-linux-2.27.1/debian/patches/series util-linux-2.27.1/debian/patches/series --- util-linux-2.27.1/debian/patches/series 2016-03-30 21:06:57.000000000 +0000 +++ util-linux-2.27.1/debian/patches/series 2016-04-13 14:59:53.000000000 +0000 @@ -1,3 +1,4 @@ +script-use-empty-slave.patch upstream-lscpu-powerpc.patch Multiarch-support-in-util-linux-build.patch man-page-tweaks-cleanup-my_dev_t.h-ancient-stuff.patch