* How to handle terminal detection in a daemon calling git? @ 2012-05-30 21:16 Travis P 2012-05-31 1:29 ` Jeff King 2012-05-31 3:14 ` Sitaram Chamarty 0 siblings, 2 replies; 9+ messages in thread From: Travis P @ 2012-05-30 21:16 UTC (permalink / raw) To: git I've got a script that runs in the background without a terminal. It actually does have STDOUT and STDERR set to a rotating log file. When it runs: /bin/sh -c 'cd /to/my/wc; git pull --ff-only' the git command fails (rc 32768). When it runs /bin/sh -c 'cd /to/my/wc; git pull --ff-only > /to/a/file 2>&1' or even /bin/sh -c 'cd /to/my/wc; git pull --ff-only | cat' then all is well. The command succeeds (rc 0, and I see the expected results). Piping through 'cat' is okay, but I'd rather avoid the 'trick'. Is there some way to communicate to git that it should operate just as if output were redirected? -Travis ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: How to handle terminal detection in a daemon calling git? 2012-05-30 21:16 How to handle terminal detection in a daemon calling git? Travis P @ 2012-05-31 1:29 ` Jeff King 2012-05-31 6:22 ` Junio C Hamano 2012-05-31 3:14 ` Sitaram Chamarty 1 sibling, 1 reply; 9+ messages in thread From: Jeff King @ 2012-05-31 1:29 UTC (permalink / raw) To: Travis P; +Cc: git On Wed, May 30, 2012 at 04:16:47PM -0500, Travis P wrote: > I've got a script that runs in the background without a terminal. > It actually does have STDOUT and STDERR set to a rotating log file. > > When it runs: > /bin/sh -c 'cd /to/my/wc; git pull --ff-only' > the git command fails (rc 32768). > > When it runs > /bin/sh -c 'cd /to/my/wc; git pull --ff-only > /to/a/file 2>&1' > > or even > /bin/sh -c 'cd /to/my/wc; git pull --ff-only | cat' > > then all is well. The command succeeds (rc 0, and I see the expected > results). If your stdout and stderr are not a terminal in the first place (you say they go to a rotating log file), then that should not be making a difference. Are they connected by a pty or something odd? Can you describe the failure in the first case more? Does git produce any output? > Piping through 'cat' is okay, but I'd rather avoid the 'trick'. Is > there some way to communicate to git that it should operate just as if > output were redirected? Git cares about terminals in only a few cases: 1. We check isatty(2) to enable progress reporting by default. You can use --no-progress to disable this. However, in your final example you only redirect stdout, which makes me think that stderr is not relevant. 2. We check isatty(1) for starting a pager, auto-selecting color, and in recent versions of git, for column support. But none of those things should be in use by git-pull anyway. 3. Merge was changed recently to open an editor when we have a terminal. That can be changed by setting GIT_MERGE_AUTOEDIT=no in the environment. However, since you pass --ff-only, we shouldn't be running merge at all. So I'm confused. Could it be not related to a terminal at all, but that there is a problem writing to the original stdout? Something that might give git a SIGPIPE? Can you describe the original stdout destination more? -Peff ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: How to handle terminal detection in a daemon calling git? 2012-05-31 1:29 ` Jeff King @ 2012-05-31 6:22 ` Junio C Hamano 2012-05-31 13:39 ` Travis P 2012-05-31 13:43 ` Travis P 0 siblings, 2 replies; 9+ messages in thread From: Junio C Hamano @ 2012-05-31 6:22 UTC (permalink / raw) To: Jeff King; +Cc: Travis P, git Jeff King <peff@peff.net> writes: > On Wed, May 30, 2012 at 04:16:47PM -0500, Travis P wrote: > >> I've got a script that runs in the background without a terminal. >> It actually does have STDOUT and STDERR set to a rotating log file. >> >> When it runs: >> /bin/sh -c 'cd /to/my/wc; git pull --ff-only' >> the git command fails (rc 32768). >> >> When it runs >> /bin/sh -c 'cd /to/my/wc; git pull --ff-only > /to/a/file 2>&1' >> >> or even >> /bin/sh -c 'cd /to/my/wc; git pull --ff-only | cat' >> >> then all is well. The command succeeds (rc 0, and I see the expected >> results). > > If your stdout and stderr are not a terminal in the first place (you say > they go to a rotating log file), then that should not be making a > difference. Are they connected by a pty or something odd? A more likely failure case is when fd 0, 1 and 2 are _closed_. I vaguely recall we once saw a failure report for that particular case, and then audited the code several years ago, but I do not offhand know if we have regressed over time. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: How to handle terminal detection in a daemon calling git? 2012-05-31 6:22 ` Junio C Hamano @ 2012-05-31 13:39 ` Travis P 2012-06-01 9:53 ` Jeff King 2012-05-31 13:43 ` Travis P 1 sibling, 1 reply; 9+ messages in thread From: Travis P @ 2012-05-31 13:39 UTC (permalink / raw) To: Junio C Hamano, Jeff King; +Cc: git On Wed, May 30, 2012, at 11:22 PM, Junio C Hamano wrote: > > A more likely failure case is when fd 0, 1 and 2 are _closed_. > > I vaguely recall we once saw a failure report for that particular > case, and then audited the code several years ago, but I do not > offhand know if we have regressed over time. Thanks all for your suggestions about where to look. I've been doing some more experiments, and I see that Junio's comment is very relevant. Here's what I learned this morning: it appears to work when I don't close STDIN. #close $_ for *STDIN, *STDOUT, *STDERR; # What I was doing. Fails. close $_ for *STDOUT, *STDERR; # Tried this, it works. *STDOUT = $log_fh; *STDERR = $log_fh; Jeff King wrote: > Could it be not related to a terminal at all, but that > there is a problem writing to the original stdout? Writing to stdout, stderr are both fine. I've been doing print STDOUT "Stdout test.\n"; print STDERR "Stderr test.\n"; right before the git commands to ensure that STDOUT, STDERR are hooked up fine to the log file. But, you gave me a hint that led to an error message. In a test rig where I've been looking at this just now, I was using backticks and losing a message to stderr: 'cd /local/test_web; git pull --ff-only | cat' rc=0 out={{}} 'cd /local/test_web; git pull --ff-only 2>&1 | cat' rc=0 out={{fatal: The remote end hung up unexpectedly Note however: despite the "fatal", I am seeing rc=0 and I was observing my working copy update as expected, so I wasn't looking for error output. > 1. We check isatty(2) to enable progress reporting by default. You can > use --no-progress to disable this. I don't see "--no-progress" making any difference. > 2. We check isatty(1) for starting a pager, auto-selecting color, and > in recent versions of git, for column support. But none of those > things should be in use by git-pull anyway. Ahh, this could be it: when the pull does receive an output and I'm running the command in the shell, I get output with a "+-" where the plus is green and the minus red. So, I think that git may be trying to check whether color (and columns?) is supported to output. However, it appears that this check is sensitive to stdin being connected (based on test mentioned earlier here), which is surprising. Is the code that calls isatty, calling it on all 3 descriptors, even when STDIN is not relevant? > 3. Merge was changed recently to open an editor when we have a > terminal. That can be changed by setting GIT_MERGE_AUTOEDIT=no in > the environment. However, since you pass --ff-only, we shouldn't be > running merge at all. Yes, I tried the env switch just to be sure, and this doesn't appear relevant. -Travis ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: How to handle terminal detection in a daemon calling git? 2012-05-31 13:39 ` Travis P @ 2012-06-01 9:53 ` Jeff King 2012-06-01 13:52 ` Travis 0 siblings, 1 reply; 9+ messages in thread From: Jeff King @ 2012-06-01 9:53 UTC (permalink / raw) To: Travis P; +Cc: Junio C Hamano, git On Thu, May 31, 2012 at 08:39:42AM -0500, Travis P wrote: > Here's what I learned this morning: it appears to work when I don't > close STDIN. > > #close $_ for *STDIN, *STDOUT, *STDERR; # What I was doing. Fails. > close $_ for *STDOUT, *STDERR; # Tried this, it works. > *STDOUT = $log_fh; > *STDERR = $log_fh; Yeah, don't do that. This can cause subtle bugs in subprocesses. For example: 1. You don't have a descriptor 0, because it is closed. 2. Some part of the program opens a new descriptor (e.g., to read a file, making a pipe, etc). This becomes descriptor 0, because it is the lowest unused descriptor. 3. The program wants to redirect its stdin (e.g., because it is forking and exec'ing a child). So it calls dup2(fd, 0), closing what was at stdin previously, which might have been valuable. The right thing to do is to redirect stdin from /dev/null, not close it entirely. > > 2. We check isatty(1) for starting a pager, auto-selecting color, > > and in recent versions of git, for column support. But none of > > those things should be in use by git-pull anyway. > > Ahh, this could be it: when the pull does receive an output and I'm > running the command in the shell, I get output with a "+-" where the > plus is green and the minus red. So, I think that git may be trying > to check whether color (and columns?) is supported to output. > However, it appears that this check is sensitive to stdin being > connected (based on test mentioned earlier here), which is surprising. > > Is the code that calls isatty, calling it on all 3 descriptors, even > when STDIN is not relevant? No, the color code just checks isatty(1). And even if it checked some random descriptor, the worst case should be that it affects the color flag. So I think the terminal thing is a red herring, and it is more likely you are seeing some subtle issue like the one I described above. -Peff ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: How to handle terminal detection in a daemon calling git? 2012-06-01 9:53 ` Jeff King @ 2012-06-01 13:52 ` Travis 2012-06-02 16:51 ` Jeff King 0 siblings, 1 reply; 9+ messages in thread From: Travis @ 2012-06-01 13:52 UTC (permalink / raw) To: Jeff King; +Cc: Junio C Hamano, git On Jun 1, 2012, at 4:53 AM, Jeff King wrote: > On Thu, May 31, 2012 at 08:39:42AM -0500, Travis P wrote: > >> Here's what I learned this morning: it appears to work when I don't >> close STDIN. >> >> #close $_ for *STDIN, *STDOUT, *STDERR; # What I was doing. Fails. >> close $_ for *STDOUT, *STDERR; # Tried this, it works. >> *STDOUT = $log_fh; >> *STDERR = $log_fh; > > Yeah, don't do that. This can cause subtle bugs in subprocesses. For > example: > > 1. You don't have a descriptor 0, because it is closed. > > 2. Some part of the program opens a new descriptor (e.g., to read a > file, making a pipe, etc). This becomes descriptor 0, because it > is > the lowest unused descriptor. > > 3. The program wants to redirect its stdin (e.g., because it is > forking and exec'ing a child). So it calls dup2(fd, 0), closing > what was at stdin previously, which might have been valuable. > > The right thing to do is to redirect stdin from /dev/null, not close > it > entirely. Ah, yes, that's a normal thing I would think about in C. In Perl, I imagined that those details were handled by Perl. With that in mind, I'm still seeing strange behavior when I do this, where it looks to me like I'm closing and then immediately assigning STDIN: my $null_in_fh; open($null_in_fh, '<', '/dev/null') or die; close *STDIN; # this appears to mess things up, even with the following assignment *STDIN = $null_in_fh; But if I don't do the close STDIN (with or without the glob), then things work. Maybe that assignment doesn't work for some Perl-ish reason. Because, if I just do this open(STDIN, '<', '/dev/null') or die; even after the close and/or assignment, then all appears okay. I'll stick with this last technique and just chalk it up to something to something about Perl I don't understand. (I had the idea that maybe I wanted to redirect /dev/null to STDIN at some point anyway.) Thanks for your comments. -Travis ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: How to handle terminal detection in a daemon calling git? 2012-06-01 13:52 ` Travis @ 2012-06-02 16:51 ` Jeff King 0 siblings, 0 replies; 9+ messages in thread From: Jeff King @ 2012-06-02 16:51 UTC (permalink / raw) To: Travis; +Cc: Junio C Hamano, git On Fri, Jun 01, 2012 at 08:52:04AM -0500, Travis wrote: > With that in mind, I'm still seeing strange behavior when I do this, > where it looks to me like I'm closing and then immediately assigning > STDIN: > > my $null_in_fh; > open($null_in_fh, '<', '/dev/null') or die; > close *STDIN; # this appears to mess things up, even with the > following assignment > *STDIN = $null_in_fh; Keep in mind that STDIN is a perl filehandle, not a file descriptor. When you close it, you close the filehandle and its underlying descriptor. Then you assign another filehandle to STDIN, which has its own descriptor. Try this: strace perl -e ' open($null, "</dev/null"); close *STDIN; *STDIN = $null; <STDIN>; ' you'll see that it is doing something like: open("/dev/null", O_RDONLY) = 3 close(0) = 0 read(3, "", 8192) = 0 The final read comes from the new descriptor, and we never re-opened descriptor 0. You are basically just pointing the name STDIN to a new handle, not doing anything with the underlying descriptor. > Because, if I just do this > open(STDIN, '<', '/dev/null') or die; > even after the close and/or assignment, then all appears okay. Yeah, this is the right way to re-open a descriptor in perl, because open() does the magic to dup2 the newly opened descriptor onto STDIN's descriptor. > Thanks for your comments. No problem. Glad it is working now. -Peff ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: How to handle terminal detection in a daemon calling git? 2012-05-31 6:22 ` Junio C Hamano 2012-05-31 13:39 ` Travis P @ 2012-05-31 13:43 ` Travis P 1 sibling, 0 replies; 9+ messages in thread From: Travis P @ 2012-05-31 13:43 UTC (permalink / raw) To: Junio C Hamano, Jeff King; +Cc: git Oops, I meant to mention that I'm using git 1.7.6 on RedHat. Someone else did the git installation. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: How to handle terminal detection in a daemon calling git? 2012-05-30 21:16 How to handle terminal detection in a daemon calling git? Travis P 2012-05-31 1:29 ` Jeff King @ 2012-05-31 3:14 ` Sitaram Chamarty 1 sibling, 0 replies; 9+ messages in thread From: Sitaram Chamarty @ 2012-05-31 3:14 UTC (permalink / raw) To: Travis P; +Cc: git On Thu, May 31, 2012 at 2:46 AM, Travis P <git@castle.fastmail.fm> wrote: > > I've got a script that runs in the background without a terminal. > It actually does have STDOUT and STDERR set to a rotating log file. > > When it runs: > /bin/sh -c 'cd /to/my/wc; git pull --ff-only' > the git command fails (rc 32768). > > When it runs > /bin/sh -c 'cd /to/my/wc; git pull --ff-only > /to/a/file 2>&1' > > or even > /bin/sh -c 'cd /to/my/wc; git pull --ff-only | cat' > > then all is well. The command succeeds (rc 0, and I see the expected > results). > > Piping through 'cat' is okay, but I'd rather avoid the 'trick'. Is > there > some way to communicate to git that it should operate just as if output > were redirected? would "git --no-pager" help? Honestly I don't know why your first error occurred at all -- they should all have worked, IMO. ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2012-06-02 16:52 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-05-30 21:16 How to handle terminal detection in a daemon calling git? Travis P 2012-05-31 1:29 ` Jeff King 2012-05-31 6:22 ` Junio C Hamano 2012-05-31 13:39 ` Travis P 2012-06-01 9:53 ` Jeff King 2012-06-01 13:52 ` Travis 2012-06-02 16:51 ` Jeff King 2012-05-31 13:43 ` Travis P 2012-05-31 3:14 ` Sitaram Chamarty
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).