From 03f6a8529c6ac8c9d60eb7e2febe114ba3d22645 Mon Sep 17 00:00:00 2001 From: Brian Barrett Date: Sat, 4 Feb 2006 23:26:58 +0000 Subject: [PATCH] * Fix situation where we were unlocking a mutex we didn't own in an error cleanup code in the signal part of the event library * Only attempt to forward standard input if we have a controlling terminal (isatty() returns 1) and we are the foreground process OR we do not have a controlling terminal (isatty() returns 0). If we have a controlling terminal, check at each SIGCONT if we should change our forwarding, since our foreground / background status may have changed. Unfortunately, there isn't a great way in the iof framework to know if we are capturing a starter's stdin. Use the logic that if it's a source AND tagged as standard input, it's a starter's stdin. This seems to work for all the common usages. Both these need to go to the v1.0 branch. This commit was SVN r8894. --- opal/event/signal.c | 3 +- orte/mca/iof/base/iof_base_endpoint.c | 56 ++++++++++++++++++++++++--- orte/mca/iof/base/iof_base_endpoint.h | 1 + 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/opal/event/signal.c b/opal/event/signal.c index 475df73b69..d6796e57fe 100644 --- a/opal/event/signal.c +++ b/opal/event/signal.c @@ -127,8 +127,7 @@ opal_evsignal_add(sigset_t *evsigmask, struct opal_event *ev) gives a window where a signal handler *should* be installed but actually is not. */ if (opal_evsel->recalc && opal_evsel->recalc(opal_evbase, 0) == -1) { - opal_output(0, "opal_event_loop: opal_evsel->recalc() failed."); - opal_mutex_unlock(&opal_event_lock); + opal_output(0, "opal_evsignal_add: opal_evsel->recalc() failed."); return (-1); } diff --git a/orte/mca/iof/base/iof_base_endpoint.c b/orte/mca/iof/base/iof_base_endpoint.c index dc1d33530a..617187da23 100644 --- a/orte/mca/iof/base/iof_base_endpoint.c +++ b/orte/mca/iof/base/iof_base_endpoint.c @@ -223,6 +223,31 @@ static void orte_iof_base_endpoint_write_handler(int sd, short flags, void *user OPAL_THREAD_UNLOCK(&orte_iof_base.iof_lock); } + +/* return true if we should read stdin from fd, false otherwise */ +static bool orte_iof_base_endpoint_stdin_check(int fd) +{ + if (isatty(fd) && (getpgrp() != tcgetpgrp(fd))) { + return false; + } else { + return true; + } +} + + +static void orte_iof_base_endpoint_stdin_cb(int sd, short flags, void *user) +{ + orte_iof_base_endpoint_t* endpoint = (orte_iof_base_endpoint_t*)user; + bool should_process = orte_iof_base_endpoint_stdin_check(endpoint->ep_fd); + + if (should_process) { + opal_event_add(&endpoint->ep_event, 0); + } else { + opal_event_del(&endpoint->ep_event); + } +} + + /* * Lookup existing endpoint matching parameters * supplied to create. @@ -289,13 +314,32 @@ int orte_iof_base_endpoint_create( /* setup event handler */ switch(mode) { case ORTE_IOF_SOURCE: + if (tag == ORTE_IOF_STDIN && isatty(endpoint->ep_fd)) { + /* We should avoid trying to read from stdin if we + have a terminal, but are backgrounded. Catch the + signals that are commonly used when we switch + between being backgrounded and not. If the + filedescriptor is not a tty, don't worry about it + and always stay connected. */ + opal_signal_set(&(endpoint->ep_stdin_event), + SIGCONT, + orte_iof_base_endpoint_stdin_cb, + endpoint); + opal_signal_add(&(endpoint->ep_stdin_event), NULL); + } + + /* always setup the event, but only add it if we should be + reading from stdin right now (per rules above) */ opal_event_set( - &endpoint->ep_event, - endpoint->ep_fd, - OPAL_EV_READ|OPAL_EV_PERSIST, - orte_iof_base_endpoint_read_handler, - endpoint); - opal_event_add(&endpoint->ep_event, 0); + &endpoint->ep_event, + endpoint->ep_fd, + OPAL_EV_READ|OPAL_EV_PERSIST, + orte_iof_base_endpoint_read_handler, + endpoint); + if (tag != ORTE_IOF_STDIN || + orte_iof_base_endpoint_stdin_check(endpoint->ep_fd)) { + opal_event_add(&endpoint->ep_event, 0); + } break; case ORTE_IOF_SINK: opal_event_set( diff --git a/orte/mca/iof/base/iof_base_endpoint.h b/orte/mca/iof/base/iof_base_endpoint.h index 16dcffe8dd..8cfbfcdb9e 100644 --- a/orte/mca/iof/base/iof_base_endpoint.h +++ b/orte/mca/iof/base/iof_base_endpoint.h @@ -34,6 +34,7 @@ struct orte_iof_base_endpoint_t { uint32_t ep_seq; uint32_t ep_ack; opal_event_t ep_event; + opal_event_t ep_stdin_event; opal_list_t ep_frags; opal_list_t ep_callbacks; };