1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef PROCESS_JS_CHILDPROCESS_H
17#define PROCESS_JS_CHILDPROCESS_H
18
19#include <string>
20#include <sys/types.h>
21
22#include "napi/native_api.h"
23#include "napi/native_node_api.h"
24namespace OHOS::JsSysModule::Process {
25    struct WaitInfo {
26        napi_async_work worker {nullptr};
27        napi_deferred deferred {nullptr};
28        int status {0};
29    };
30
31    struct StdInfo {
32        napi_async_work worker {nullptr};
33        napi_deferred deferred {nullptr};
34        napi_value promise {nullptr};
35        std::string stdData {};
36        bool *isNeedRun {nullptr};
37        int64_t maxBuffSize {};
38        int fd {};
39        int pid {};
40    };
41
42    struct OptionsInfo {
43        napi_async_work worker {nullptr};
44        bool *isNeedRun {nullptr};
45        int32_t timeout {};
46        int32_t killSignal {};
47        int64_t maxBuffer {};
48        pid_t pid {};
49    };
50
51    class ChildProcess {
52    public:
53        /**
54         * Create child process object.
55         */
56        explicit ChildProcess() {}
57
58        /**
59         * Close the target process.
60         */
61        void Close();
62
63        /**
64         * Send a signal to process.
65         *
66         * @param env NAPI environment parameters.
67         * @param signal Number or string represents the signal sent.
68         */
69        void Kill(napi_env env, const napi_value signo);
70
71        /**
72         * Wait for the child process to finish running, and return a promise object
73         * whose value is the exit code of the child process.
74         *
75         * @param env NAPI environment parameters.
76         */
77        napi_value Wait(napi_env env);
78
79        /**
80         * Get the standard output of the child process.
81         *
82         * @param env NAPI environment parameters.
83         */
84        napi_value GetOutput(napi_env env) const;
85
86        /**
87         * Get the standard error output of the child process.
88         *
89         * @param env NAPI environment parameters.
90         */
91        napi_value GetErrorOutput(napi_env env) const;
92
93        /**
94         * Get kill status.
95         *
96         * @param env NAPI environment parameters.
97         */
98        napi_value GetKilled(napi_env env) const;
99
100        /**
101         * Get the specific pid value.
102         *
103         * @param env NAPI environment parameters.
104         */
105        napi_value Getpid(napi_env env) const;
106
107        /**
108         * Get the parent process ID.
109         *
110         * @param env NAPI environment parameters.
111         */
112        napi_value Getppid(napi_env env) const;
113
114        /**
115         * Get exit status.
116         *
117         * @param env NAPI environment parameters.
118         */
119        napi_value GetExitCode(napi_env env) const;
120
121        /**
122         * Initialization option information.
123         *
124         * @param env NAPI environment parameters.
125         * @param options Option parameter.
126         */
127        void InitOptionsInfo(napi_env env, napi_value options);
128
129        /**
130         * Start a subprocess to execute shell commands.
131         *
132         * @param env NAPI environment parameters.
133         * @param command Command parameters.
134         */
135        void Spawn(napi_env env, napi_value command);
136
137        /**
138         * ChildProcess destructor.
139         */
140        virtual ~ChildProcess();
141
142    private:
143        static void ReadStdOut(napi_env env, void* data);
144        static void EndStdOut(napi_env env, napi_status status, void* buffer);
145        static void ReadStdErr(napi_env env, void* data);
146        static void EndStdErr(napi_env env, napi_status status, void* buffer);
147        static void TimeoutListener(napi_env env, void* data);
148        std::string RequireStrValue(napi_env env, const napi_value strValue);
149        int GetValidSignal(napi_env env, const napi_value signo);
150        void CreateWorker(napi_env env);
151
152        OptionsInfo* optionsInfo_ {nullptr};
153        StdInfo* stdOutInfo_ {nullptr};
154        StdInfo* stdErrInfo_ {nullptr};
155
156        int exitCode_ {};
157        int stdOutFd_[2] {};
158        int stdErrFd_[2] {};
159        int ppid_ {};
160
161        bool isNeedRun_ {true};
162        bool killed_ {};
163        bool isWait_ {true};
164    };
165} // namespace OHOS::JsSysModule::Process
166#endif // PROCESS_JS_CHILDPROCESS_H
167