Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/nodejs/src/spawn_sync.h
1 // Copyright Joyent, Inc. and other Node contributors. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a 4 // copy of this software and associated documentation files (the 5 // "Software"), to deal in the Software without restriction, including 6 // without limitation the rights to use, copy, modify, merge, publish, 7 // distribute, sublicense, and/or sell copies of the Software, and to permit 8 // persons to whom the Software is furnished to do so, subject to the 9 // following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included 12 // in all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 // USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22 #ifndef SRC_SPAWN_SYNC_H_ 23 #define SRC_SPAWN_SYNC_H_ 24 25 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 26 27 #include "node_buffer.h" 28 #include "uv.h" 29 #include "v8.h" 30 31 namespace node { 32 33 class ExternalReferenceRegistry; 34 class SyncProcessOutputBuffer; 35 class SyncProcessStdioPipe; 36 class SyncProcessRunner; 37 38 39 class SyncProcessOutputBuffer { 40 static const unsigned int kBufferSize = 65536; 41 42 public: 43 inline SyncProcessOutputBuffer() = default; 44 45 inline void OnAlloc(size_t suggested_size, uv_buf_t* buf) const; 46 inline void OnRead(const uv_buf_t* buf, size_t nread); 47 48 inline size_t Copy(char* dest) const; 49 50 inline unsigned int available() const; 51 inline unsigned int used() const; 52 53 inline SyncProcessOutputBuffer* next() const; 54 inline void set_next(SyncProcessOutputBuffer* next); 55 56 private: 57 // Use unsigned int because that's what `uv_buf_init` takes. 58 mutable char data_[kBufferSize]; 59 unsigned int used_ = 0; 60 61 SyncProcessOutputBuffer* next_ = nullptr; 62 }; 63 64 65 class SyncProcessStdioPipe { 66 enum Lifecycle { 67 kUninitialized = 0, 68 kInitialized, 69 kStarted, 70 kClosing, 71 kClosed 72 }; 73 74 public: 75 SyncProcessStdioPipe(SyncProcessRunner* process_handler, 76 bool readable, 77 bool writable, 78 uv_buf_t input_buffer); 79 ~SyncProcessStdioPipe(); 80 81 int Initialize(uv_loop_t* loop); 82 int Start(); 83 void Close(); 84 85 v8::MaybeLocal<v8::Object> GetOutputAsBuffer(Environment* env) const; 86 87 inline bool readable() const; 88 inline bool writable() const; 89 inline uv_stdio_flags uv_flags() const; 90 91 inline uv_pipe_t* uv_pipe() const; 92 inline uv_stream_t* uv_stream() const; 93 inline uv_handle_t* uv_handle() const; 94 95 private: 96 inline size_t OutputLength() const; 97 inline void CopyOutput(char* dest) const; 98 99 inline void OnAlloc(size_t suggested_size, uv_buf_t* buf); 100 inline void OnRead(const uv_buf_t* buf, ssize_t nread); 101 inline void OnWriteDone(int result); 102 inline void OnShutdownDone(int result); 103 inline void OnClose(); 104 105 inline void SetError(int error); 106 107 static void AllocCallback(uv_handle_t* handle, 108 size_t suggested_size, 109 uv_buf_t* buf); 110 static void ReadCallback(uv_stream_t* stream, 111 ssize_t nread, 112 const uv_buf_t* buf); 113 static void WriteCallback(uv_write_t* req, int result); 114 static void ShutdownCallback(uv_shutdown_t* req, int result); 115 static void CloseCallback(uv_handle_t* handle); 116 117 SyncProcessRunner* process_handler_; 118 119 bool readable_; 120 bool writable_; 121 uv_buf_t input_buffer_; 122 123 SyncProcessOutputBuffer* first_output_buffer_; 124 SyncProcessOutputBuffer* last_output_buffer_; 125 126 mutable uv_pipe_t uv_pipe_; 127 uv_write_t write_req_; 128 uv_shutdown_t shutdown_req_; 129 130 Lifecycle lifecycle_; 131 }; 132 133 134 class SyncProcessRunner { 135 enum Lifecycle { 136 kUninitialized = 0, 137 kInitialized, 138 kHandlesClosed 139 }; 140 141 public: 142 static void RegisterExternalReferences(ExternalReferenceRegistry* registry); 143 static void Initialize(v8::Local<v8::Object> target, 144 v8::Local<v8::Value> unused, 145 v8::Local<v8::Context> context, 146 void* priv); 147 static void Spawn(const v8::FunctionCallbackInfo<v8::Value>& args); 148 149 private: 150 friend class SyncProcessStdioPipe; 151 152 explicit SyncProcessRunner(Environment* env_); 153 ~SyncProcessRunner(); 154 155 inline Environment* env() const; 156 157 v8::MaybeLocal<v8::Object> Run(v8::Local<v8::Value> options); 158 v8::Maybe<void> TryInitializeAndRunLoop(v8::Local<v8::Value> options); 159 void CloseHandlesAndDeleteLoop(); 160 161 void CloseStdioPipes(); 162 void CloseKillTimer(); 163 164 void Kill(); 165 void IncrementBufferSizeAndCheckOverflow(ssize_t length); 166 167 void OnExit(int64_t exit_status, int term_signal); 168 void OnKillTimerTimeout(); 169 170 int GetError(); 171 void SetError(int error); 172 void SetPipeError(int pipe_error); 173 174 v8::MaybeLocal<v8::Object> BuildResultObject(); 175 v8::MaybeLocal<v8::Array> BuildOutputArray(); 176 177 v8::Maybe<int> ParseOptions(v8::Local<v8::Value> js_value); 178 v8::Maybe<int> ParseStdioOptions(v8::Local<v8::Value> js_value); 179 v8::Maybe<int> ParseStdioOption(int child_fd, 180 v8::Local<v8::Object> js_stdio_option); 181 182 inline int AddStdioIgnore(uint32_t child_fd); 183 inline int AddStdioPipe(uint32_t child_fd, 184 bool readable, 185 bool writable, 186 uv_buf_t input_buffer); 187 inline int AddStdioInheritFD(uint32_t child_fd, int inherit_fd); 188 189 static bool IsSet(v8::Local<v8::Value> value); 190 v8::Maybe<int> CopyJsString(v8::Local<v8::Value> js_value, 191 const char** target); 192 v8::Maybe<int> CopyJsStringArray(v8::Local<v8::Value> js_value, 193 char** target); 194 195 static void ExitCallback(uv_process_t* handle, 196 int64_t exit_status, 197 int term_signal); 198 static void KillTimerCallback(uv_timer_t* handle); 199 static void KillTimerCloseCallback(uv_handle_t* handle); 200 201 double max_buffer_; 202 uint64_t timeout_; 203 int kill_signal_; 204 205 uv_loop_t* uv_loop_; 206 207 uint32_t stdio_count_; 208 std::vector<uv_stdio_container_t> uv_stdio_containers_; 209 std::vector<std::unique_ptr<SyncProcessStdioPipe>> stdio_pipes_; 210 bool stdio_pipes_initialized_; 211 212 uv_process_options_t uv_process_options_; 213 std::unique_ptr<const char[]> file_buffer_; 214 std::unique_ptr<char[]> args_buffer_; 215 std::unique_ptr<char[]> env_buffer_; 216 std::unique_ptr<const char[]> cwd_buffer_; 217 218 uv_process_t uv_process_; 219 bool killed_; 220 221 size_t buffered_output_size_; 222 int64_t exit_status_; 223 int term_signal_; 224 225 uv_timer_t uv_timer_; 226 bool kill_timer_initialized_; 227 228 // Errors that happen in one of the pipe handlers are stored in the 229 // `pipe_error` field. They are treated as "low-priority", only to be 230 // reported if no more serious errors happened. 231 int error_; 232 int pipe_error_; 233 234 Lifecycle lifecycle_; 235 236 Environment* env_; 237 }; 238 239 } // namespace node 240 241 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 242 243 #endif // SRC_SPAWN_SYNC_H_