Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run process detached from its parent on Linux #42

Merged
merged 3 commits into from
Sep 14, 2017

Conversation

GAumala
Copy link
Contributor

@GAumala GAumala commented Mar 5, 2017

Add option 'detached' to allow the opened app to continue running after the
parent process exits.

in Linux and MacOS if this option is true, the child process stdio is
set to 'ignore'.


The reason for this change is that I use opn to open a browser, but I don't want the browser to get closed when the node.js process exits, which is what currently happens, even if I set wait to false. The code is a bit messy because this option seems to conflic with wait. According to the docs, to spawn a child process so that it can continue after parent exits 2 options are needed:

  • set option detached true.
  • set option stdio to 'ignore'.

it might be better add stdio option as well instead of just asuming that detached true implies the value of stdio.

@kevva
Copy link

kevva commented Jul 23, 2017

What OS are you on? This option seems to do exactly what we want wait to do, so it's better if we can fix that one instead.

@GAumala
Copy link
Contributor Author

GAumala commented Sep 13, 2017

I'm on Linux. I don't really understand how wait should do the same thing. README only says that it controls the moment in which the promise is fulfilled, but it doesn't say anything about what options are set to the spawned process.

I do recognize that this solution is probably not optimal since increasing the number of options adds up complexity. Do you think that wait should also modify detached and stdio in the spawned process?

@kevva
Copy link

kevva commented Sep 13, 2017

Well, you're doing exactly the same thing, except that you're waiting for the process to exit before resolving the Promise. I don't have a Linux system available so I'm afraid I can't debug it further though.

@GAumala
Copy link
Contributor Author

GAumala commented Sep 14, 2017

Thanks for the quick reply. I think I finally understood what you meant. I have now changed the code so that when wait is false it sets stdio to 'ignore' and detached to true on all platforms. No extra options added.

The node.js docs show this example for detaching child processes in order to let them run after the parent exits:

const { spawn } = require('child_process');

const subprocess = spawn(process.argv[0], ['child_program.js'], {
  detached: true,
  stdio: 'ignore'
});

subprocess.unref();

This is what I want opn to do when wait is false.

I do believe that this issue occurs on all platforms but I'd like to be proven wrong so here's a test plan.

Consider the following script:

const opn = require('opn')

opn('https://fsf.org', { app: 'google-chrome-stable', wait: false}).then(() => {
  console.log('promise fulfilled')
})

while(true);

It just opens Google Chrome and with wait set to false and then gets stuck in an infinite loop. Before you run this make sure that the browser is not already running, we need the script to actually start the browser process not just open a new tab.

After the page loads, terminate the script with Ctrl+C.

What should happen is that the script exits, but the browser keeps running.
What actually happens in any recent version of opn is that both the script and the browser exit.

Why? Because node forwards the interrupt signal to the child process. The only way to avoid it to detach the child process from its parent.

@kevva
Copy link

kevva commented Sep 14, 2017

I can't reproduce this behaviour in macOS, even when using your snippet. When I exit the process the app stays open. Would be useful if someone else using Linux could chime in so we can verify your problem.

@evalexpr
Copy link

I can confirm using macOS Sierra does not cause this to occur. However, using Arch Linux I can replicate the behaviour described by @GAumala

@kevva
Copy link

kevva commented Sep 14, 2017

@W1lkins, thanks for testing. @GAumala, could you just move the detached option into https://github.com/sindresorhus/opn/blob/master/index.js#L63 and I think this will be good to go.

On platforms that use xdg-open, if waiting option is false set stdio to 'ignore'
and detached to true so that the xdg-open process is completely detached from
the parent and it is able to continue running after the parent exits.
@GAumala
Copy link
Contributor Author

GAumala commented Sep 14, 2017

Yes it seems I've been looking at this at the wrong level. Probably the bug is related to xdg-open and it needs to be detached so that the app can continue to run after the node process exits. I have now changed my code to only apply this change on platforms that use xdg-open. Thanks for helping guys!

@kevva kevva changed the title Add 'detached' option Run process detached from its parent on Linux Sep 14, 2017
@kevva kevva merged commit b9f7e56 into sindresorhus:master Sep 14, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants