diff options
Diffstat (limited to 'src/sysdep.c')
| -rw-r--r-- | src/sysdep.c | 129 |
1 files changed, 84 insertions, 45 deletions
diff --git a/src/sysdep.c b/src/sysdep.c index e172dc0aed4..91b2a5cb943 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -382,19 +382,23 @@ get_child_status (pid_t child, int *status, int options, bool interruptible) | |||
| 382 | so that another thread running glib won't find them. */ | 382 | so that another thread running glib won't find them. */ |
| 383 | eassert (child > 0); | 383 | eassert (child > 0); |
| 384 | 384 | ||
| 385 | while ((pid = waitpid (child, status, options)) < 0) | 385 | while (true) |
| 386 | { | 386 | { |
| 387 | /* Note: the MS-Windows emulation of waitpid calls maybe_quit | ||
| 388 | internally. */ | ||
| 389 | if (interruptible) | ||
| 390 | maybe_quit (); | ||
| 391 | |||
| 392 | pid = waitpid (child, status, options); | ||
| 393 | if (0 <= pid) | ||
| 394 | break; | ||
| 395 | |||
| 387 | /* Check that CHILD is a child process that has not been reaped, | 396 | /* Check that CHILD is a child process that has not been reaped, |
| 388 | and that STATUS and OPTIONS are valid. Otherwise abort, | 397 | and that STATUS and OPTIONS are valid. Otherwise abort, |
| 389 | as continuing after this internal error could cause Emacs to | 398 | as continuing after this internal error could cause Emacs to |
| 390 | become confused and kill innocent-victim processes. */ | 399 | become confused and kill innocent-victim processes. */ |
| 391 | if (errno != EINTR) | 400 | if (errno != EINTR) |
| 392 | emacs_abort (); | 401 | emacs_abort (); |
| 393 | |||
| 394 | /* Note: the MS-Windows emulation of waitpid calls maybe_quit | ||
| 395 | internally. */ | ||
| 396 | if (interruptible) | ||
| 397 | maybe_quit (); | ||
| 398 | } | 402 | } |
| 399 | 403 | ||
| 400 | /* If successful and status is requested, tell wait_reading_process_output | 404 | /* If successful and status is requested, tell wait_reading_process_output |
| @@ -2503,78 +2507,113 @@ emacs_close (int fd) | |||
| 2503 | #define MAX_RW_COUNT (INT_MAX >> 18 << 18) | 2507 | #define MAX_RW_COUNT (INT_MAX >> 18 << 18) |
| 2504 | #endif | 2508 | #endif |
| 2505 | 2509 | ||
| 2506 | /* Read from FILEDESC to a buffer BUF with size NBYTE, retrying if interrupted. | 2510 | /* Read from FD to a buffer BUF with size NBYTE. |
| 2511 | If interrupted, process any quits and pending signals immediately | ||
| 2512 | if INTERRUPTIBLE, and then retry the read unless quitting. | ||
| 2507 | Return the number of bytes read, which might be less than NBYTE. | 2513 | Return the number of bytes read, which might be less than NBYTE. |
| 2508 | On error, set errno and return -1. */ | 2514 | On error, set errno to a value other than EINTR, and return -1. */ |
| 2509 | ptrdiff_t | 2515 | static ptrdiff_t |
| 2510 | emacs_read (int fildes, void *buf, ptrdiff_t nbyte) | 2516 | emacs_intr_read (int fd, void *buf, ptrdiff_t nbyte, bool interruptible) |
| 2511 | { | 2517 | { |
| 2512 | ssize_t rtnval; | 2518 | ssize_t result; |
| 2513 | 2519 | ||
| 2514 | /* There is no need to check against MAX_RW_COUNT, since no caller ever | 2520 | /* There is no need to check against MAX_RW_COUNT, since no caller ever |
| 2515 | passes a size that large to emacs_read. */ | 2521 | passes a size that large to emacs_read. */ |
| 2522 | do | ||
| 2523 | { | ||
| 2524 | if (interruptible) | ||
| 2525 | maybe_quit (); | ||
| 2526 | result = read (fd, buf, nbyte); | ||
| 2527 | } | ||
| 2528 | while (result < 0 && errno == EINTR); | ||
| 2516 | 2529 | ||
| 2517 | while ((rtnval = read (fildes, buf, nbyte)) == -1 | 2530 | return result; |
| 2518 | && (errno == EINTR)) | ||
| 2519 | maybe_quit (); | ||
| 2520 | return (rtnval); | ||
| 2521 | } | 2531 | } |
| 2522 | 2532 | ||
| 2523 | /* Write to FILEDES from a buffer BUF with size NBYTE, retrying if interrupted | 2533 | /* Read from FD to a buffer BUF with size NBYTE. |
| 2524 | or if a partial write occurs. If interrupted, process pending | 2534 | If interrupted, retry the read. Return the number of bytes read, |
| 2525 | signals if PROCESS SIGNALS. Return the number of bytes written, setting | 2535 | which might be less than NBYTE. On error, set errno to a value |
| 2526 | errno if this is less than NBYTE. */ | 2536 | other than EINTR, and return -1. */ |
| 2537 | ptrdiff_t | ||
| 2538 | emacs_read (int fd, void *buf, ptrdiff_t nbyte) | ||
| 2539 | { | ||
| 2540 | return emacs_intr_read (fd, buf, nbyte, false); | ||
| 2541 | } | ||
| 2542 | |||
| 2543 | /* Like emacs_read, but also process quits and pending signals. */ | ||
| 2544 | ptrdiff_t | ||
| 2545 | emacs_read_quit (int fd, void *buf, ptrdiff_t nbyte) | ||
| 2546 | { | ||
| 2547 | return emacs_intr_read (fd, buf, nbyte, true); | ||
| 2548 | } | ||
| 2549 | |||
| 2550 | /* Write to FILEDES from a buffer BUF with size NBYTE, retrying if | ||
| 2551 | interrupted or if a partial write occurs. Process any quits | ||
| 2552 | immediately if INTERRUPTIBLE is positive, and process any pending | ||
| 2553 | signals immediately if INTERRUPTIBLE is nonzero. Return the number | ||
| 2554 | of bytes written; if this is less than NBYTE, set errno to a value | ||
| 2555 | other than EINTR. */ | ||
| 2527 | static ptrdiff_t | 2556 | static ptrdiff_t |
| 2528 | emacs_full_write (int fildes, char const *buf, ptrdiff_t nbyte, | 2557 | emacs_full_write (int fd, char const *buf, ptrdiff_t nbyte, |
| 2529 | bool process_signals) | 2558 | int interruptible) |
| 2530 | { | 2559 | { |
| 2531 | ptrdiff_t bytes_written = 0; | 2560 | ptrdiff_t bytes_written = 0; |
| 2532 | 2561 | ||
| 2533 | while (nbyte > 0) | 2562 | while (nbyte > 0) |
| 2534 | { | 2563 | { |
| 2535 | ssize_t n = write (fildes, buf, min (nbyte, MAX_RW_COUNT)); | 2564 | ssize_t n = write (fd, buf, min (nbyte, MAX_RW_COUNT)); |
| 2536 | 2565 | ||
| 2537 | if (n < 0) | 2566 | if (n < 0) |
| 2538 | { | 2567 | { |
| 2539 | if (errno == EINTR) | 2568 | if (errno != EINTR) |
| 2569 | break; | ||
| 2570 | |||
| 2571 | if (interruptible) | ||
| 2540 | { | 2572 | { |
| 2541 | /* I originally used maybe_quit but that might cause files to | 2573 | if (0 < interruptible) |
| 2542 | be truncated if you hit C-g in the middle of it. --Stef */ | 2574 | maybe_quit (); |
| 2543 | if (process_signals && pending_signals) | 2575 | if (pending_signals) |
| 2544 | process_pending_signals (); | 2576 | process_pending_signals (); |
| 2545 | continue; | ||
| 2546 | } | 2577 | } |
| 2547 | else | ||
| 2548 | break; | ||
| 2549 | } | 2578 | } |
| 2550 | 2579 | else | |
| 2551 | buf += n; | 2580 | { |
| 2552 | nbyte -= n; | 2581 | buf += n; |
| 2553 | bytes_written += n; | 2582 | nbyte -= n; |
| 2583 | bytes_written += n; | ||
| 2584 | } | ||
| 2554 | } | 2585 | } |
| 2555 | 2586 | ||
| 2556 | return bytes_written; | 2587 | return bytes_written; |
| 2557 | } | 2588 | } |
| 2558 | 2589 | ||
| 2559 | /* Write to FILEDES from a buffer BUF with size NBYTE, retrying if | 2590 | /* Write to FD from a buffer BUF with size NBYTE, retrying if |
| 2560 | interrupted or if a partial write occurs. Return the number of | 2591 | interrupted or if a partial write occurs. Do not process quits or |
| 2561 | bytes written, setting errno if this is less than NBYTE. */ | 2592 | pending signals. Return the number of bytes written, setting errno |
| 2593 | if this is less than NBYTE. */ | ||
| 2594 | ptrdiff_t | ||
| 2595 | emacs_write (int fd, void const *buf, ptrdiff_t nbyte) | ||
| 2596 | { | ||
| 2597 | return emacs_full_write (fd, buf, nbyte, 0); | ||
| 2598 | } | ||
| 2599 | |||
| 2600 | /* Like emacs_write, but also process pending signals. */ | ||
| 2562 | ptrdiff_t | 2601 | ptrdiff_t |
| 2563 | emacs_write (int fildes, void const *buf, ptrdiff_t nbyte) | 2602 | emacs_write_sig (int fd, void const *buf, ptrdiff_t nbyte) |
| 2564 | { | 2603 | { |
| 2565 | return emacs_full_write (fildes, buf, nbyte, 0); | 2604 | return emacs_full_write (fd, buf, nbyte, -1); |
| 2566 | } | 2605 | } |
| 2567 | 2606 | ||
| 2568 | /* Like emacs_write, but also process pending signals if interrupted. */ | 2607 | /* Like emacs_write, but also process quits and pending signals. */ |
| 2569 | ptrdiff_t | 2608 | ptrdiff_t |
| 2570 | emacs_write_sig (int fildes, void const *buf, ptrdiff_t nbyte) | 2609 | emacs_write_quit (int fd, void const *buf, ptrdiff_t nbyte) |
| 2571 | { | 2610 | { |
| 2572 | return emacs_full_write (fildes, buf, nbyte, 1); | 2611 | return emacs_full_write (fd, buf, nbyte, 1); |
| 2573 | } | 2612 | } |
| 2574 | 2613 | ||
| 2575 | /* Write a diagnostic to standard error that contains MESSAGE and a | 2614 | /* Write a diagnostic to standard error that contains MESSAGE and a |
| 2576 | string derived from errno. Preserve errno. Do not buffer stderr. | 2615 | string derived from errno. Preserve errno. Do not buffer stderr. |
| 2577 | Do not process pending signals if interrupted. */ | 2616 | Do not process quits or pending signals if interrupted. */ |
| 2578 | void | 2617 | void |
| 2579 | emacs_perror (char const *message) | 2618 | emacs_perror (char const *message) |
| 2580 | { | 2619 | { |
| @@ -3168,7 +3207,7 @@ system_process_attributes (Lisp_Object pid) | |||
| 3168 | else | 3207 | else |
| 3169 | { | 3208 | { |
| 3170 | record_unwind_protect_int (close_file_unwind, fd); | 3209 | record_unwind_protect_int (close_file_unwind, fd); |
| 3171 | nread = emacs_read (fd, procbuf, sizeof procbuf - 1); | 3210 | nread = emacs_read_quit (fd, procbuf, sizeof procbuf - 1); |
| 3172 | } | 3211 | } |
| 3173 | if (0 < nread) | 3212 | if (0 < nread) |
| 3174 | { | 3213 | { |
| @@ -3289,7 +3328,7 @@ system_process_attributes (Lisp_Object pid) | |||
| 3289 | /* Leave room even if every byte needs escaping below. */ | 3328 | /* Leave room even if every byte needs escaping below. */ |
| 3290 | readsize = (cmdline_size >> 1) - nread; | 3329 | readsize = (cmdline_size >> 1) - nread; |
| 3291 | 3330 | ||
| 3292 | nread_incr = emacs_read (fd, cmdline + nread, readsize); | 3331 | nread_incr = emacs_read_quit (fd, cmdline + nread, readsize); |
| 3293 | nread += max (0, nread_incr); | 3332 | nread += max (0, nread_incr); |
| 3294 | } | 3333 | } |
| 3295 | while (nread_incr == readsize); | 3334 | while (nread_incr == readsize); |
| @@ -3402,7 +3441,7 @@ system_process_attributes (Lisp_Object pid) | |||
| 3402 | else | 3441 | else |
| 3403 | { | 3442 | { |
| 3404 | record_unwind_protect_int (close_file_unwind, fd); | 3443 | record_unwind_protect_int (close_file_unwind, fd); |
| 3405 | nread = emacs_read (fd, &pinfo, sizeof pinfo); | 3444 | nread = emacs_read_quit (fd, &pinfo, sizeof pinfo); |
| 3406 | } | 3445 | } |
| 3407 | 3446 | ||
| 3408 | if (nread == sizeof pinfo) | 3447 | if (nread == sizeof pinfo) |