Issue 2701 clone ssh repo fails when using Ctrl-C to stop getting patches

Title clone ssh repo fails when using Ctrl-C to stop getting patches
Priority Status resolved
Milestone Resolved in 2.18.1
Superseder Nosy List bfrk
Assigned To

Created on 2023-04-02.09:14:43 by bfrk, last changed 2023-06-24.20:29:42 by noreply.

msg23260 (view) Author: bfrk Date: 2023-04-02.09:14:42
> darcs clone darcs-unstable@darcs.net:/opt/darcs/screened -v --no-cache
Welcome to the darcs screened repository.

If you would like to contribute, please read our guide for contributors:

Thanks and happy hacking!
Cloning packed basic repository.
Done fetching and unpacking basic pack.
Copying hashed inventory from remote repo...
Copying patches, to get lazy repository hit ctrl-C...
Using patches pack.
^CUsing lazy repository.

By the way, I could not reach the following location:
Unless you plan to restore access to it, you should delete the corresponding entry from 
> echo $?

This happens only when cloning via ssh, not http(s).

It worked with darcs-2.14.2 but no longer with darcs-2.16.5. I am trying to narrow it down, 
which I'll have to do manually since you have to hit Ctrl-C at the right moment...
msg23261 (view) Author: bfrk Date: 2023-04-02.12:58:29
The patch that breaks it is

patch 67418ecc6fa5c29a46818f918624c7ad2b3bcf83
Author: Ben Franksen <ben.franksen@online.de>
Date:   Wed Nov 14 22:00:30 CET 2018
  * resolve issue2603: warn and mark conflicts when cloning


Marking conflicts requires access to the patches since the latest clean tag. Thus, 
even if we clone lazily, we need to download those patches. This causes no serious 
problems with http access or when we pass --lazy, it fails only when we hit Ctrl-C to 
stop downloading patches. Running with --debug shows this:

catchall: fd:12: hFlush: resource vanished (Broken pipe)

This looks to me as if the SIGINT from hitting Ctrl-C has the undesired side-effect 
of killing the running `ssh <user@host> darcs transfer-mode` command. Indeed, when I 
add a getChar after the allowCtrlC block to make execution pause, suspend the 
process, and look at the process table, I see that the ssh child is "defunct" i.e. 
dead. This explains why the above patch breaks it, since before that patch we never 
downloaded any files after the actions wrapped in allowCtrlC.

The clean fix would be to somehow protect the child process from the SIGINT. 
Searching for how to do this on the internet reveals that (apart from modifying the 
child process so that it ignores SIGINT, which we cannot do because the child in 
question is the program named 'ssh') the only solution is to assign the child to 
another process group. Doing this right is fiddly and hardly portable.

A crude but effective solution is to terminate and restart the remote transfer-mode 
children. I tried that and it fixes the problem, again confirming that my analysis is 

Comments or ideas for a better solution are welcome!
msg23404 (view) Author: noreply Date: 2023-06-24.20:29:39
The following patch sent by Ben Franksen <ben.franksen@online.de> updated issue issue2701 with

Hash: 2d6e625736208ef4cbeae4e80b26c5076f8f3873
Author: Ben Franksen <ben.franksen@online.de>
* resolve issue2701: clone ssh repo with Ctrl-C

  This solves the problem by terminating all child processes that run a remote
  'darcs transfer-mode' and recording that in the sshConnections MVar. The
  next copySSH will then start a new child.
Date User Action Args
2023-04-02 09:14:43bfrkcreate
2023-04-02 12:58:29bfrksetmessages: + msg23261
2023-06-24 20:29:42noreplysetstatus: unknown -> resolved
messages: + msg23404
resolvedin: 2.18.1