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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
use crate::;
use Vec;
use ;
use CStr;
use ;
/// Spawns a new server process and sets up pipes.
///
/// This function creates two pairs of pipes for communication between the parent and child processes.
/// It then spawns a new process using the specified index and source, passing the provided arguments
/// to the new process. The function returns the read and write file descriptors for the parent process
/// to communicate with the child process.
///
/// # Arguments
///
/// * `index` - The index of the cell to spawn.
/// * `source` - The source of the cell (e.g., `Source::CellDep`).
/// * `argv` - A slice of C strings representing the arguments to pass to the new process.
///
/// # Returns
///
/// A `Result` containing a tuple of two `Pipe` representing the read and write file descriptors
/// for the parent process, or an `IpcError` if an error occurs.
///
/// # Errors
///
/// This function returns an `IpcError` if any of the following syscalls fail:
/// * `pipe` - If creating a pipe fails.
/// * `spawn` - If spawning the new process fails.
///
/// # Example
///
/// ```rust,ignore
/// use ckb_script_ipc_common::spawn::spawn_server;
///
/// let (read_pipe, write_pipe) = spawn_server(
/// 0,
/// Source::CellDep,
/// &[CString::new("demo").unwrap().as_ref()],
/// ).expect("Failed to spawn server");
/// ```
/// Spawns a new server process using the provided code hash and hash type. This function is similar
/// to `spawn_server`, but it uses a specific cell identified by the `code_hash` and `hash_type` to
/// spawn the new process. The function returns the read and write file descriptors for the parent
/// process to communicate with the child process.
///
/// # Arguments
///
/// * `code_hash` - A byte slice representing the code hash of the cell to spawn.
/// * `hash_type` - The hash type of the cell (e.g., `ScriptHashType::Type`).
/// * `argv` - A slice of C strings representing the arguments to pass to the new process.
///
/// # Returns
///
/// A `Result` containing a tuple of two `Pipe` representing the read and write file descriptors
/// for the parent process, or an `IpcError` if an error occurs.
///
/// # Errors
///
/// This function returns an `IpcError` if any of the following syscalls fail:
/// * `pipe` - If creating a pipe fails.
/// * `spawn_cell` - If spawning the new process using the cell fails.
///
/// # Example
///
/// ```rust,ignore
/// use ckb_script_ipc_common::spawn::spawn_cell_server;
///
/// let (read_pipe, write_pipe) = spawn_cell_server(
/// code_hash,
/// hash_type,
/// &[CString::new("demo").unwrap().as_ref()],
/// ).expect("Failed to spawn cell server");
/// ```
/// Runs the server with the provided service implementation. This function listens for incoming
/// requests, processes them using the provided service, and sends back the responses. It uses
/// the inherited file descriptors for communication.
///
/// # Arguments
///
/// * `serve` - A mutable reference to the service implementation that handles the requests and
/// generates the responses. The service must implement the `Serve` trait with the appropriate
/// request and response types.
///
/// # Type Parameters
///
/// * `Req` - The type of the request messages. It must implement `Serialize` and `Deserialize`.
/// * `Resp` - The type of the response messages. It must implement `Serialize` and `Deserialize`.
/// * `S` - The type of the service implementation. It must implement the `Serve` trait with
/// `Req` as the request type and `Resp` as the response type.
///
/// # Returns
///
/// A `Result` indicating the success or failure of the server execution. If the server runs
/// successfully, it never returns. If an error occurs, it returns an `IpcError`.
///
/// # Errors
///
/// This function returns an `IpcError` if any of the following conditions occur:
/// * The inherited file descriptors are not exactly two.
/// * An error occurs during the execution of the channel.