diff -u linux-2.4.x/arch/um/drivers/chan_kern.c --- linux-2.4.x/arch/um/drivers/chan_kern.c.orig +++ linux-2.4.x/arch/um/drivers/chan_kern.c 2003-12-03 10:49:11.000000000 +1000 @@ -175,13 +175,21 @@ * state. Then, the first one opened will have the original state, * so it must be the last closed. */ - for(ele = chans->prev; ele != chans; ele = ele->prev){ - chan = list_entry(ele, struct chan, list); - if(!chan->opened) continue; - if(chan->ops->close != NULL) - (*chan->ops->close)(chan->fd, chan->data); + for(ele = chans->prev; ele != chans; ele = prev){ + /* Note that the close function can trigger a signal + * which will close this channel from under us, so + * we need to do everything for the channel + * before we call close */ + int fd; + prev = ele->prev; + + chan = list_entry(ele, struct chan, list); + if (!chan->opened) continue; + fd = chan->fd; chan->opened = 0; chan->fd = -1; + if(chan->ops->close != NULL) + (*chan->ops->close)(fd, chan->data); } }