mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-24 01:24:26 +01:00
connectd: implement @ correctly.
dev_blackhole_fd was a hack, and doesn't work well now we are async (it worked for sync comms in per-peer daemons, but now we could sneak through a read before we get to the next write). So, make explicit flags and use them. This is much easier now we have all peer comms in one place. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -105,56 +105,4 @@ void dev_sabotage_fd(int fd, bool close_fd)
|
||||
dup2(fds[1], fd);
|
||||
close(fds[1]);
|
||||
}
|
||||
|
||||
/* Replace fd with blackhole until dev_disconnect file is truncated. */
|
||||
void dev_blackhole_fd(int fd)
|
||||
{
|
||||
int fds[2];
|
||||
int i;
|
||||
struct stat st;
|
||||
|
||||
int maxfd;
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) != 0)
|
||||
err(1, "dev_blackhole_fd: creating socketpair");
|
||||
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
err(1, "dev_blackhole_fd: forking");
|
||||
case 0:
|
||||
/* Close everything but the dev_disconnect_fd, the socket
|
||||
* which is pretending to be the peer, and stderr.
|
||||
* The "correct" way to do this would be to move the
|
||||
* fds we want to preserve to the low end (0, 1, 2...)
|
||||
* of the fd space and then just do a single closefrom
|
||||
* call, but dup2 could fail with ENFILE (which is a
|
||||
* *system*-level error, i.e. the entire system has too
|
||||
* many processes with open files) and we have no
|
||||
* convenient way to inform the parent of the error.
|
||||
* So loop until we reach whichever is higher of fds[0]
|
||||
* or dev_disconnect_fd, and *then* closefrom after that.
|
||||
*/
|
||||
maxfd = (fds[0] > dev_disconnect_fd) ? fds[0] :
|
||||
dev_disconnect_fd ;
|
||||
for (i = 0; i < maxfd; i++)
|
||||
if (i != fds[0]
|
||||
&& i != dev_disconnect_fd
|
||||
&& i != STDERR_FILENO)
|
||||
close(i);
|
||||
closefrom(maxfd + 1);
|
||||
|
||||
/* Close once dev_disconnect file is truncated. */
|
||||
for (;;) {
|
||||
if (fstat(dev_disconnect_fd, &st) != 0)
|
||||
err(1, "fstat of dev_disconnect_fd failed");
|
||||
if (st.st_size == 0)
|
||||
_exit(0);
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
close(fds[0]);
|
||||
dup2(fds[1], fd);
|
||||
close(fds[1]);
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user