Closed hummerbliss closed 6 years ago
This patch works for me. Inspired from (https://bugs.python.org/file16863/io-openpty.patch). Is something like this acceptable ?
--- a/master.c
+++ b/master.c
@@ -253,8 +253,12 @@ pty_activity(int s)
len = read(the_pty.fd, buf, sizeof(buf));
/* Error -> die */
- if (len <= 0)
- exit(1);
+ if (len <= 0) {
+ if (len == -1 && errno == EIO)
+ exit(0);
+ else
+ exit(1);
+ }
Here is an expanded version of the patch which tries to save the exit code. See if it works for you:
--- a/dtach.h
+++ b/dtach.h
@@ -71,6 +71,7 @@
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include <sys/wait.h>
#ifndef S_ISREG
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
--- a/master.c
+++ b/master.c
@@ -28,6 +28,8 @@ struct pty
#endif
/* Process id of the child. */
pid_t pid;
+ /* Exit code of the child. */
+ int exit_code;
/* The terminal parameters of the pty. Old and new for comparision
** purposes. */
struct termios term;
@@ -72,6 +74,14 @@ die(int sig)
/* Well, the child died. */
if (sig == SIGCHLD)
{
+ int status;
+
+ if (waitpid(-1, &status, WNOHANG) > 0)
+ {
+ if (WIFEXITED(status))
+ the_pty.exit_code = WEXITSTATUS(status);
+ }
+
#ifdef BROKEN_MASTER
/* Damn you Solaris! */
close(the_pty.fd);
@@ -134,7 +144,7 @@ init_pty(char **argv, int statusfd)
printf("%s: could not execute %s: %s\r\n", progname,
*argv, strerror(errno));
fflush(stdout);
- _exit(127);
+ _exit(1);
}
/* Parent.. Finish up and return */
#ifdef BROKEN_MASTER
@@ -254,7 +264,17 @@ pty_activity(int s)
/* Error -> die */
if (len <= 0)
- exit(1);
+ {
+#ifdef EIO
+ if (len < 0 && errno == EIO)
+ len = 0;
+#endif
+
+ if (len == 0)
+ exit(the_pty.exit_code);
+ else
+ exit(1);
+ }
#ifdef BROKEN_MASTER
/* Get the current terminal settings. */
Any updates on this issue? Results in failure in systemd units when attempting to stop the service
I never received a reply from @hummerbliss saying whether my expanded version of the patch worked for them or not.
Maybe you could try it and see if there are any issues with it?
@crigler I tried it.
patched version: ~/resources/dtach/dtach
current version: /usr/bin/dtach
.
~
❯ ~/resources/dtach/dtach -N /tmp/a1 echo "ASD" && echo "success" || echo "failed"
success
~
❯ /usr/bin/dtach -N /tmp/a1 echo "ASD" && echo "success" || echo "failed"
failed
Also tried with a complex example with rtorrent. It works.
Also the OP's example works.
~
❯ strace -s 8192 -ff ~/resources/dtach/dtach -n /tmp/f /bin/sh -c "sleep 1" |& grep 'exited with'
[pid 12626] +++ exited with 0 +++
[pid 12628] +++ exited with 0 +++
+++ exited with 0 +++
~
❯ strace -s 8192 -ff /usr/bin/dtach -n /tmp/f /bin/sh -c "sleep 1" |& grep 'exited with'
[pid 12641] +++ exited with 0 +++
[pid 12643] +++ exited with 0 +++
+++ exited with 1 +++
However, I would like to ask does this have any bearing on what the executed command returns? Actually I checked with top after I did kill -9 <toppid>
The patched version outputs:
❯ ~/resources/dtach/dtach -N /tmp/a1 top
[1] 12274 killed ~/resources/dtach/dtach -N /tmp/a1 top
~ 7s
❯ echo $?
137
The same by the nonpatch version.
So I am assuming dtach transmits the executed commands error code.
Apologies for missing the updates. Works well for me.
When ever dtach exits because the command started by dtach finishes it always seems to exit with -1 when started in dtach -n mode.
For example,
strace -s 8192 -ff ./dtach -n /tmp/f /bin/sh -c "sleep 1"
Produces the following snipped output,