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

Implement a way to daemonize a process #15641

Closed
gsingh93 opened this issue Jul 13, 2014 · 15 comments
Closed

Implement a way to daemonize a process #15641

gsingh93 opened this issue Jul 13, 2014 · 15 comments

Comments

@gsingh93
Copy link
Contributor

Being able to daemonize is a common thing for applications to do. There should be something in Rust similar to the C daemon function: http://man7.org/linux/man-pages/man3/daemon.3.html

@alexcrichton
Copy link
Member

Could you elaborate a little more on what you'd like here? It looks like the C daemon function can be built on top of what we already provide today, and we also have some additional facilities with Process and Command

@gsingh93
Copy link
Contributor Author

Hey Alex, I asked on the mailing list and IRC on how to do this, and I didn't get any responses, so I assumed it wasn't possible. Can you explain how I can achieve the same functionality as the C daemon function in Rust?

@alexcrichton
Copy link
Member

You'll want to spawn a new process with the detached option set to true, like so:

use std::io::Command;
use std::os;

fn main() {
    let args = os::args();
    if args.len() == 1 {
        let child = Command::new(args.get(0).as_slice())
                            .arg("child")
                            .detached().spawn().unwrap();
        println!("child: {}", child.id());
        child.forget();
    } else {
        println!("I'm a daemon!");
    }
}

This is all possible today, so I'm going to close this issue.

@gsingh93
Copy link
Contributor Author

So if I understand correctly, if I run this code with no arguments, I should see the process ID of the daemon and the daemon should print "I'm a daemon"? Because I only see the child process ID printed.

@alexcrichton
Copy link
Member

I believe that is because the child has been detached so it did not inherit the same stdio file descriptors.

@gsingh93
Copy link
Contributor Author

I also added a 60 second sleep call after the "I'm a daemon!" println and ran pgrep and ps -p with the child process ID. It doesn't seem like the daemon is running.

@alexcrichton
Copy link
Member

Ah, that's because the stdout handle is closed so the call to println! is failing the rust task (discoverable through strace)

@blark
Copy link

blark commented Jan 17, 2017

Since std::io::Command is now defunct would someone be able to post a working example using std::process similar to the one that @alexcrichton posted above?

@somedude232
Copy link

somedude232 commented Jun 29, 2017

use std::process::Command;
use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() == 2 {
        if &args[1] == "start" {
                let child = Command::new(&args[0])
                                    .spawn().expect("Child process failed to start.");
                println!("child pid: {}", child.id());
                // child.forget() No Child Left Behind
        }
    } else {
        println!("This is an incredibly simple daemon!");
    }
}

This works for me.

@acrossoffwest
Copy link

@somedude232 thanks

@Ofenhed
Copy link

Ofenhed commented Jan 15, 2020

The code above is not an acceptable solution, it's a backdoor. If anyone has copied the code above into a suid program, privilege escalation is trivial, since the args array is set by the calling process and args[0] cannot be trusted. Even if that wasn't true, a race condition would still exist since the path args[0] names could be replaced before the Command is executed.

@alanyee
Copy link

alanyee commented Feb 16, 2020

@Ofenhed do you have a safer alternative?

@Ofenhed
Copy link

Ofenhed commented Feb 16, 2020

The correct way would be to demonize the actual running process. I haven't tried it, but running the unsafe libc functions fork (and killing the parent) and setsid may do the trick.

To slightly increase security with the examples above on systems with /proc available, args[0] could be replaced with "/proc/self/exe".

@Ofenhed
Copy link

Ofenhed commented Oct 6, 2020

@alexcrichton Could we possibly reopen this thread (as it is not solved) or at least remove the backdoors as recommended solutions?

bors added a commit to rust-lang-ci/rust that referenced this issue Nov 13, 2023
…eykril

fix: preceding QualifiedPathType for into_to_from assist

fixes rust-lang#15598
@qq253498229
Copy link

How should I redirect stdout and stderr in this way?

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

No branches or pull requests

8 participants