##// END OF EJS Templates
chg: exec pager in child process...
Jun Wu -
r29344:bb3d5c20 default
parent child Browse files
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 (pre 369741ef7253) */
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 == 0) {
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