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

Refactor core::run to remove the ProgRepr struct... #6044

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 50 additions & 67 deletions src/libcore/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,48 @@ pub struct RunProgramResult {
handle: *(),
}

struct ProgRepr {
pid: pid_t,
handle: *(),
in_fd: c_int,
out_file: *libc::FILE,
err_file: *libc::FILE,
finished: bool,
/// A value representing a child process
pub struct Program {
priv pid: pid_t,
priv handle: *(),
priv in_fd: c_int,
priv out_file: *libc::FILE,
priv err_file: *libc::FILE,
priv finished: bool,
}

impl Drop for Program {
fn finalize(&self) {
// FIXME #4943: transmute is bad.
let mut_self: &mut Program = unsafe { cast::transmute(self) };

mut_self.finish();
mut_self.close_outputs();
free_handle(self.handle);
}
}

impl ProgRepr {
pub impl Program {

/// Returns the process id of the program
fn get_id(&mut self) -> pid_t { self.pid }

/// Returns an io::Writer that can be used to write to stdin
fn input(&mut self) -> @io::Writer {
io::fd_writer(self.in_fd, false)
}

/// Returns an io::Reader that can be used to read from stdout
fn output(&mut self) -> @io::Reader {
io::FILE_reader(self.out_file, false)
}

/// Returns an io::Reader that can be used to read from stderr
fn err(&mut self) -> @io::Reader {
io::FILE_reader(self.err_file, false)
}

/// Closes the handle to the child processes standard input
fn close_input(&mut self) {
let invalid_fd = -1i32;
if self.in_fd != invalid_fd {
Expand All @@ -67,21 +99,25 @@ impl ProgRepr {
}
}

fn close_outputs(&mut self) {
priv fn close_outputs(&mut self) {
unsafe {
fclose_and_null(&mut self.out_file);
fclose_and_null(&mut self.err_file);
}
}

/**
* Waits for the child process to terminate. Closes the handle
* to stdin if necessary.
*/
fn finish(&mut self) -> int {
if self.finished { return 0; }
self.finished = true;
self.close_input();
return waitpid(self.pid);
}

fn destroy(&mut self, force: bool) {
priv fn destroy_internal(&mut self, force: bool) {
killpid(self.pid, force);
self.finish();
self.close_outputs();
Expand All @@ -107,57 +143,6 @@ impl ProgRepr {
}
}
}
}

/// A value representing a child process
pub struct Program {
priv r: ProgRepr,
}

impl Drop for Program {
fn finalize(&self) {
// FIXME #4943: transmute is bad.
let selfr: &mut ProgRepr = unsafe { cast::transmute(&self.r) };

selfr.finish();
selfr.close_outputs();
free_handle(self.r.handle);
}
}

pub impl Program {
priv fn new(r: ProgRepr) -> Program {
Program {
r: r
}
}

/// Returns the process id of the program
fn get_id(&mut self) -> pid_t { self.r.pid }

/// Returns an io::Writer that can be used to write to stdin
fn input(&mut self) -> @io::Writer {
io::fd_writer(self.r.in_fd, false)
}

/// Returns an io::Reader that can be used to read from stdout
fn output(&mut self) -> @io::Reader {
io::FILE_reader(self.r.out_file, false)
}

/// Returns an io::Reader that can be used to read from stderr
fn err(&mut self) -> @io::Reader {
io::FILE_reader(self.r.err_file, false)
}

/// Closes the handle to the child processes standard input
fn close_input(&mut self) { self.r.close_input(); }

/**
* Waits for the child process to terminate. Closes the handle
* to stdin if necessary.
*/
fn finish(&mut self) -> int { self.r.finish() }

/**
* Terminate the program, giving it a chance to clean itself up if
Expand All @@ -166,7 +151,7 @@ pub impl Program {
* On Posix OSs SIGTERM will be sent to the process. On Win32
* TerminateProcess(..) will be called.
*/
fn destroy(&mut self) { self.r.destroy(false); }
fn destroy(&mut self) { self.destroy_internal(false); }

/**
* Terminate the program as soon as possible without giving it a
Expand All @@ -175,7 +160,7 @@ pub impl Program {
* On Posix OSs SIGKILL will be sent to the process. On Win32
* TerminateProcess(..) will be called.
*/
fn force_destroy(&mut self) { self.r.destroy(true); }
fn force_destroy(&mut self) { self.destroy_internal(true); }
}


Expand Down Expand Up @@ -366,16 +351,14 @@ pub fn start_program(prog: &str, args: &[~str]) -> Program {
libc::close(pipe_err.out);
}

let repr = ProgRepr {
Program {
pid: res.pid,
handle: res.handle,
in_fd: pipe_input.out,
out_file: os::fdopen(pipe_output.in),
err_file: os::fdopen(pipe_err.in),
finished: false,
};

Program::new(repr)
}
}

fn read_all(rd: @io::Reader) -> ~str {
Expand Down