comparison src/channel.c @ 8761:f8707ec9efe4 v7.4.1669

commit https://github.com/vim/vim/commit/8b877ac38e96424a08a8b8eb713ef4b3cf0064be Author: Bram Moolenaar <Bram@vim.org> Date: Mon Mar 28 19:16:20 2016 +0200 patch 7.4.1669 Problem: When writing buffer lines to a pipe Vim may block. Solution: Avoid blocking, write more lines later.
author Christian Brabandt <cb@256bit.org>
date Mon, 28 Mar 2016 19:30:05 +0200
parents cc2ef7367643
children 23b7f05a7f48
comparison
equal deleted inserted replaced
8760:e43830c12eb2 8761:f8707ec9efe4
971 if (options->jo_in_top == 0 && !(options->jo_set & JO_IN_BOT)) 971 if (options->jo_in_top == 0 && !(options->jo_set & JO_IN_BOT))
972 { 972 {
973 /* Special mode: send last-but-one line when appending a line 973 /* Special mode: send last-but-one line when appending a line
974 * to the buffer. */ 974 * to the buffer. */
975 in_part->ch_buffer->b_write_to_channel = TRUE; 975 in_part->ch_buffer->b_write_to_channel = TRUE;
976 in_part->ch_buf_append = TRUE;
976 in_part->ch_buf_top = 977 in_part->ch_buf_top =
977 in_part->ch_buffer->b_ml.ml_line_count + 1; 978 in_part->ch_buffer->b_ml.ml_line_count + 1;
978 } 979 }
979 else 980 else
980 in_part->ch_buf_top = options->jo_in_top; 981 in_part->ch_buf_top = options->jo_in_top;
1045 channel->ch_part[part].ch_timeout = opt->jo_timeout; 1046 channel->ch_part[part].ch_timeout = opt->jo_timeout;
1046 if (opt->jo_set & JO_OUT_TIMEOUT) 1047 if (opt->jo_set & JO_OUT_TIMEOUT)
1047 channel->ch_part[PART_OUT].ch_timeout = opt->jo_out_timeout; 1048 channel->ch_part[PART_OUT].ch_timeout = opt->jo_out_timeout;
1048 if (opt->jo_set & JO_ERR_TIMEOUT) 1049 if (opt->jo_set & JO_ERR_TIMEOUT)
1049 channel->ch_part[PART_ERR].ch_timeout = opt->jo_err_timeout; 1050 channel->ch_part[PART_ERR].ch_timeout = opt->jo_err_timeout;
1051 if (opt->jo_set & JO_BLOCK_WRITE)
1052 channel->ch_part[PART_IN].ch_block_write = 1;
1050 1053
1051 if (opt->jo_set & JO_CALLBACK) 1054 if (opt->jo_set & JO_CALLBACK)
1052 { 1055 {
1053 cbp = &channel->ch_callback; 1056 cbp = &channel->ch_callback;
1054 pp = &channel->ch_partial; 1057 pp = &channel->ch_partial;
1191 channel_send(channel, PART_IN, p, "write_buf_line()"); 1194 channel_send(channel, PART_IN, p, "write_buf_line()");
1192 vim_free(p); 1195 vim_free(p);
1193 } 1196 }
1194 1197
1195 /* 1198 /*
1199 * Return TRUE if "channel" can be written to.
1200 * Returns FALSE if the input is closed or the write would block.
1201 */
1202 static int
1203 can_write_buf_line(channel_T *channel)
1204 {
1205 chanpart_T *in_part = &channel->ch_part[PART_IN];
1206
1207 if (in_part->ch_fd == INVALID_FD)
1208 return FALSE; /* pipe was closed */
1209
1210 /* for testing: block every other attempt to write */
1211 if (in_part->ch_block_write == 1)
1212 in_part->ch_block_write = -1;
1213 else if (in_part->ch_block_write == -1)
1214 in_part->ch_block_write = 1;
1215
1216 /* TODO: Win32 implementation, probably using WaitForMultipleObjects() */
1217 #ifndef WIN32
1218 {
1219 # if defined(HAVE_SELECT)
1220 struct timeval tval;
1221 fd_set wfds;
1222 int ret;
1223
1224 FD_ZERO(&wfds);
1225 FD_SET((int)in_part->ch_fd, &wfds);
1226 tval.tv_sec = 0;
1227 tval.tv_usec = 0;
1228 for (;;)
1229 {
1230 ret = select((int)in_part->ch_fd + 1, NULL, &wfds, NULL, &tval);
1231 # ifdef EINTR
1232 SOCK_ERRNO;
1233 if (ret == -1 && errno == EINTR)
1234 continue;
1235 # endif
1236 if (ret <= 0 || in_part->ch_block_write == 1)
1237 {
1238 if (ret > 0)
1239 ch_log(channel, "FAKED Input not ready for writing");
1240 else
1241 ch_log(channel, "Input not ready for writing");
1242 return FALSE;
1243 }
1244 break;
1245 }
1246 # else
1247 struct pollfd fds;
1248
1249 fds.fd = in_part->ch_fd;
1250 fds.events = POLLOUT;
1251 if (poll(&fds, 1, 0) <= 0)
1252 {
1253 ch_log(channel, "Input not ready for writing");
1254 return FALSE;
1255 }
1256 if (in_part->ch_block_write == 1)
1257 {
1258 ch_log(channel, "FAKED Input not ready for writing");
1259 return FALSE;
1260 }
1261 # endif
1262 }
1263 #endif
1264 return TRUE;
1265 }
1266
1267 /*
1196 * Write any lines to the input channel. 1268 * Write any lines to the input channel.
1197 */ 1269 */
1198 void 1270 static void
1199 channel_write_in(channel_T *channel) 1271 channel_write_in(channel_T *channel)
1200 { 1272 {
1201 chanpart_T *in_part = &channel->ch_part[PART_IN]; 1273 chanpart_T *in_part = &channel->ch_part[PART_IN];
1202 linenr_T lnum; 1274 linenr_T lnum;
1203 buf_T *buf = in_part->ch_buffer; 1275 buf_T *buf = in_part->ch_buffer;
1204 int written = 0; 1276 int written = 0;
1205 1277
1206 if (buf == NULL) 1278 if (buf == NULL || in_part->ch_buf_append)
1207 return; 1279 return; /* no buffer or using appending */
1208 if (!buf_valid(buf) || buf->b_ml.ml_mfp == NULL) 1280 if (!buf_valid(buf) || buf->b_ml.ml_mfp == NULL)
1209 { 1281 {
1210 /* buffer was wiped out or unloaded */ 1282 /* buffer was wiped out or unloaded */
1211 in_part->ch_buffer = NULL; 1283 in_part->ch_buffer = NULL;
1212 return; 1284 return;
1213 } 1285 }
1214 1286
1215 for (lnum = in_part->ch_buf_top; lnum <= in_part->ch_buf_bot 1287 for (lnum = in_part->ch_buf_top; lnum <= in_part->ch_buf_bot
1216 && lnum <= buf->b_ml.ml_line_count; ++lnum) 1288 && lnum <= buf->b_ml.ml_line_count; ++lnum)
1217 { 1289 {
1218 if (in_part->ch_fd == INVALID_FD) 1290 if (!can_write_buf_line(channel))
1219 /* pipe was closed */ 1291 break;
1220 return;
1221 /* TODO: check if channel can be written to, do not block on write */
1222 write_buf_line(buf, lnum, channel); 1292 write_buf_line(buf, lnum, channel);
1223 ++written; 1293 ++written;
1224 } 1294 }
1225 1295
1226 if (written == 1) 1296 if (written == 1)
1227 ch_logn(channel, "written line %d to channel", (int)lnum - 1); 1297 ch_logn(channel, "written line %d to channel", (int)lnum - 1);
1228 else if (written > 1) 1298 else if (written > 1)
1229 ch_logn(channel, "written %d lines to channel", written); 1299 ch_logn(channel, "written %d lines to channel", written);
1230 1300
1231 in_part->ch_buf_top = lnum; 1301 in_part->ch_buf_top = lnum;
1302 if (lnum > buf->b_ml.ml_line_count)
1303 {
1304 /* Writing is done, no longer need the buffer. */
1305 in_part->ch_buffer = NULL;
1306 ch_log(channel, "Finished writing all lines to channel");
1307 }
1308 else
1309 ch_logn(channel, "Still %d more lines to write",
1310 buf->b_ml.ml_line_count - lnum + 1);
1311 }
1312
1313 /*
1314 * Write any lines waiting to be written to a channel.
1315 */
1316 void
1317 channel_write_any_lines()
1318 {
1319 channel_T *channel;
1320
1321 for (channel = first_channel; channel != NULL; channel = channel->ch_next)
1322 {
1323 chanpart_T *in_part = &channel->ch_part[PART_IN];
1324
1325 if (in_part->ch_buffer != NULL)
1326 {
1327 if (in_part->ch_buf_append)
1328 channel_write_new_lines(in_part->ch_buffer);
1329 else
1330 channel_write_in(channel);
1331 }
1332 }
1232 } 1333 }
1233 1334
1234 /* 1335 /*
1235 * Write appended lines above the last one in "buf" to the channel. 1336 * Write appended lines above the last one in "buf" to the channel.
1236 */ 1337 */
1246 { 1347 {
1247 chanpart_T *in_part = &channel->ch_part[PART_IN]; 1348 chanpart_T *in_part = &channel->ch_part[PART_IN];
1248 linenr_T lnum; 1349 linenr_T lnum;
1249 int written = 0; 1350 int written = 0;
1250 1351
1251 if (in_part->ch_buffer == buf) 1352 if (in_part->ch_buffer == buf && in_part->ch_buf_append)
1252 { 1353 {
1253 if (in_part->ch_fd == INVALID_FD) 1354 if (in_part->ch_fd == INVALID_FD)
1254 /* pipe was closed */ 1355 continue; /* pipe was closed */
1255 continue;
1256 found_one = TRUE; 1356 found_one = TRUE;
1257 for (lnum = in_part->ch_buf_bot; lnum < buf->b_ml.ml_line_count; 1357 for (lnum = in_part->ch_buf_bot; lnum < buf->b_ml.ml_line_count;
1258 ++lnum) 1358 ++lnum)
1259 { 1359 {
1360 if (!can_write_buf_line(channel))
1361 break;
1260 write_buf_line(buf, lnum, channel); 1362 write_buf_line(buf, lnum, channel);
1261 ++written; 1363 ++written;
1262 } 1364 }
1263 1365
1264 if (written == 1) 1366 if (written == 1)
1265 ch_logn(channel, "written line %d to channel", (int)lnum - 1); 1367 ch_logn(channel, "written line %d to channel", (int)lnum - 1);
1266 else if (written > 1) 1368 else if (written > 1)
1267 ch_logn(channel, "written %d lines to channel", written); 1369 ch_logn(channel, "written %d lines to channel", written);
1370 if (lnum < buf->b_ml.ml_line_count)
1371 ch_logn(channel, "Still %d more lines to write",
1372 buf->b_ml.ml_line_count - lnum);
1268 1373
1269 in_part->ch_buf_bot = lnum; 1374 in_part->ch_buf_bot = lnum;
1270 } 1375 }
1271 } 1376 }
1272 if (!found_one) 1377 if (!found_one)
2377 #define DETACH_MSG_RAW "DETACH\n" 2482 #define DETACH_MSG_RAW "DETACH\n"
2378 2483
2379 /* Buffer size for reading incoming messages. */ 2484 /* Buffer size for reading incoming messages. */
2380 #define MAXMSGSIZE 4096 2485 #define MAXMSGSIZE 4096
2381 2486
2487 #if defined(HAVE_SELECT)
2488 /*
2489 * Add write fds where we are waiting for writing to be possible.
2490 */
2491 static int
2492 channel_fill_wfds(int maxfd_arg, fd_set *wfds)
2493 {
2494 int maxfd = maxfd_arg;
2495 channel_T *ch;
2496
2497 for (ch = first_channel; ch != NULL; ch = ch->ch_next)
2498 {
2499 chanpart_T *in_part = &ch->ch_part[PART_IN];
2500
2501 if (in_part->ch_fd != INVALID_FD && in_part->ch_buffer != NULL)
2502 {
2503 FD_SET((int)in_part->ch_fd, wfds);
2504 if ((int)in_part->ch_fd >= maxfd)
2505 maxfd = (int)in_part->ch_fd + 1;
2506 }
2507 }
2508 return maxfd;
2509 }
2510 #else
2511 /*
2512 * Add write fds where we are waiting for writing to be possible.
2513 */
2514 static int
2515 channel_fill_poll_write(int nfd_in, struct pollfd *fds)
2516 {
2517 int nfd = nfd_in;
2518 channel_T *ch;
2519
2520 for (ch = first_channel; ch != NULL; ch = ch->ch_next)
2521 {
2522 chanpart_T *in_part = &ch->ch_part[PART_IN];
2523
2524 if (in_part->ch_fd != INVALID_FD && in_part->ch_buffer != NULL)
2525 {
2526 in_part->ch_poll_idx = nfd;
2527 fds[nfd].fd = in_part->ch_fd;
2528 fds[nfd].events = POLLOUT;
2529 ++nfd;
2530 }
2531 else
2532 in_part->ch_poll_idx = -1;
2533 }
2534 return nfd;
2535 }
2536 #endif
2537
2382 /* 2538 /*
2383 * Check for reading from "fd" with "timeout" msec. 2539 * Check for reading from "fd" with "timeout" msec.
2384 * Return FAIL when there is nothing to read. 2540 * Return FAIL when there is nothing to read.
2385 */ 2541 */
2386 static int 2542 static int
2401 while (TRUE) 2557 while (TRUE)
2402 { 2558 {
2403 if (PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &nread, NULL) 2559 if (PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &nread, NULL)
2404 && nread > 0) 2560 && nread > 0)
2405 return OK; 2561 return OK;
2562
2563 /* perhaps write some buffer lines */
2564 channel_write_any_lines();
2565
2406 sleep_time = deadline - GetTickCount(); 2566 sleep_time = deadline - GetTickCount();
2407 if (sleep_time <= 0) 2567 if (sleep_time <= 0)
2408 break; 2568 break;
2409 /* Wait for a little while. Very short at first, up to 10 msec 2569 /* Wait for a little while. Very short at first, up to 10 msec
2410 * after looping a few times. */ 2570 * after looping a few times. */
2420 #endif 2580 #endif
2421 { 2581 {
2422 #if defined(HAVE_SELECT) 2582 #if defined(HAVE_SELECT)
2423 struct timeval tval; 2583 struct timeval tval;
2424 fd_set rfds; 2584 fd_set rfds;
2425 int ret; 2585 fd_set wfds;
2426 2586 int ret;
2427 FD_ZERO(&rfds); 2587 int maxfd;
2428 FD_SET((int)fd, &rfds); 2588
2429 tval.tv_sec = timeout / 1000; 2589 tval.tv_sec = timeout / 1000;
2430 tval.tv_usec = (timeout % 1000) * 1000; 2590 tval.tv_usec = (timeout % 1000) * 1000;
2431 for (;;) 2591 for (;;)
2432 { 2592 {
2433 ret = select((int)fd + 1, &rfds, NULL, NULL, &tval); 2593 FD_ZERO(&rfds);
2594 FD_SET((int)fd, &rfds);
2595
2596 /* Write lines to a pipe when a pipe can be written to. Need to
2597 * set this every time, some buffers may be done. */
2598 maxfd = (int)fd + 1;
2599 FD_ZERO(&wfds);
2600 maxfd = channel_fill_wfds(maxfd, &wfds);
2601
2602 ret = select(maxfd, &rfds, &wfds, NULL, &tval);
2434 # ifdef EINTR 2603 # ifdef EINTR
2435 SOCK_ERRNO; 2604 SOCK_ERRNO;
2436 if (ret == -1 && errno == EINTR) 2605 if (ret == -1 && errno == EINTR)
2437 continue; 2606 continue;
2438 # endif 2607 # endif
2439 if (ret > 0) 2608 if (ret > 0)
2440 return OK; 2609 {
2610 if (FD_ISSET(fd, &rfds))
2611 return OK;
2612 channel_write_any_lines();
2613 continue;
2614 }
2441 break; 2615 break;
2442 } 2616 }
2443 #else 2617 #else
2444 struct pollfd fds; 2618 for (;;)
2445 2619 {
2446 fds.fd = fd; 2620 struct pollfd fds[MAX_OPEN_CHANNELS + 1];
2447 fds.events = POLLIN; 2621 int nfd = 1;
2448 if (poll(&fds, 1, timeout) > 0) 2622
2449 return OK; 2623 fds[0].fd = fd;
2624 fds[0].events = POLLIN;
2625 nfd = channel_fill_poll_write(nfd, fds);
2626 if (poll(fds, nfd, timeout) > 0)
2627 {
2628 if (fds[0].revents & POLLIN)
2629 return OK;
2630 channel_write_any_lines();
2631 continue;
2632 }
2633 break;
2634 }
2450 #endif 2635 #endif
2451 } 2636 }
2452 return FAIL; 2637 return FAIL;
2453 } 2638 }
2454 2639
3008 3193
3009 for (channel = first_channel; channel != NULL; channel = channel->ch_next) 3194 for (channel = first_channel; channel != NULL; channel = channel->ch_next)
3010 { 3195 {
3011 for (part = PART_SOCK; part < PART_IN; ++part) 3196 for (part = PART_SOCK; part < PART_IN; ++part)
3012 { 3197 {
3013 if (channel->ch_part[part].ch_fd != INVALID_FD) 3198 chanpart_T *ch_part = &channel->ch_part[part];
3014 { 3199
3015 channel->ch_part[part].ch_poll_idx = nfd; 3200 if (ch_part->ch_fd != INVALID_FD)
3016 fds[nfd].fd = channel->ch_part[part].ch_fd; 3201 {
3202 ch_part->ch_poll_idx = nfd;
3203 fds[nfd].fd = ch_part->ch_fd;
3017 fds[nfd].events = POLLIN; 3204 fds[nfd].events = POLLIN;
3018 nfd++; 3205 nfd++;
3019 } 3206 }
3020 else 3207 else
3021 channel->ch_part[part].ch_poll_idx = -1; 3208 channel->ch_part[part].ch_poll_idx = -1;
3022 } 3209 }
3023 } 3210 }
3211
3212 nfd = channel_fill_poll_write(nfd, fds);
3024 3213
3025 return nfd; 3214 return nfd;
3026 } 3215 }
3027 3216
3028 /* 3217 /*
3033 { 3222 {
3034 int ret = ret_in; 3223 int ret = ret_in;
3035 channel_T *channel; 3224 channel_T *channel;
3036 struct pollfd *fds = fds_in; 3225 struct pollfd *fds = fds_in;
3037 int part; 3226 int part;
3227 int idx;
3228 chanpart_T *in_part;
3038 3229
3039 for (channel = first_channel; channel != NULL; channel = channel->ch_next) 3230 for (channel = first_channel; channel != NULL; channel = channel->ch_next)
3040 { 3231 {
3041 for (part = PART_SOCK; part < PART_IN; ++part) 3232 for (part = PART_SOCK; part < PART_IN; ++part)
3042 { 3233 {
3043 int idx = channel->ch_part[part].ch_poll_idx; 3234 idx = channel->ch_part[part].ch_poll_idx;
3044 3235
3045 if (ret > 0 && idx != -1 && fds[idx].revents & POLLIN) 3236 if (ret > 0 && idx != -1 && (fds[idx].revents & POLLIN))
3046 { 3237 {
3047 channel_read(channel, part, "channel_poll_check"); 3238 channel_read(channel, part, "channel_poll_check");
3048 --ret; 3239 --ret;
3049 } 3240 }
3050 } 3241 }
3242
3243 in_part = &channel->ch_part[PART_IN];
3244 idx = in_part->ch_poll_idx;
3245 if (ret > 0 && idx != -1 && (fds[idx].revents & POLLOUT))
3246 {
3247 if (in_part->ch_buf_append)
3248 {
3249 if (in_part->ch_buffer != NULL)
3250 channel_write_new_lines(in_part->ch_buffer);
3251 }
3252 else
3253 channel_write_in(channel);
3254 --ret;
3255 }
3051 } 3256 }
3052 3257
3053 return ret; 3258 return ret;
3054 } 3259 }
3055 # endif /* UNIX && !HAVE_SELECT */ 3260 # endif /* UNIX && !HAVE_SELECT */
3056 3261
3057 # if (!defined(WIN32) && defined(HAVE_SELECT)) || defined(PROTO) 3262 # if (!defined(WIN32) && defined(HAVE_SELECT)) || defined(PROTO)
3058 /* 3263 /*
3059 * The type of "rfds" is hidden to avoid problems with the function proto. 3264 * The "fd_set" type is hidden to avoid problems with the function proto.
3060 */ 3265 */
3061 int 3266 int
3062 channel_select_setup(int maxfd_in, void *rfds_in) 3267 channel_select_setup(int maxfd_in, void *rfds_in, void *wfds_in)
3063 { 3268 {
3064 int maxfd = maxfd_in; 3269 int maxfd = maxfd_in;
3065 channel_T *channel; 3270 channel_T *channel;
3066 fd_set *rfds = rfds_in; 3271 fd_set *rfds = rfds_in;
3272 fd_set *wfds = wfds_in;
3067 int part; 3273 int part;
3068 3274
3069 for (channel = first_channel; channel != NULL; channel = channel->ch_next) 3275 for (channel = first_channel; channel != NULL; channel = channel->ch_next)
3070 { 3276 {
3071 for (part = PART_SOCK; part < PART_IN; ++part) 3277 for (part = PART_SOCK; part < PART_IN; ++part)
3079 maxfd = (int)fd; 3285 maxfd = (int)fd;
3080 } 3286 }
3081 } 3287 }
3082 } 3288 }
3083 3289
3290 maxfd = channel_fill_wfds(maxfd, wfds);
3291
3084 return maxfd; 3292 return maxfd;
3085 } 3293 }
3086 3294
3087 /* 3295 /*
3088 * The type of "rfds" is hidden to avoid problems with the function proto. 3296 * The "fd_set" type is hidden to avoid problems with the function proto.
3089 */ 3297 */
3090 int 3298 int
3091 channel_select_check(int ret_in, void *rfds_in) 3299 channel_select_check(int ret_in, void *rfds_in, void *wfds_in)
3092 { 3300 {
3093 int ret = ret_in; 3301 int ret = ret_in;
3094 channel_T *channel; 3302 channel_T *channel;
3095 fd_set *rfds = rfds_in; 3303 fd_set *rfds = rfds_in;
3304 fd_set *wfds = wfds_in;
3096 int part; 3305 int part;
3306 chanpart_T *in_part;
3097 3307
3098 for (channel = first_channel; channel != NULL; channel = channel->ch_next) 3308 for (channel = first_channel; channel != NULL; channel = channel->ch_next)
3099 { 3309 {
3100 for (part = PART_SOCK; part < PART_IN; ++part) 3310 for (part = PART_SOCK; part < PART_IN; ++part)
3101 { 3311 {
3104 if (ret > 0 && fd != INVALID_FD && FD_ISSET(fd, rfds)) 3314 if (ret > 0 && fd != INVALID_FD && FD_ISSET(fd, rfds))
3105 { 3315 {
3106 channel_read(channel, part, "channel_select_check"); 3316 channel_read(channel, part, "channel_select_check");
3107 --ret; 3317 --ret;
3108 } 3318 }
3319 }
3320
3321 in_part = &channel->ch_part[PART_IN];
3322 if (ret > 0 && in_part->ch_fd != INVALID_FD
3323 && FD_ISSET(in_part->ch_fd, wfds))
3324 {
3325 if (in_part->ch_buf_append)
3326 {
3327 if (in_part->ch_buffer != NULL)
3328 channel_write_new_lines(in_part->ch_buffer);
3329 }
3330 else
3331 channel_write_in(channel);
3332 --ret;
3109 } 3333 }
3110 } 3334 }
3111 3335
3112 return ret; 3336 return ret;
3113 } 3337 }
3606 { 3830 {
3607 EMSG2(_(e_invarg2), "exit_cb"); 3831 EMSG2(_(e_invarg2), "exit_cb");
3608 return FAIL; 3832 return FAIL;
3609 } 3833 }
3610 } 3834 }
3835 else if (STRCMP(hi->hi_key, "block_write") == 0)
3836 {
3837 if (!(supported & JO_BLOCK_WRITE))
3838 break;
3839 opt->jo_set |= JO_BLOCK_WRITE;
3840 opt->jo_block_write = get_tv_number(item);
3841 }
3611 else 3842 else
3612 break; 3843 break;
3613 --todo; 3844 --todo;
3614 } 3845 }
3615 if (todo > 0) 3846 if (todo > 0)
3825 4056
3826 /* Default mode is NL. */ 4057 /* Default mode is NL. */
3827 clear_job_options(&opt); 4058 clear_job_options(&opt);
3828 opt.jo_mode = MODE_NL; 4059 opt.jo_mode = MODE_NL;
3829 if (get_job_options(&argvars[1], &opt, 4060 if (get_job_options(&argvars[1], &opt,
3830 JO_MODE_ALL + JO_CB_ALL + JO_TIMEOUT_ALL 4061 JO_MODE_ALL + JO_CB_ALL + JO_TIMEOUT_ALL + JO_STOPONEXIT
3831 + JO_STOPONEXIT + JO_EXIT_CB + JO_OUT_IO) == FAIL) 4062 + JO_EXIT_CB + JO_OUT_IO + JO_BLOCK_WRITE) == FAIL)
3832 return job; 4063 return job;
3833 4064
3834 /* Check that when io is "file" that there is a file name. */ 4065 /* Check that when io is "file" that there is a file name. */
3835 for (part = PART_OUT; part <= PART_IN; ++part) 4066 for (part = PART_OUT; part <= PART_IN; ++part)
3836 if ((opt.jo_set & (JO_OUT_IO << (part - PART_OUT))) 4067 if ((opt.jo_set & (JO_OUT_IO << (part - PART_OUT)))