Giorgos Keramidas wrote: >On 2006-08-11 21:31, Julian Elischer <julian_at_elischer.org> wrote: > > >>Giorgos Keramidas wrote: >> >> >>>On 2006-08-11 20:54, Julian Elischer <julian_at_elischer.org> wrote: >>> >>> >>>>Yes I said I hacked it in :-) >>>>In my app you will never have such long lines.. >>>>basically you need something that reads lines and tells you how much it >>>>read.. >>>>(I have no idea WHY fgets need sto return the START.. you already KNOW >>>>that!) >>>>it'd be nice if you didn't have to to a strlen() on each line. >>>> >>>> >>>Perhaps the solution Sam proposed is much better then? >>> >>>To read one >>>character at-a-time and only special-case the '\n' characters? >>> >>> >>I didn't see that being mentionned anywhere, but I guess compared to >>running date once for every line >>I could live with a strlen(). :-) >>it'd probably be more efficient than doing it one char at a time. >> >> >> >>>Maybe something like this? >>> >>> if (sflag) { >>> >>> >>> >>> >>> >>[...] >> >> >> >>> otval = tval; >>> } >>> (void)printf("%s", buf); >>> if (fflush(stdout)) >>> >>> >>> >>> >>wonder if it would want to be flushed less often if stdout was a file.. >>I think stdio would do the right thing in most cases so I guess teh >>fflush woudl only be needed at the end, after the last file, >>or maybe just on a signal handler so it flushes out the last buffer on ^C >> >> > >IIRC, stdio can buffer more than one line, so now that you mention it, >maybe it is a good idea to flush at every '\n' character to make output >appear every time there's a complete line ready. > > stdio will automatically flush pipe and terminal output at every \n. the problem is if you are writing to a file. If you get a signal it just calls _exit() which doesn't flush anything. if it does an exit() it flushes the output so that would be ok. signal handlers shouldn't call stdio as they are not async-safe, so making a signal handler that calls fflush is not possible. I tried making the signal handler just set a variable that makes the main loop quit, flush and exit, but believe it or not, fgets() doesn't return from a signal. so you hit ^C but it doesn't notice the flag that is set until you then hit CR. hmm maybe if the signal handler closed file descriptor 0....... heh, yep that makes it quit.. try this on for size :) >I'm too sleepy to run tests now, but if you still want something inside >date(1) -- which is probably the only logical place to put it (to let us >leverage the date/time formatting code date(1) already has) -- then I >can run a few tests during the weekend and see which approach works >better, for some definition of `better' :-) > > ? date ? date.1.gz ? xx Index: date.c =================================================================== RCS file: /usr/local/cvsroot/freebsd/src/bin/date/date.c,v retrieving revision 1.47 diff -u -r1.47 date.c --- date.c 10 Jan 2005 08:39:21 -0000 1.47 +++ date.c 12 Aug 2006 05:50:57 -0000 _at__at_ -49,6 +49,7 _at__at_ #include <err.h> #include <locale.h> #include <libutil.h> +#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> _at__at_ -64,17 +65,19 _at__at_ static time_t tval; int retval; +int cleanup; static void setthetime(const char *, const char *, int, int); static void badformat(void); static void usage(void); +static void sighandler(int); int main(int argc, char *argv[]) { struct timezone tz; int ch, rflag; - int jflag, nflag; + int jflag, nflag, sflag; const char *format; char buf[1024]; char *endptr, *fmt; _at__at_ -89,9 +92,9 _at__at_ (void) setlocale(LC_TIME, ""); tz.tz_dsttime = tz.tz_minuteswest = 0; rflag = 0; - jflag = nflag = 0; + sflag = jflag = nflag = 0; set_timezone = 0; - while ((ch = getopt(argc, argv, "d:f:jnr:t:uv:")) != -1) + while ((ch = getopt(argc, argv, "d:f:jnr:t:uv:s")) != -1) switch((char)ch) { case 'd': /* daylight savings time */ tz.tz_dsttime = strtol(optarg, &endptr, 10) ? 1 : 0; _at__at_ -114,6 +117,9 _at__at_ if (*tmp != 0) usage(); break; + case 's': /* don't set network */ + sflag = 1; /* stream mode */ + break; case 't': /* minutes west of UTC */ /* error check; don't allow "PST" */ tz.tz_minuteswest = strtol(optarg, &endptr, 10); _at__at_ -160,22 +166,76 _at__at_ if (*argv && **argv == '+') format = *argv + 1; - lt = *localtime(&tval); - badv = vary_apply(v, <); - if (badv) { - fprintf(stderr, "%s: Cannot apply date adjustment\n", - badv->arg); + if (sflag) { + char linebuf[2048]; + time_t otval = 0; + int len; + int complete = 1; + + cleanup = 0; + signal(SIGHUP, sighandler); + signal(SIGINT, sighandler); + signal(SIGTERM, sighandler); + signal(SIGXCPU, sighandler); + signal(SIGXFSZ, sighandler); + signal(SIGVTALRM, sighandler); + signal(SIGPROF, sighandler); + while (fgets(linebuf, 2048, stdin) && cleanup == 0) { + if (!rflag && time(&tval) == -1) + err(1, "time"); + + if (complete != 0 && tval != otval) { + lt = *localtime(&tval); + badv = vary_apply(v, <); + if (badv) { + fprintf(stderr, "%s: Cannot apply date adjustment\n", + badv->arg); + vary_destroy(v); + usage(); + } + (void)strftime(buf, sizeof(buf), format, <); + otval = tval; + } + if (complete != 0) { + if (printf("%s", buf) < 0) + break; + complete = 0; + } + if (fputs(linebuf, stdout) == EOF) + break; + len = strlen(linebuf); + if (linebuf[len - 1] == '\n') + complete = 1; + } + if (fflush(stdout)) { + err(1, "stdout"); + } + } else { + lt = *localtime(&tval); + badv = vary_apply(v, <); + if (badv) { + fprintf(stderr, "%s: Cannot apply date adjustment\n", + badv->arg); + vary_destroy(v); + usage(); + } vary_destroy(v); - usage(); + (void)strftime(buf, sizeof(buf), format, <); + (void)printf("%s\n", buf); + if (fflush(stdout)) + err(1, "stdout"); } - vary_destroy(v); - (void)strftime(buf, sizeof(buf), format, <); - (void)printf("%s\n", buf); - if (fflush(stdout)) - err(1, "stdout"); exit(retval); } +static void +sighandler(int arg) +{ + arg = 0; /* shut up gcc */ + close(0); + cleanup = 1; +} + #define ATOI2(s) ((s) += 2, ((s)[-2] - '0') * 10 + ((s)[-1] - '0')) static void _at__at_ -299,7 +359,7 _at__at_ usage(void) { (void)fprintf(stderr, "%s\n%s\n", - "usage: date [-jnu] [-d dst] [-r seconds] [-t west] " + "usage: date [-jnus] [-d dst] [-r seconds] [-t west] " "[-v[+|-]val[ymwdHMS]] ... ", " " "[-f fmt date | [[[[[cc]yy]mm]dd]HH]MM[.ss]] [+format]");Received on Sat Aug 12 2006 - 03:53:01 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:58 UTC