A former colleague wanted to be able to have an arbitrary action taken if a job takes too long to complete, which is almost what $REPORTTIME gives us, but we can't have arbitrary actions taken. So it seems like what's needed is a hook function (and array). Below is a patch which I will *not* commit, because it's a first pass to get feedback. For one thing, it hooks into printtime so is also invoked when the time pre-command modifier prints output. This could be useful, but might not be desired; I figured it would be best to pass the printtime() `desc` parameter as the first parameter to the new hook, but while that lets folks analyse and short-circuit I think it's putting the onus in the wrong place. I'm tempted to make this $REPORTTIME only, by amending printtime() to take a new bool parameter and renaming the hook to reporttime(). Another issue is that reporttime() (shell-level function) becomes a new magic function additionally called, and we don't have namespaces for functions, but I think our normal approach is to accept that it _might_ conflict with scripts, right? Then there's the parameters needed; I've opted to pass in the desc (which for $REPORTTIME is the command invoked) in the first parameter then elapsed/user/system/total time as subsequent parameters. I half think it might be worth putting a bunch of the various variables used for $TIMEFMT into a hash, but if I do that I'm likely to want to add an existshookfunc() check to reduce the work, or create a magic hash which extracts values and make $TIMEFMT reduce to referencing that hash, or a new print flag similar to -P which can be used to get the same expansions as $TIMEFMT. (Patch also fixes an unused variable complaint) What do people think? Is this generally useful enough, and should I amend printtime? How best to pass the various values or make them available? I *think* I favour: 1: adding a new parameter to printtime(); 2: moving moving the printtime() expansion logic into a function which can be used by "print -T" or the current $TIMEFMT expansion; this involves making a new global which can hold the last child_times_t object around for implicit use; 3: calling the hook "reporttime" and then the hook functions can just use "print -T" for any data they want. I can add documentation when things are more firmed, then resend the patch and go through the zsh/git/listid cycle. Thoughts? -Phil diff --git a/Src/jobs.c b/Src/jobs.c index 0dbb10b..2ca3bfe 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -645,11 +645,13 @@ static void printtime(struct timeval *real, child_times_t *ti, char *desc) { char *s; + LinkList funcargs; double elapsed_time, user_time, system_time; #ifdef HAVE_GETRUSAGE double total_time; #endif int percent, desclen; + char buf[20]; if (!desc) { @@ -830,6 +832,19 @@ printtime(struct timeval *real, child_times_t *ti, char *desc) unqueue_signals(); putc('\n', stderr); fflush(stderr); + + funcargs = newlinklist(); + addlinknode(funcargs, "printtime"); + addlinknode(funcargs, desc); + sprintf(buf, "%4.2f", elapsed_time); + addlinknode(funcargs, ztrdup(buf)); + sprintf(buf, "%4.2f", user_time); + addlinknode(funcargs, ztrdup(buf)); + sprintf(buf, "%4.2f", system_time); + addlinknode(funcargs, ztrdup(buf)); + sprintf(buf, "%4.2f", total_time); + addlinknode(funcargs, ztrdup(buf)); + callhookfunc("printtime", funcargs, 1, NULL); } /**/ @@ -1714,7 +1729,9 @@ static int hackspace; void init_jobs(char **argv, char **envp) { +#ifndef HAVE_SETPROCTITLE char *p, *q; +#endif size_t init_bytes = MAXJOBS_ALLOC*sizeof(struct job); /*
Attachment:
pgpS9NoYNQzia.pgp
Description: PGP signature