Show More
@@ -417,21 +417,22 b' error:' | |||||
417 | abortmsgerrno("failed to set up signal handlers"); |
|
417 | abortmsgerrno("failed to set up signal handlers"); | |
418 | } |
|
418 | } | |
419 |
|
419 | |||
420 |
/* This implementation is based on hgext/pager.py (p |
|
420 | /* This implementation is based on hgext/pager.py (post 369741ef7253) | |
421 | static void setuppager(hgclient_t *hgc, const char *const args[], |
|
421 | * Return 0 if pager is not started, or pid of the pager */ | |
|
422 | static pid_t setuppager(hgclient_t *hgc, const char *const args[], | |||
422 | size_t argsize) |
|
423 | size_t argsize) | |
423 | { |
|
424 | { | |
424 | const char *pagercmd = hgc_getpager(hgc, args, argsize); |
|
425 | const char *pagercmd = hgc_getpager(hgc, args, argsize); | |
425 | if (!pagercmd) |
|
426 | if (!pagercmd) | |
426 | return; |
|
427 | return 0; | |
427 |
|
428 | |||
428 | int pipefds[2]; |
|
429 | int pipefds[2]; | |
429 | if (pipe(pipefds) < 0) |
|
430 | if (pipe(pipefds) < 0) | |
430 | return; |
|
431 | return 0; | |
431 | pid_t pid = fork(); |
|
432 | pid_t pid = fork(); | |
432 | if (pid < 0) |
|
433 | if (pid < 0) | |
433 | goto error; |
|
434 | goto error; | |
434 |
if (pid |
|
435 | if (pid > 0) { | |
435 | close(pipefds[0]); |
|
436 | close(pipefds[0]); | |
436 | if (dup2(pipefds[1], fileno(stdout)) < 0) |
|
437 | if (dup2(pipefds[1], fileno(stdout)) < 0) | |
437 | goto error; |
|
438 | goto error; | |
@@ -441,7 +442,7 b' static void setuppager(hgclient_t *hgc, ' | |||||
441 | } |
|
442 | } | |
442 | close(pipefds[1]); |
|
443 | close(pipefds[1]); | |
443 | hgc_attachio(hgc); /* reattach to pager */ |
|
444 | hgc_attachio(hgc); /* reattach to pager */ | |
444 | return; |
|
445 | return pid; | |
445 | } else { |
|
446 | } else { | |
446 | dup2(pipefds[0], fileno(stdin)); |
|
447 | dup2(pipefds[0], fileno(stdin)); | |
447 | close(pipefds[0]); |
|
448 | close(pipefds[0]); | |
@@ -451,13 +452,27 b' static void setuppager(hgclient_t *hgc, ' | |||||
451 | if (r < 0) { |
|
452 | if (r < 0) { | |
452 | abortmsgerrno("cannot start pager '%s'", pagercmd); |
|
453 | abortmsgerrno("cannot start pager '%s'", pagercmd); | |
453 | } |
|
454 | } | |
454 | return; |
|
455 | return 0; | |
455 | } |
|
456 | } | |
456 |
|
457 | |||
457 | error: |
|
458 | error: | |
458 | close(pipefds[0]); |
|
459 | close(pipefds[0]); | |
459 | close(pipefds[1]); |
|
460 | close(pipefds[1]); | |
460 | abortmsgerrno("failed to prepare pager"); |
|
461 | abortmsgerrno("failed to prepare pager"); | |
|
462 | return 0; | |||
|
463 | } | |||
|
464 | ||||
|
465 | static void waitpager(pid_t pid) | |||
|
466 | { | |||
|
467 | /* close output streams to notify the pager its input ends */ | |||
|
468 | fclose(stdout); | |||
|
469 | fclose(stderr); | |||
|
470 | while (1) { | |||
|
471 | pid_t ret = waitpid(pid, NULL, 0); | |||
|
472 | if (ret == -1 && errno == EINTR) | |||
|
473 | continue; | |||
|
474 | break; | |||
|
475 | } | |||
461 | } |
|
476 | } | |
462 |
|
477 | |||
463 | /* Run instructions sent from the server like unlink and set redirect path |
|
478 | /* Run instructions sent from the server like unlink and set redirect path | |
@@ -585,9 +600,12 b' int main(int argc, const char *argv[], c' | |||||
585 | } |
|
600 | } | |
586 |
|
601 | |||
587 | setupsignalhandler(hgc_peerpid(hgc)); |
|
602 | setupsignalhandler(hgc_peerpid(hgc)); | |
588 | setuppager(hgc, argv + 1, argc - 1); |
|
603 | pid_t pagerpid = setuppager(hgc, argv + 1, argc - 1); | |
589 | int exitcode = hgc_runcommand(hgc, argv + 1, argc - 1); |
|
604 | int exitcode = hgc_runcommand(hgc, argv + 1, argc - 1); | |
590 | hgc_close(hgc); |
|
605 | hgc_close(hgc); | |
591 | freecmdserveropts(&opts); |
|
606 | freecmdserveropts(&opts); | |
|
607 | if (pagerpid) | |||
|
608 | waitpager(pagerpid); | |||
|
609 | ||||
592 | return exitcode; |
|
610 | return exitcode; | |
593 | } |
|
611 | } |
@@ -201,3 +201,24 b' Pager works with hg aliases including en' | |||||
201 | paged! '1\n' |
|
201 | paged! '1\n' | |
202 | $ A=2 hg --config pager.attend-printa=yes printa |
|
202 | $ A=2 hg --config pager.attend-printa=yes printa | |
203 | paged! '2\n' |
|
203 | paged! '2\n' | |
|
204 | ||||
|
205 | Pager should not override the exit code of other commands | |||
|
206 | ||||
|
207 | $ cat >> $TESTTMP/fortytwo.py <<'EOF' | |||
|
208 | > from mercurial import cmdutil, commands | |||
|
209 | > cmdtable = {} | |||
|
210 | > command = cmdutil.command(cmdtable) | |||
|
211 | > @command('fortytwo', [], 'fortytwo', norepo=True) | |||
|
212 | > def fortytwo(ui, *opts): | |||
|
213 | > ui.write('42\n') | |||
|
214 | > return 42 | |||
|
215 | > EOF | |||
|
216 | ||||
|
217 | $ cat >> $HGRCPATH <<'EOF' | |||
|
218 | > [extensions] | |||
|
219 | > fortytwo = $TESTTMP/fortytwo.py | |||
|
220 | > EOF | |||
|
221 | ||||
|
222 | $ hg fortytwo --pager=on | |||
|
223 | paged! '42\n' | |||
|
224 | [42] |
General Comments 0
You need to be logged in to leave comments.
Login now