<feed xmlns='http://www.w3.org/2005/Atom'>
<title>delta/git.git, branch jk/execv-dashed-external</title>
<subtitle>github.com: git/git.git
</subtitle>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/git.git/'/>
<entry>
<title>run-command: fix segfault when cleaning forked async process</title>
<updated>2017-03-18T17:29:15+00:00</updated>
<author>
<name>Jeff King</name>
<email>peff@peff.net</email>
</author>
<published>2017-03-17T23:20:04+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/git.git/commit/?id=7b91929ba0422435c193c506dbaa593964be6e84'/>
<id>7b91929ba0422435c193c506dbaa593964be6e84</id>
<content type='text'>
Callers of the run-command API may mark a child as
"clean_on_exit"; it gets added to a list and killed when the
main process dies.  Since commit 46df6906f
(execv_dashed_external: wait for child on signal death,
2017-01-06), we respect an extra "wait_after_clean" flag,
which we expect to find in the child_process struct.

When Git is built with NO_PTHREADS, we start "struct
async" processes by forking rather than spawning a thread.
The resulting processes get added to the cleanup list but
they don't have a child_process struct, and the cleanup
function ends up dereferencing NULL.

We should notice this case and assume that the processes do
not need to be waited for (i.e., the same behavior they had
before 46df6906f).

Reported-by: Brandon Williams &lt;bmwill@google.com&gt;
Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Reviewed-by: Jonathan Nieder &lt;jrnieder@gmail.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Callers of the run-command API may mark a child as
"clean_on_exit"; it gets added to a list and killed when the
main process dies.  Since commit 46df6906f
(execv_dashed_external: wait for child on signal death,
2017-01-06), we respect an extra "wait_after_clean" flag,
which we expect to find in the child_process struct.

When Git is built with NO_PTHREADS, we start "struct
async" processes by forking rather than spawning a thread.
The resulting processes get added to the cleanup list but
they don't have a child_process struct, and the cleanup
function ends up dereferencing NULL.

We should notice this case and assume that the processes do
not need to be waited for (i.e., the same behavior they had
before 46df6906f).

Reported-by: Brandon Williams &lt;bmwill@google.com&gt;
Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Reviewed-by: Jonathan Nieder &lt;jrnieder@gmail.com&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>execv_dashed_external: wait for child on signal death</title>
<updated>2017-01-09T21:41:40+00:00</updated>
<author>
<name>Jeff King</name>
<email>peff@peff.net</email>
</author>
<published>2017-01-07T01:22:23+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/git.git/commit/?id=46df6906f3aaf74dafe2026b028c8c5c1a0d5f58'/>
<id>46df6906f3aaf74dafe2026b028c8c5c1a0d5f58</id>
<content type='text'>
When you hit ^C to interrupt a git command going to a pager,
this usually leaves the pager running. But when a dashed
external is in use, the pager ends up in a funny state and
quits (but only after eating one more character from the
terminal!). This fixes it.

Explaining the reason will require a little background.

When git runs a pager, it's important for the git process to
hang around and wait for the pager to finish, even though it
has no more data to feed it. This is because git spawns the
pager as a child, and thus the git process is the session
leader on the terminal. After it dies, the pager will finish
its current read from the terminal (eating the one
character), and then get EIO trying to read again.

When you hit ^C, that sends SIGINT to git and to the pager,
and it's a similar situation.  The pager ignores it, but the
git process needs to hang around until the pager is done. We
addressed that long ago in a3da882120 (pager: do
wait_for_pager on signal death, 2009-01-22).

But when you have a dashed external (or an alias pointing to
a builtin, which will re-exec git for the builtin), there's
an extra process in the mix. For instance, running:

  $ git -c alias.l=log l

will end up with a process tree like:

  git (parent)
    \
     git-log (child)
      \
       less (pager)

If you hit ^C, SIGINT goes to all of them. The pager ignores
it, and the child git process will end up in wait_for_pager().
But the parent git process will die, and the usual EIO
trouble happens.

So we really want the parent git process to wait_for_pager(),
but of course it doesn't know anything about the pager at
all, since it was started by the child.  However, we can
have it wait on the git-log child, which in turn is waiting
on the pager. And that's what this patch does.

There are a few design decisions here worth explaining:

  1. The new feature is attached to run-command's
     clean_on_exit feature. Partly this is convenience,
     since that feature already has a signal handler that
     deals with child cleanup.

     But it's also a meaningful connection. The main reason
     that dashed externals use clean_on_exit is to bind the
     two processes together. If somebody kills the parent
     with a signal, we propagate that to the child (in this
     instance with SIGINT, we do propagate but it doesn't
     matter because the original signal went to the whole
     process group). Likewise, we do not want the parent
     to go away until the child has done so.

     In a traditional Unix world, we'd probably accomplish
     this binding by just having the parent execve() the
     child directly. But since that doesn't work on Windows,
     everything goes through run_command's more spawn-like
     interface.

  2. We do _not_ automatically waitpid() on any
     clean_on_exit children. For dashed externals this makes
     sense; we know that the parent is doing nothing but
     waiting for the child to exit anyway. But with other
     children, it's possible that the child, after getting
     the signal, could be waiting on the parent to do
     something (like closing a descriptor). If we were to
     wait on such a child, we'd end up in a deadlock. So
     this errs on the side of caution, and lets callers
     enable the feature explicitly.

  3. When we send children the cleanup signal, we send all
     the signals first, before waiting on any children. This
     is to avoid the case where one child might be waiting
     on another one to exit, causing a deadlock. We inform
     all of them that it's time to die before reaping any.

     In practice, there is only ever one dashed external run
     from a given process, so this doesn't matter much now.
     But it future-proofs us if other callers start using
     the wait_after_clean mechanism.

There's no automated test here, because it would end up racy
and unportable. But it's easy to reproduce the situation by
running the log command given above and hitting ^C.

Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When you hit ^C to interrupt a git command going to a pager,
this usually leaves the pager running. But when a dashed
external is in use, the pager ends up in a funny state and
quits (but only after eating one more character from the
terminal!). This fixes it.

Explaining the reason will require a little background.

When git runs a pager, it's important for the git process to
hang around and wait for the pager to finish, even though it
has no more data to feed it. This is because git spawns the
pager as a child, and thus the git process is the session
leader on the terminal. After it dies, the pager will finish
its current read from the terminal (eating the one
character), and then get EIO trying to read again.

When you hit ^C, that sends SIGINT to git and to the pager,
and it's a similar situation.  The pager ignores it, but the
git process needs to hang around until the pager is done. We
addressed that long ago in a3da882120 (pager: do
wait_for_pager on signal death, 2009-01-22).

But when you have a dashed external (or an alias pointing to
a builtin, which will re-exec git for the builtin), there's
an extra process in the mix. For instance, running:

  $ git -c alias.l=log l

will end up with a process tree like:

  git (parent)
    \
     git-log (child)
      \
       less (pager)

If you hit ^C, SIGINT goes to all of them. The pager ignores
it, and the child git process will end up in wait_for_pager().
But the parent git process will die, and the usual EIO
trouble happens.

So we really want the parent git process to wait_for_pager(),
but of course it doesn't know anything about the pager at
all, since it was started by the child.  However, we can
have it wait on the git-log child, which in turn is waiting
on the pager. And that's what this patch does.

There are a few design decisions here worth explaining:

  1. The new feature is attached to run-command's
     clean_on_exit feature. Partly this is convenience,
     since that feature already has a signal handler that
     deals with child cleanup.

     But it's also a meaningful connection. The main reason
     that dashed externals use clean_on_exit is to bind the
     two processes together. If somebody kills the parent
     with a signal, we propagate that to the child (in this
     instance with SIGINT, we do propagate but it doesn't
     matter because the original signal went to the whole
     process group). Likewise, we do not want the parent
     to go away until the child has done so.

     In a traditional Unix world, we'd probably accomplish
     this binding by just having the parent execve() the
     child directly. But since that doesn't work on Windows,
     everything goes through run_command's more spawn-like
     interface.

  2. We do _not_ automatically waitpid() on any
     clean_on_exit children. For dashed externals this makes
     sense; we know that the parent is doing nothing but
     waiting for the child to exit anyway. But with other
     children, it's possible that the child, after getting
     the signal, could be waiting on the parent to do
     something (like closing a descriptor). If we were to
     wait on such a child, we'd end up in a deadlock. So
     this errs on the side of caution, and lets callers
     enable the feature explicitly.

  3. When we send children the cleanup signal, we send all
     the signals first, before waiting on any children. This
     is to avoid the case where one child might be waiting
     on another one to exit, causing a deadlock. We inform
     all of them that it's time to die before reaping any.

     In practice, there is only ever one dashed external run
     from a given process, so this doesn't matter much now.
     But it future-proofs us if other callers start using
     the wait_after_clean mechanism.

There's no automated test here, because it would end up racy
and unportable. But it's easy to reproduce the situation by
running the log command given above and hitting ^C.

Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>execv_dashed_external: stop exiting with negative code</title>
<updated>2017-01-09T21:41:35+00:00</updated>
<author>
<name>Jeff King</name>
<email>peff@peff.net</email>
</author>
<published>2017-01-07T01:17:48+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/git.git/commit/?id=246f0edec0b789ccfeebcf7fef85417b7cb04425'/>
<id>246f0edec0b789ccfeebcf7fef85417b7cb04425</id>
<content type='text'>
When we try to exec a git sub-command, we pass along the
status code from run_command(). But that may return -1 if we
ran into an error with pipe() or execve(). This tends to
work (and end up as 255 due to twos-complement wraparound
and truncation), but in general it's probably a good idea to
avoid negative exit codes for portability.

We can easily translate to the normal generic "128" code we
get when syscalls cause us to die.

Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When we try to exec a git sub-command, we pass along the
status code from run_command(). But that may return -1 if we
ran into an error with pipe() or execve(). This tends to
work (and end up as 255 due to twos-complement wraparound
and truncation), but in general it's probably a good idea to
avoid negative exit codes for portability.

We can easily translate to the normal generic "128" code we
get when syscalls cause us to die.

Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>execv_dashed_external: use child_process struct</title>
<updated>2017-01-09T21:41:33+00:00</updated>
<author>
<name>Jeff King</name>
<email>peff@peff.net</email>
</author>
<published>2017-01-07T01:16:24+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/git.git/commit/?id=2b296c93d49d65303a4ce291225c8755eeab1ff8'/>
<id>2b296c93d49d65303a4ce291225c8755eeab1ff8</id>
<content type='text'>
When we run a dashed external, we use the one-liner
run_command_v_opt() to do so. Let's switch to using a
child_process struct, which has two advantages:

  1. We can drop all of the allocation and cleanup code for
     building our custom argv array, and just rely on the
     builtin argv_array (at the minor cost of doing a few
     extra mallocs).

  2. We have access to the complete range of child_process
     options, not just the ones that the "_opt()" form can
     forward.

Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When we run a dashed external, we use the one-liner
run_command_v_opt() to do so. Let's switch to using a
child_process struct, which has two advantages:

  1. We can drop all of the allocation and cleanup code for
     building our custom argv array, and just rely on the
     builtin argv_array (at the minor cost of doing a few
     extra mallocs).

  2. We have access to the complete range of child_process
     options, not just the ones that the "_opt()" form can
     forward.

Signed-off-by: Jeff King &lt;peff@peff.net&gt;
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Sync with maint-2.10</title>
<updated>2016-12-05T19:25:47+00:00</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2016-12-05T19:25:47+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/git.git/commit/?id=a274e0a036ea886a31f8b216564ab1b4a3142f6c'/>
<id>a274e0a036ea886a31f8b216564ab1b4a3142f6c</id>
<content type='text'>
* maint-2.10:
  preparing for 2.10.3
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* maint-2.10:
  preparing for 2.10.3
</pre>
</div>
</content>
</entry>
<entry>
<title>preparing for 2.10.3</title>
<updated>2016-12-05T19:25:02+00:00</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2016-12-05T19:25:02+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/git.git/commit/?id=c3808ca6982b0ad7ee9b87eca9b50b9a24ec08b0'/>
<id>c3808ca6982b0ad7ee9b87eca9b50b9a24ec08b0</id>
<content type='text'>
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Signed-off-by: Junio C Hamano &lt;gitster@pobox.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'jk/common-main' into maint-2.10</title>
<updated>2016-12-05T19:24:28+00:00</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2016-12-05T19:24:17+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/git.git/commit/?id=cd1c2e7301820f9a198c8d665cd72d930233d02a'/>
<id>cd1c2e7301820f9a198c8d665cd72d930233d02a</id>
<content type='text'>
* jk/common-main:
  common-main: stop munging argv[0] path
  git-compat-util: move content inside ifdef/endif guards
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* jk/common-main:
  common-main: stop munging argv[0] path
  git-compat-util: move content inside ifdef/endif guards
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'tk/diffcore-delta-remove-unused' into maint</title>
<updated>2016-11-29T21:28:03+00:00</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2016-11-29T21:28:03+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/git.git/commit/?id=0a79ccaac7dcfaf93294979fd9608d0f95fd7a47'/>
<id>0a79ccaac7dcfaf93294979fd9608d0f95fd7a47</id>
<content type='text'>
Code cleanup.

* tk/diffcore-delta-remove-unused:
  diffcore-delta: remove unused parameter to diffcore_count_changes()
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Code cleanup.

* tk/diffcore-delta-remove-unused:
  diffcore-delta: remove unused parameter to diffcore_count_changes()
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'jk/create-branch-remove-unused-param' into maint</title>
<updated>2016-11-29T21:28:02+00:00</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2016-11-29T21:28:02+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/git.git/commit/?id=af8d6a9821d79f18c8b645582b5b5d251066ae2f'/>
<id>af8d6a9821d79f18c8b645582b5b5d251066ae2f</id>
<content type='text'>
Code clean-up.

* jk/create-branch-remove-unused-param:
  create_branch: drop unused "head" parameter
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Code clean-up.

* jk/create-branch-remove-unused-param:
  create_branch: drop unused "head" parameter
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'nd/worktree-lock' into maint</title>
<updated>2016-11-29T21:28:02+00:00</updated>
<author>
<name>Junio C Hamano</name>
<email>gitster@pobox.com</email>
</author>
<published>2016-11-29T21:28:02+00:00</published>
<link rel='alternate' type='text/html' href='http://trove.baserock.org/cgit/delta/git.git/commit/?id=797d1a4672c67ed4e560c67c5d1fe208e31f0b47'/>
<id>797d1a4672c67ed4e560c67c5d1fe208e31f0b47</id>
<content type='text'>
Typofix.

* nd/worktree-lock:
  git-worktree.txt: fix typo "to"/"two", and add comma
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Typofix.

* nd/worktree-lock:
  git-worktree.txt: fix typo "to"/"two", and add comma
</pre>
</div>
</content>
</entry>
</feed>
