diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-03 00:52:17 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-03 00:52:17 +0000 |
| commit | 4f8d27f29a29db6afd0fbb941c00d4eaee860e90 (patch) | |
| tree | 96f7a1582856b9166d1bdb5f7c2a66c5aa13149e | |
| parent | 493691a4f5023097b909aa8a443bb45dd9d9a68c (diff) | |
| download | busybox-w32-4f8d27f29a29db6afd0fbb941c00d4eaee860e90.tar.gz busybox-w32-4f8d27f29a29db6afd0fbb941c00d4eaee860e90.tar.bz2 busybox-w32-4f8d27f29a29db6afd0fbb941c00d4eaee860e90.zip | |
svlogd: do not set O_NONBLOCK on stdin permanently - that can
affect other processes!
| -rw-r--r-- | runit/svlogd.c | 72 |
1 files changed, 44 insertions, 28 deletions
diff --git a/runit/svlogd.c b/runit/svlogd.c index 59b1e5721..a0e562b21 100644 --- a/runit/svlogd.c +++ b/runit/svlogd.c | |||
| @@ -44,15 +44,19 @@ static int wstat; | |||
| 44 | static struct taia trotate; | 44 | static struct taia trotate; |
| 45 | 45 | ||
| 46 | static char *line; | 46 | static char *line; |
| 47 | static unsigned exitasap; | 47 | static smallint exitasap; |
| 48 | static unsigned rotateasap; | 48 | static smallint rotateasap; |
| 49 | static unsigned reopenasap; | 49 | static smallint reopenasap; |
| 50 | static unsigned linecomplete = 1; | 50 | static smallint linecomplete = 1; |
| 51 | static unsigned tmaxflag; | 51 | |
| 52 | static iopause_fd input; | 52 | static smallint tmaxflag; |
| 53 | 53 | ||
| 54 | static const char *replace = ""; | ||
| 55 | static char repl; | 54 | static char repl; |
| 55 | static const char *replace = ""; | ||
| 56 | |||
| 57 | sigset_t blocked_sigset; | ||
| 58 | static iopause_fd input; | ||
| 59 | static int fl_flag_0; | ||
| 56 | 60 | ||
| 57 | static struct logdir { | 61 | static struct logdir { |
| 58 | //// char *btmp; | 62 | //// char *btmp; |
| @@ -333,7 +337,7 @@ static int buffer_pwrite(int n, char *s, unsigned len) | |||
| 333 | if (len > (ld->sizemax - ld->size)) | 337 | if (len > (ld->sizemax - ld->size)) |
| 334 | len = ld->sizemax - ld->size; | 338 | len = ld->sizemax - ld->size; |
| 335 | } | 339 | } |
| 336 | while ((i = write(ld->fdcur, s, len)) == -1) { | 340 | while ((i = full_write(ld->fdcur, s, len)) == -1) { |
| 337 | if ((errno == ENOSPC) && (ld->nmin < ld->nmax)) { | 341 | if ((errno == ENOSPC) && (ld->nmin < ld->nmax)) { |
| 338 | DIR *d; | 342 | DIR *d; |
| 339 | struct dirent *f; | 343 | struct dirent *f; |
| @@ -585,6 +589,17 @@ static void logdirs_reopen(void) | |||
| 585 | if (!ok) fatalx("no functional log directories"); | 589 | if (!ok) fatalx("no functional log directories"); |
| 586 | } | 590 | } |
| 587 | 591 | ||
| 592 | /* Will look good in libbb one day */ | ||
| 593 | static ssize_t ndelay_read(int fd, void *buf, size_t count) | ||
| 594 | { | ||
| 595 | if (!(fl_flag_0 & O_NONBLOCK)) | ||
| 596 | fcntl(fd, F_SETFL, fl_flag_0 | O_NONBLOCK); | ||
| 597 | count = safe_read(fd, buf, count); | ||
| 598 | if (!(fl_flag_0 & O_NONBLOCK)) | ||
| 599 | fcntl(fd, F_SETFL, fl_flag_0); | ||
| 600 | return count; | ||
| 601 | } | ||
| 602 | |||
| 588 | /* Used for reading stdin */ | 603 | /* Used for reading stdin */ |
| 589 | static int buffer_pread(int fd, char *s, unsigned len) | 604 | static int buffer_pread(int fd, char *s, unsigned len) |
| 590 | { | 605 | { |
| @@ -617,17 +632,10 @@ static int buffer_pread(int fd, char *s, unsigned len) | |||
| 617 | } | 632 | } |
| 618 | 633 | ||
| 619 | while (1) { | 634 | while (1) { |
| 620 | /* Comment? */ | 635 | sigprocmask(SIG_UNBLOCK, &blocked_sigset, NULL); |
| 621 | sig_unblock(SIGTERM); | ||
| 622 | sig_unblock(SIGCHLD); | ||
| 623 | sig_unblock(SIGALRM); | ||
| 624 | sig_unblock(SIGHUP); | ||
| 625 | iopause(&input, 1, &trotate, &now); | 636 | iopause(&input, 1, &trotate, &now); |
| 626 | sig_block(SIGTERM); | 637 | sigprocmask(SIG_BLOCK, &blocked_sigset, NULL); |
| 627 | sig_block(SIGCHLD); | 638 | i = ndelay_read(fd, s, len); |
| 628 | sig_block(SIGALRM); | ||
| 629 | sig_block(SIGHUP); | ||
| 630 | i = safe_read(fd, s, len); | ||
| 631 | if (i >= 0) break; | 639 | if (i >= 0) break; |
| 632 | if (errno != EAGAIN) { | 640 | if (errno != EAGAIN) { |
| 633 | warn("cannot read standard input"); | 641 | warn("cannot read standard input"); |
| @@ -775,14 +783,17 @@ int svlogd_main(int argc, char **argv) | |||
| 775 | fndir = argv; | 783 | fndir = argv; |
| 776 | input.fd = 0; | 784 | input.fd = 0; |
| 777 | input.events = IOPAUSE_READ; | 785 | input.events = IOPAUSE_READ; |
| 778 | /* I be damned. Linux 2.6.18: this somehow affects | 786 | /* We cannot set NONBLOCK on fd #0 permanently - this setting |
| 779 | * OTHER processes! Konsole starts to redraw itself much slower! | 787 | * _isn't_ per-process! It is shared among all other processes |
| 780 | * This persists even after svlogd exits */ | 788 | * with the same stdin */ |
| 781 | ndelay_on(input.fd); | 789 | fl_flag_0 = fcntl(0, F_GETFL, 0); |
| 782 | sig_block(SIGTERM); | 790 | |
| 783 | sig_block(SIGCHLD); | 791 | sigemptyset(&blocked_sigset); |
| 784 | sig_block(SIGALRM); | 792 | sigaddset(&blocked_sigset, SIGTERM); |
| 785 | sig_block(SIGHUP); | 793 | sigaddset(&blocked_sigset, SIGCHLD); |
| 794 | sigaddset(&blocked_sigset, SIGALRM); | ||
| 795 | sigaddset(&blocked_sigset, SIGHUP); | ||
| 796 | sigprocmask(SIG_BLOCK, &blocked_sigset, NULL); | ||
| 786 | sig_catch(SIGTERM, sig_term_handler); | 797 | sig_catch(SIGTERM, sig_term_handler); |
| 787 | sig_catch(SIGCHLD, sig_child_handler); | 798 | sig_catch(SIGCHLD, sig_child_handler); |
| 788 | sig_catch(SIGALRM, sig_alarm_handler); | 799 | sig_catch(SIGALRM, sig_alarm_handler); |
| @@ -850,8 +861,13 @@ int svlogd_main(int argc, char **argv) | |||
| 850 | /* linelen == no of chars incl. '\n' (or == stdin_cnt) */ | 861 | /* linelen == no of chars incl. '\n' (or == stdin_cnt) */ |
| 851 | ch = lineptr[linelen-1]; | 862 | ch = lineptr[linelen-1]; |
| 852 | 863 | ||
| 853 | /* write out lineptr[0..linelen-1] to each log destination */ | 864 | /* TODO: biggest performance hit is coming from the fact |
| 854 | /* (or lineptr[-26..linelen-1] if timestamping) */ | 865 | * that we do not buffer writes. We may read many lines |
| 866 | * in one read() above, but will do one write() | ||
| 867 | * per line below. Should we use stdio? */ | ||
| 868 | |||
| 869 | /* write out lineptr[0..linelen-1] to each log destination | ||
| 870 | * (or lineptr[-26..linelen-1] if timestamping) */ | ||
| 855 | printlen = linelen; | 871 | printlen = linelen; |
| 856 | printptr = lineptr; | 872 | printptr = lineptr; |
| 857 | if (timestamp) { | 873 | if (timestamp) { |
