|
46 | 46 | #include "src/common/libutil/read_all.h" |
47 | 47 | #include "src/common/libutil/monotime.h" |
48 | 48 | #include "src/common/libutil/fsd.h" |
| 49 | +#include "src/common/libutil/fdutils.h" |
49 | 50 | #include "src/common/libidset/idset.h" |
50 | 51 | #include "src/common/libeventlog/eventlog.h" |
51 | 52 | #include "src/common/libioencode/ioencode.h" |
@@ -1887,7 +1888,7 @@ void attach_signal_cb (flux_reactor_t *r, flux_watcher_t *w, |
1887 | 1888 | */ |
1888 | 1889 | void restore_stdin_flags (void) |
1889 | 1890 | { |
1890 | | - (void)fcntl (STDIN_FILENO, F_SETFL, stdin_flags); |
| 1891 | + (void)fd_set_flags (STDIN_FILENO, stdin_flags); |
1891 | 1892 | } |
1892 | 1893 |
|
1893 | 1894 | static void attach_send_shell_completion (flux_future_t *f, void *arg) |
@@ -2093,21 +2094,31 @@ static void attach_setup_stdin (struct attach_ctx *ctx) |
2093 | 2094 | /* flux_buffer_read_watcher_create() requires O_NONBLOCK on |
2094 | 2095 | * stdin */ |
2095 | 2096 |
|
2096 | | - if ((stdin_flags = fcntl (STDIN_FILENO, F_GETFL)) < 0) |
2097 | | - log_err_exit ("fcntl F_GETFL stdin"); |
| 2097 | + if ((stdin_flags = fd_set_nonblocking (STDIN_FILENO)) < 0) |
| 2098 | + log_err_exit ("unable to set stdin nonblocking"); |
2098 | 2099 | if (atexit (restore_stdin_flags) != 0) |
2099 | 2100 | log_err_exit ("atexit"); |
2100 | | - if (fcntl (STDIN_FILENO, F_SETFL, stdin_flags | O_NONBLOCK) < 0) |
2101 | | - log_err_exit ("fcntl F_SETFL stdin"); |
2102 | 2101 |
|
2103 | 2102 | w = flux_buffer_read_watcher_create (flux_get_reactor (ctx->h), |
2104 | 2103 | STDIN_FILENO, |
2105 | 2104 | 1 << 20, |
2106 | 2105 | attach_stdin_cb, |
2107 | 2106 | flags, |
2108 | 2107 | ctx); |
2109 | | - if (!w) |
| 2108 | + if (!w) { |
| 2109 | + /* Users have reported rare occurrences of an EINVAL error |
| 2110 | + * from flux_buffer_read_watcher_create(), the cause of which |
| 2111 | + * is not understood (See issue #5175). In many cases, perhaps all, |
| 2112 | + * stdin is not used by the job, so aborting `flux job attach` |
| 2113 | + * is an unnecessary failure. Therefore, just ignore stdin when |
| 2114 | + * errno is EINVAL here: |
| 2115 | + */ |
| 2116 | + if (errno == EINVAL) { |
| 2117 | + log_msg ("Warning: ignoring stdin: failed to create watcher"); |
| 2118 | + return; |
| 2119 | + } |
2110 | 2120 | log_err_exit ("flux_buffer_read_watcher_create"); |
| 2121 | + } |
2111 | 2122 |
|
2112 | 2123 | if (!(ctx->stdin_rpcs = zlist_new ())) |
2113 | 2124 | log_err_exit ("zlist_new"); |
|
0 commit comments