Skip to content

Commit 139e6e8

Browse files
benzearichardweinberger
authored andcommitted
um: Reap winch thread if it fails
When the winch thread runs into an error condition, it would exit(1) and never be reaped until shutdown time. Change this to write a command byte which causes the driver to kill it, therefore reaping the child. Signed-off-by: Benjamin Berg <benjamin@sipsolutions.net> Signed-off-by: Richard Weinberger <richard@nod.at>
1 parent 1818b84 commit 139e6e8

2 files changed

Lines changed: 19 additions & 10 deletions

File tree

arch/um/drivers/chan_user.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ struct winch_data {
141141
int pipe_fd;
142142
};
143143

144-
static int winch_thread(void *arg)
144+
static __noreturn int winch_thread(void *arg)
145145
{
146146
struct winch_data *data = arg;
147147
sigset_t sigs;
@@ -168,27 +168,27 @@ static int winch_thread(void *arg)
168168
if (sigprocmask(SIG_SETMASK, &sigs, NULL) < 0) {
169169
os_info("winch_thread : sigprocmask failed, errno = %d\n",
170170
errno);
171-
exit(1);
171+
goto wait_kill;
172172
}
173173
/* In sigsuspend(), block anything else than SIGWINCH. */
174174
sigdelset(&sigs, SIGWINCH);
175175

176176
if (setsid() < 0) {
177177
os_info("winch_thread : setsid failed, errno = %d\n",
178178
errno);
179-
exit(1);
179+
goto wait_kill;
180180
}
181181

182182
if (ioctl(pty_fd, TIOCSCTTY, 0) < 0) {
183183
os_info("winch_thread : TIOCSCTTY failed on "
184184
"fd %d err = %d\n", pty_fd, errno);
185-
exit(1);
185+
goto wait_kill;
186186
}
187187

188188
if (tcsetpgrp(pty_fd, os_getpid()) < 0) {
189189
os_info("winch_thread : tcsetpgrp failed on fd %d err = %d\n",
190190
pty_fd, errno);
191-
exit(1);
191+
goto wait_kill;
192192
}
193193

194194
/*
@@ -214,6 +214,12 @@ static int winch_thread(void *arg)
214214
os_info("winch_thread : write failed, err = %d\n",
215215
errno);
216216
}
217+
218+
wait_kill:
219+
c = 2;
220+
count = write(pipe_fd, &c, sizeof(c));
221+
while (1)
222+
pause();
217223
}
218224

219225
static int winch_tramp(int fd, struct tty_port *port, int *fd_out,

arch/um/drivers/line.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -629,15 +629,18 @@ static irqreturn_t winch_interrupt(int irq, void *data)
629629

630630
if (fd != -1) {
631631
err = generic_read(fd, &c, NULL);
632-
if (err < 0) {
632+
/* A read of 2 means the winch thread failed and has warned */
633+
if (err < 0 || (err == 1 && c == 2)) {
633634
if (err != -EAGAIN) {
634635
winch->fd = -1;
635636
list_del(&winch->list);
636637
os_close_file(fd);
637-
printk(KERN_ERR "winch_interrupt : "
638-
"read failed, errno = %d\n", -err);
639-
printk(KERN_ERR "fd %d is losing SIGWINCH "
640-
"support\n", winch->tty_fd);
638+
if (err < 0) {
639+
printk(KERN_ERR "winch_interrupt : read failed, errno = %d\n",
640+
-err);
641+
printk(KERN_ERR "fd %d is losing SIGWINCH support\n",
642+
winch->tty_fd);
643+
}
641644
INIT_WORK(&winch->work, __free_winch);
642645
schedule_work(&winch->work);
643646
return IRQ_HANDLED;

0 commit comments

Comments
 (0)