1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use std::mem;

/// Exit status of a process.

#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum ExitStatus {
    /// The process exited with the specified exit code.
    ///
    /// Note that the exit code is limited to a much smaller range on
    /// most platforms.
    Exited(u32),

    /// The process exited due to a signal with the specified number.
    ///
    /// This variant is never created on Windows, where signals of
    /// Unix kind do not exist.
    Signaled(u8),

    /// The process exit status cannot be described by the preceding
    /// two variants.
    ///
    /// This should not occur in normal operation.
    Other(i32),

    /// It is known that the process has completed, but its exit
    /// status is unavailable.
    ///
    /// This should not occur in normal operation, but if possible if
    /// for example some foreign code calls `waitpid()` on the PID of
    /// the child process.
    Undetermined,
}

impl ExitStatus {
    /// True if the exit status is of the process is 0.
    pub fn success(&self) -> bool {
        if let &ExitStatus::Exited(0) = self {
            true
        } else {
            false
        }
    }
}

#[derive(Debug, Copy, Clone)]
#[allow(dead_code)]
pub enum StandardStream {
    Input,
    Output,
    Error,
}

// Undropped: don't drop an object after going out of scope.  This is
// used for Files made from standard descriptors.  For example:
//
// let unowned_stdin = unsafe { Undropped::new(File::from_raw_fd(0)) };
//
// This allows the use of &File corresponding to standard input
// without closing fd 0 when unowned_stdin goes out of scope.  Using
// this class is inherently dangerous, but it is useful to represent
// the system streams returned by get_standard_stream.

#[derive(Debug)]
pub struct Undropped<T>(Option<T>);

impl<T> Undropped<T> {
    pub unsafe fn new(o: T) -> Undropped<T> {
        Undropped(Some(o))
    }

    pub fn get_ref(&self) -> &T {
        self.0.as_ref().unwrap()
    }
}

impl<T> Drop for Undropped<T> {
    fn drop(&mut self) {
        let o = self.0.take().unwrap();
        mem::forget(o);
    }
}