merge js_sys_module_master and mv to js_sys_module

Signed-off-by: lengchangjing <lengchangjing@huawei.com>
This commit is contained in:
lengchangjing 2022-07-20 15:34:19 +08:00
commit fde09f43c7
16 changed files with 3657 additions and 0 deletions

177
js_sys_module/LICENSE Normal file
View File

@ -0,0 +1,177 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

365
js_sys_module/README.md Executable file
View File

@ -0,0 +1,365 @@
# js_sys_module Subsystems/Components
- [Introduction](#Introduction)
- [Directory](#Directory)
- [Description](#Description)
- [Interface description](#Interface description)
- [Interface instructions](#Interface instructions)
- [Related warehouse](#Related warehouse])
## Introduction
Process is mainly used to obtain the relevant ID of the process, obtain and modify the working directory of the process, exit and close the process. The childprocess object can be used to create a new process. The main process can obtain the standard input and output of the child process, send signals and close the child process.
## Directory
```
base/compileruntime/js_sys_module/
├── Class:PROCESS # class of PROCESS
├── Uid # attribute of Uid
├── Gid # attribute of Gid
├── EUid # attribute of EUid
├── EGid # attribute of EGid
├── Groups # attribute of Groups
├── Pid # attribute of Pid
├── Ppid # attribute of Ppid
├── chdir() # method of chdir
├── uptime() # method of uptime
├── kill() # method of kill
├── abort() # method of abort
├── on() # method of on
├── tid # method of tid
├── getStartRealtime() # method of getStartRealtime
├── getAvailableCores() # method of getAvailableCores
├── getPastCputime() # method of getPastCputime
├── isIsolatedProcess() # method of isIsolatedProcess
├── is64Bit() # method of is64Bit
├── isAppUid() # method of isAppUid
├── getUidForName() # method of getUidForName
├── getThreadPriority() # method of getThreadPriority
├── getSystemConfig() # method of getSystemConfig
├── getEnvironmentVar() # method of getEnvironmentVar
├── exit() # method of exit
├── cwd() # method of cwd
├── off() # method of off
├── runCmd() # method of runCmd
└─── Class:CHILDPROCESS # class of CHILDPROCESS
├── close() # method of close
├── kill() # method of kill
├── getOutput() # method of getOutput
├── getErrorOutput() # method of getErrorOutput
├── wait() # method of wait
├── killed # attribute of killed
├── pid # attribute of pid
├── ppid # attribute of ppid
└── exitCode # attribute of exitCode
```
## Description
### Interface description
| Interface name | description |
| -------- | -------- |
| const uid :number | returns the digital user ID of the process. |
| const gid :number | returns the numeric group ID of the process. |
| const euid :number | returns the numeric valid user identity of the process. |
| const egid :number | returns the numeric valid group ID of the node.js process. |
| const groups :number[] | returns an array with supplementary group ID. |
| const pid :number | returns the PID of the process. |
| const ppid :number | returns the PID of the parent process of the current process. |
| chdir(dir:string) :void | change the current working directory of the node.js process. |
| uptime() :number | returns the number of seconds the current system has been running. |
| Kill(pid:number, signal:number) :boolean | send the signal to the identified process PID, and true means the sending is successful. |
| abort() :void | cause the node.js process to exit immediately and generate a core file. |
| on(type:string ,listener:EventListener) :void | used to store events triggered by users. |
| exit(code:number):void | cause the node.js process to exit immediately. |
| cwd():string | returns the current working directory of the node.js process. |
| off(type: string): boolean | clear the events stored by the user. True means the clearing is successful. |
| runCmd(command: string, options?: { timeout : number, killSignal : number \| string, maxBuffer : number }): ChildProcess |through runcmd, you can fork a new process to run a shell and return the childprocess object. The first parameter command refers to the shell to be run, and the second parameter options refers to some running parameters of the child process. These parameters mainly refer to timeout, killsignal and maxbuffer. If timeout is set, the child process will send a signal killsignal after timeout is exceeded. Maxbuffer is used to limit the maximum stdout and stderr sizes that can be received. |
| wait() Promise\<number> | is used to wait for the child process to run and return the promise object, whose value is the exit code of the child process. |
| getOutput(): Promise\<Uint8Array> | used to get the standard output of the child process. |
| getErrorOutput(): Promise\<Uint8Array> | used to get the standard error output of the child process. |
| const tid:number | Returns the TID of the process. |
| getStartRealtime() :number | Gets the real time elapsed (in milliseconds) from system startup to process startup. |
| getAvailableCores() :number[] | Gets the CPU kernel available to the current process on the multi-core device. |
| getPastCputime() :number | Gets the CPU time (in milliseconds) from the start of the process to the current time. |
| isIsolatedProcess(): boolean | Check if the process is quarantined. |
| is64Bit(): boolean | Check whether the process is running in a 64 bit environment. |
| isAppUid(v:number): boolean | Checks whether the specified uid belongs to a specific application. |
| getUidForName(v:string): number | Obtain the user group ID to which the user belongs according to the user name |
| getThreadPriority(v:number): number | Gets the thread priority based on the specified TID. |
| getSystemConfig(name:number): number | Gets the configuration of the system according to the specified system configuration name. |
| getEnvironmentVar(name:string): string | Obtain the corresponding value according to the name of the environment variable. |
| close(): void | used to close the running child process. |
| kill(signal: number \| string): void | used to send signals to child processes. |
| readonly killed: boolean | indicates whether the signal is sent successfully, and true indicates that the signal is sent successfully. |
| readonly exitCode: number | indicates the exit code of the child process. |
| readonly pid: number | represents the child process ID. |
| readonly ppid: number | represents the main process ID. |
### Interface instructions
Example of using interface
1.uid()
```
uid(){
var res = Process.uid;
}
```
2.gid()
```
gid(){
var result = Process.gid;
}
```
3.euid()
```
euid(){
var and = Process.euid;
}
```
4.egid()
```
egid(){
var resb = Process.egid;
}
```
5.groups()
```
groups(){
var answer = Process.groups;
}
```
6.pid()
```
pid(){
var result = Process.pid;
}
```
7.ppid()
```
ppid(){
var result = Process.ppid;
}
```
8.chdir()
```
chdir(){
Process.chdir("123456");
}
```
9.uptime()
```
uptime(){
var num = Process.uptime();
}
```
10.kill()
```
kill(){
var ansu = Process.kill(5,23);
}
```
11.abort()
```
abort(){
Process.abort();
}
```
12.on()
```
on(){
function add(num){
var value = num + 5;
return value;
}
Process.on("add",add);
}
```
13.exit()
```
exit(){
Process.exit(15);
}
```
14.Cwd()
```
Cwd(){
var result = Process.cwd();
}
```
15.off()
```
off(){
var result = Process.off("add");
}
```
16.runCmd()
```
runCmd(){
var child = process.runCmd('echo abc')
// killSignal can be a number or a string
var child = process.runCmd('echo abc;', {killSignal : 'SIGKILL'});
var child = process.runCmd('sleep 5; echo abc;', {timeout : 1, killSignal : 9, maxBuffer : 2})
}
```
17.wait()
```
wait()
{
var child = process.runCmd('ls')
var status = child.wait();
status.then(val => {
console.log(val);
})
}
```
18.getOutput()
```
getOutput(){
var child = process.runCmd('echo bcd;');
var res = child.getOutput();
child.wait();
res.then(val => {
console.log(val);
})
}
```
19.getErrorOutput()
```
getErrorOutput(){
var child = process.runCmd('makdir 1.txt'); // execute an error command
var res = child.getErrorOutput();
child.wait();
res.then(val => {
console.log(val);
})
}
```
20.close()
```
close(){
var child = process.runCmd('ls; sleep 5s;')
var result = child.close()
}
```
21.kill()
```
kill(){
var child = process.runCmd('ls; sleep 5s;')
var result = child.kill('SIGHUP');
child.wait();
var temp = child.killed;
}
```
22.killed
```
{
var child = process.runCmd('ls; sleep 5;')
child.kill(3);
var killed_ = child.killed;
child.wait();
}
```
23.exitCode
```
{
var child = process.runCmd('ls; sleep 5;')
child.kill(9);
child.wait();
var exitCode_ = child.exitCode;
}
```
24.pid
```
pid
{
var child = process.runCmd('ls; sleep 5;')
var pid_ = child.pid;
child.wait();
}
```
25.ppid
```
ppid
{
var child = process.runCmd('ls; sleep 5;')
var ppid_ = child.ppid;
child.wait();
}
```
26.tid
```
tid(){
var ansu = Process.tid;
}
```
27.isIsolatedProcess()
```
isIsolatedProcess(){
var ansu = Process.isIsolatedProcess()();
}
```
28.isAppUid()
```
isAppUid(){
var ansu = Process.isAppUid(10000);
}
```
29.is64Bit()
```
is64Bit(){
var ansu = Process.is64Bit();
}
```
30.getUidForName()
```
getUidForName(){
var buf = "root";
var ansu = Process.getUidForName(buf);
}
```
31.getEnvironmentVar()
```
getEnvironmentVar(){
var ansu = Process.getEnvironmentVar('USER');
}
```
32.getAvailableCores()
```
getAvailableCores(){
var ansu = Process.getAvailableCores();
}
```
33.getThreadPriority()
```
getThreadPriority(){
var result = Process.getTid();
var ansu = getThreadPriority(result);
}
```
34.getStartRealtime()
```
getStartRealtime(){
var ansu = Process.getStartRealtime();
}
```
35.getPastCputime()
```
getPastCputime(){
var ansu = Process.getPastCputime();
}
```
36.getSystemConfig()
```
getSystemConfig(){
var _SC_ARG_MAX = 0;
var ansu = Process.getSystemConfig(_SC_ARG_MAX)
}
```
## Related warehouse
[js_sys_module](base/compileruntime/js_sys_module/readme.md)
### License
SYS is available under [Mozilla license](https://www.mozilla.org/en-US/MPL/), and the documentation is detailed in [documentation](https://gitee.com/openharmony/js_sys_module/blob/master/mozilla_docs.txt). See [LICENSE](https://gitee.com/openharmony/js_sys_module/blob/master/LICENSE) for the full license text.

366
js_sys_module/README_zh.md Executable file
View File

@ -0,0 +1,366 @@
# js_sys_module子系统/组件
- [简介](#简介)
- [目录](#目录)
- [说明](#说明)
- [接口说明](#接口说明)
- [使用说明](#使用说明)
- [相关仓](#相关仓])
## 简介
进程主要用于获取进程的相关ID获取和修改进程的工作目录退出和关闭进程。 childprocess 对象可用于创建新进程。 主进程可以获取子进程的标准输入输出,发送信号,关闭子进程。
## 目录
```
base/compileruntime/js_sys_module/
├── Class:PROCESS # PROCESS类
├── Uid # Uid属性
├── Gid # Gid属性
├── EUid # EUid属性
├── EGid # EGid属性
├── Groups # Groups属性
├── Pid # Pid属性
├── Ppid # Ppid属性
├── chdir() # chdir方法
├── uptime() # uptime方法
├── kill() # kill方法
├── abort() # abort方法
├── on() # on方法
├── tid # tid方法
├── getStartRealtime() # getStartRealtime方法
├── getAvailableCores() # getAvailableCores方法
├── getPastCputime() # getPastCputime方法
├── isIsolatedProcess() # isIsolatedProcess方法
├── is64Bit() # is64Bit方法
├── isAppUid() # isAppUid方法
├── getUidForName() # getUidForName方法
├── getThreadPriority() # getThreadPriority方法
├── getSystemConfig() # getSystemConfig方法
├── getEnvironmentVar() # getEnvironmentVar方法
├── exit() # exit方法
├── cwd() # cwd方法
├── off() # off方法
├── runCmd() # runCmd方法
└─── Class:CHILDPROCESS # class of CHILDPROCESS类
├── close() # close方法
├── kill() # kill方法
├── getOutput() # getOutput方法
├── getErrorOutput() # getErrorOutput方法
├── wait() # wait方法
├── killed # killed属性
├── pid # pid属性
├── ppid # ppid属性
└── exitCode # exitCode属性
```
## 说明
### 接口说明
| 接口名 | 说明 |
| -------- | -------- |
| const uid :number | 返回进程的数字用户 ID。 |
| const gid :number | 返回进程的数字组 ID。 |
| const euid :number | 返回进程的数字有效用户身份。 |
| const egid :number | 返回 node.js 进程的数字有效组 ID。 |
| const groups :number[] | 返回具有补充组 ID 的数组。 |
| const pid :number | 返回进程的PID。 |
| const ppid :number | 返回当前进程的父进程的PID。 |
| chdir(dir:string) :void | 更改 node.js 进程的当前工作目录。 |
| uptime() :number | 返回当前系统已经运行的秒数。 |
| Kill(pid:number, signal:number) :boolean | 将信号发送到识别的进程PIDtrue表示发送成功。 |
| abort() :void | 导致 node.js 进程立即退出并生成核心文件。 |
| on(type:string ,listener:EventListener) :void | 用于存储用户触发的事件。 |
| exit(code:number):void | 导致 node.js 进程立即退出。 |
| cwd():string | 返回 node.js 进程的当前工作目录。 |
| off(type: string): boolean | 清除用户存储的事件。 True 表示清算成功。 |
| runCmd(command: string, options?: { timeout : number, killSignal : number \| string, maxBuffer : number }): ChildProcess |通过runcmd你可以fork一个新进程来运行一个shell并返回childprocess对象。 第一个参数command指的是要运行的shell第二个参数options指的是子进程的一些运行参数。 这些参数主要是指 timeout、killsignal 和 maxbuffer。 如果设置了timeout则子进程会在超时后发送killsignal信号。 Maxbuffer 用于限制可以接收的最大 stdout 和 stderr 大小。 |
| wait() Promise\<number> | 用于等待子进程运行并返回promise对象其值为子进程的退出码。 |
| getOutput(): Promise\<Uint8Array> | 用于获取子进程的标准输出。 |
| getErrorOutput(): Promise\<Uint8Array> | 用于获取子进程的标准错误输出。 |
| const tid:number | 返回进程的 TID。 |
| getStartRealtime() :number | 获取从系统启动到进程启动所经过的实时时间(以毫秒为单位)。 |
| getAvailableCores() :number[] | 获取多核设备上当前进程可用的 CPU 内核。 |
| getPastCputime() :number | 获取从进程开始到当前时间的 CPU 时间(以毫秒为单位)。 |
| isIsolatedProcess(): boolean | 检查进程是否被隔离。 |
| is64Bit(): boolean | 检查进程是否在 64 位环境中运行。 |
| isAppUid(v:number): boolean | 检查指定的 uid 是否属于特定应用程序。 |
| getUidForName(v:string): number | 根据用户名获取用户所属的用户组ID |
| getThreadPriority(v:number): number | 根据指定的 TID 获取线程优先级。 |
| getSystemConfig(name:number): number | 根据指定的系统配置名称获取系统的配置。 |
| getEnvironmentVar(name:string): string | 根据环境变量的名称获取对应的值。 |
| close(): void | 用于关闭正在运行的子进程。 |
| kill(signal: number \| string): void | 用于向子进程发送信号。 |
| readonly killed: boolean | 表示信号是否发送成功true表示信号发送成功。 |
| readonly exitCode: number | 表示子进程的退出代码。 |
| readonly pid: number | 表示子进程ID。 |
| readonly ppid: number | 代表主进程ID。 |
### 使用说明
各接口使用方法如下:
1.uid()
```
uid(){
var res = Process.uid;
}
```
2.gid()
```
gid(){
var result = Process.gid;
}
```
3.euid()
```
euid(){
var and = Process.euid;
}
```
4.egid()
```
egid(){
var resb = Process.egid;
}
```
5.groups()
```
groups(){
var answer = Process.groups;
}
```
6.pid()
```
pid(){
var result = Process.pid;
}
```
7.ppid()
```
ppid(){
var result = Process.ppid;
}
```
8.chdir()
```
chdir(){
Process.chdir("123456");
}
```
9.uptime()
```
uptime(){
var num = Process.uptime();
}
```
10.kill()
```
kill(){
var ansu = Process.kill(5,23);
}
```
11.abort()
```
abort(){
Process.abort();
}
```
12.on()
```
on(){
function add(num){
var value = num + 5;
return value;
}
Process.on("add",add);
}
```
13.exit()
```
exit(){
Process.exit(15);
}
```
14.Cwd()
```
Cwd(){
var result = Process.cwd();
}
```
15.off()
```
off(){
var result = Process.off("add");
}
```
16.runCmd()
```
runCmd(){
var child = process.runCmd('echo abc')
// killSignal can be a number or a string
var child = process.runCmd('echo abc;', {killSignal : 'SIGKILL'});
var child = process.runCmd('sleep 5; echo abc;', {timeout : 1, killSignal : 9, maxBuffer : 2})
}
```
17.wait()
```
wait()
{
var child = process.runCmd('ls')
var status = child.wait();
status.then(val => {
console.log(val);
})
}
```
18.getOutput()
```
getOutput(){
var child = process.runCmd('echo bcd;');
var res = child.getOutput();
child.wait();
res.then(val => {
console.log(val);
})
}
```
19.getErrorOutput()
```
getErrorOutput(){
var child = process.runCmd('makdir 1.txt'); // execute an error command
var res = child.getErrorOutput();
child.wait();
res.then(val => {
console.log(val);
})
}
```
20.close()
```
close(){
var child = process.runCmd('ls; sleep 5s;')
var result = child.close()
}
```
21.kill()
```
kill(){
var child = process.runCmd('ls; sleep 5s;')
var result = child.kill('SIGHUP');
child.wait();
var temp = child.killed;
}
```
22.killed
```
{
var child = process.runCmd('ls; sleep 5;')
child.kill(3);
var killed_ = child.killed;
child.wait();
}
```
23.exitCode
```
{
var child = process.runCmd('ls; sleep 5;')
child.kill(9);
child.wait();
var exitCode_ = child.exitCode;
}
```
24.pid
```
pid
{
var child = process.runCmd('ls; sleep 5;')
var pid_ = child.pid;
child.wait();
}
```
25.ppid
```
ppid
{
var child = process.runCmd('ls; sleep 5;')
var ppid_ = child.ppid;
child.wait();
}
```
26.tid
```
tid(){
var ansu = Process.tid;
}
```
27.isIsolatedProcess()
```
isIsolatedProcess(){
var ansu = Process.isIsolatedProcess()();
}
```
28.isAppUid()
```
isAppUid(){
var ansu = Process.isAppUid(10000);
}
```
29.is64Bit()
```
is64Bit(){
var ansu = Process.is64Bit();
}
```
30.getUidForName()
```
getUidForName(){
var buf = "root";
var ansu = Process.getUidForName(buf);
}
```
31.getEnvironmentVar()
```
getEnvironmentVar(){
var ansu = Process.getEnvironmentVar('USER');
}
```
32.getAvailableCores()
```
getAvailableCores(){
var ansu = Process.getAvailableCores();
}
```
33.getThreadPriority()
```
getThreadPriority(){
var result = Process.getTid();
var ansu = getThreadPriority(result);
}
```
34.getStartRealtime()
```
getStartRealtime(){
var ansu = Process.getStartRealtime();
}
```
35.getPastCputime()
```
getPastCputime(){
var ansu = Process.getPastCputime();
}
```
36.getSystemConfig()
```
getSystemConfig(){
var _SC_ARG_MAX = 0;
var ansu = Process.getSystemConfig(_SC_ARG_MAX)
}
```
## 相关仓
[js_sys_module](base/compileruntime/js_sys_module/readme.md)
### 许可证
SYS在[Mozilla许可证](https://www.mozilla.org/en-US/MPL/)下可用,说明文档详见[说明文档](https://gitee.com/openharmony/js_sys_module/blob/master/mozilla_docs.txt)。有关完整的许可证文本,有关完整的许可证文本,请参见[许可证](https://gitee.com/openharmony/js_sys_module/blob/master/LICENSE)

59
js_sys_module/bundle.json Normal file
View File

@ -0,0 +1,59 @@
{
"name": "@ohos/js_sys_module",
"version": "",
"description": "Provide system basic ability query API, including process information, CPU load information, etc. | js_sys_module, 提供系统基础能力查询API包括进程信息CPU负载信息等",
"homePage": "https://gitee.com/openharmony",
"license": "Apache V2",
"repository": "https://gitee.com/openharmony/js_sys_module",
"domain": "os",
"language": "",
"publishAs": "code-segment",
"private": false,
"scripts": {},
"tags": [
"js"
],
"keywords": [
"js",
"sys",
"module"
],
"envs": {},
"dirs": {},
"author": {
"name": "",
"email": "",
"url": ""
},
"contributors": [
{
"name": "",
"email": "",
"url": ""
}
],
"segment": {
"destPath": "base/compileruntime/js_sys_module"
},
"component": {
"name": "jsapi_sys",
"subsystem": "utils",
"syscap": [],
"features": [],
"adapted_system_type": [],
"rom": "",
"ram": "",
"deps": {
"components": [],
"third_party": []
},
"build": {
"sub_component": [
"//base/compileruntime/js_sys_module/process:process_packages",
"//base/compileruntime/js_sys_module/dfx:dfx_packages"
],
"inner_kits": [],
"test": []
}
}
}

View File

@ -0,0 +1,48 @@
# Copyright (c) 2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
ohos_shared_library("dfx") {
include_dirs = [
"//foundation/arkui/napi",
"//foundation/arkui/napi/native_engine",
"//third_party/icu/icu4c/source/common",
"//third_party/node/src",
"//foundation/arkui/napi/interfaces/kits",
"//base/compileruntime/js_api_module/dfx",
]
sources = [ "native_module_dfx.cpp" ]
deps = [
"//foundation/arkui/napi/:ace_napi",
"//foundation/arkui/napi/:ace_napi_quickjs",
"//third_party/icu/icu4c:static_icuuc",
"//utils/native/base:utils",
]
if (is_standard_system) {
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
} else {
external_deps = [ "hilog:libhilog" ]
}
subsystem_name = "utils"
part_name = "jsapi_sys"
relative_install_dir = "module"
}
group("dfx_packages") {
deps = [ ":dfx" ]
}

View File

@ -0,0 +1,210 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "napi/native_api.h"
#include "native_engine.h"
#include "napi/native_node_api.h"
#include "securec.h"
#include "utils/log.h"
namespace OHOS::Js_sys_module::Dfx {
constexpr int NUMBER_OF_PARAMETER_TWO = 2;
static napi_value DumpHeapSnapshot(napi_env env, napi_callback_info info)
{
size_t argc = NUMBER_OF_PARAMETER_TWO;
size_t requireArgc = NUMBER_OF_PARAMETER_TWO;
napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
NAPI_ASSERT(env, argc <= requireArgc, "Wrong number of arguments");
napi_value argv[NUMBER_OF_PARAMETER_TWO] = { 0 };
napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
std::string tempStr = "";
size_t tempStrsize = 0;
if (napi_get_value_string_utf8(env, argv[0], nullptr, 0, &tempStrsize) != napi_ok) {
HILOG_ERROR("can not get argv[0] size");
return nullptr;
}
tempStr.reserve(tempStrsize + 1);
tempStr.resize(tempStrsize);
if (napi_get_value_string_utf8(env, argv[0], tempStr.data(), tempStrsize + 1, &tempStrsize) != napi_ok) {
HILOG_ERROR("can not get argv[0] value");
return nullptr;
}
std::string pathStr = tempStr;
bool isVmMode = true;
napi_get_value_bool(env, argv[1], &isVmMode);
NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
engine->DumpHeapSnapshot(pathStr, isVmMode);
napi_value result = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &result));
return result;
}
static napi_value BuildNativeAndJsStackTrace(napi_env env, napi_callback_info info)
{
napi_value result = nullptr;
NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
std::string stackTraceResult = "";
bool temp = engine->BuildNativeAndJsStackTrace(stackTraceResult);
NAPI_CALL(env, napi_create_string_utf8(env, stackTraceResult.c_str(), stackTraceResult.size(), &result));
if (temp) {
return result;
} else {
return nullptr;
}
}
static napi_value StartHeapTracking(napi_env env, napi_callback_info info)
{
size_t argc = NUMBER_OF_PARAMETER_TWO;
size_t requireArgc = NUMBER_OF_PARAMETER_TWO;
napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
NAPI_ASSERT(env, argc <= requireArgc, "Wrong number of arguments");
napi_value argv[NUMBER_OF_PARAMETER_TWO] = { 0 };
napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
double timeInterval = 0;
if (napi_get_value_double(env, argv[0], &timeInterval) != napi_ok) {
HILOG_ERROR("can not get argv[0] value");
return nullptr;
}
bool isVmMode = true;
if (napi_get_value_bool(env, argv[1], &isVmMode) != napi_ok) {
HILOG_ERROR("can not get argv[1] value");
return nullptr;
}
NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
auto startResult = engine->StartHeapTracking(timeInterval, isVmMode);
napi_value result = nullptr;
NAPI_CALL(env, napi_get_boolean(env, startResult, &result));
return result;
}
static napi_value StopHeapTracking(napi_env env, napi_callback_info info)
{
size_t argc = 1;
size_t requireArgc = 1;
napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
NAPI_ASSERT(env, argc <= requireArgc, "Wrong number of arguments");
napi_value argv = nullptr;
napi_get_cb_info(env, info, &argc, &argv, nullptr, nullptr);
std::string tempStr = "";
size_t tempStrsize = 0;
if (napi_get_value_string_utf8(env, argv, nullptr, 0, &tempStrsize) != napi_ok) {
HILOG_ERROR("can not get argv size");
return nullptr;
}
tempStr.reserve(tempStrsize);
tempStr.resize(tempStrsize);
if (napi_get_value_string_utf8(env, argv, tempStr.data(), tempStrsize + 1, &tempStrsize) != napi_ok) {
HILOG_ERROR("can not get argv value");
return nullptr;
}
std::string filePath = tempStr;
NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
auto stopResult = engine->StopHeapTracking(filePath);
napi_value result = nullptr;
NAPI_CALL(env, napi_get_boolean(env, stopResult, &result));
return result;
}
static napi_value PrintStatisticResult(napi_env env, napi_callback_info info)
{
NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
engine->PrintStatisticResult();
napi_value result = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &result));
return result;
}
static napi_value StartRuntimeStat(napi_env env, napi_callback_info info)
{
NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
engine->StartRuntimeStat();
napi_value result = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &result));
return result;
}
static napi_value StopRuntimeStat(napi_env env, napi_callback_info info)
{
NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
engine->StopRuntimeStat();
napi_value result = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &result));
return result;
}
static napi_value GetArrayBufferSize(napi_env env, napi_callback_info info)
{
NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
auto value = static_cast<uint32_t>(engine->GetArrayBufferSize());
napi_value result = nullptr;
NAPI_CALL(env, napi_create_uint32(env, value, &result));
return result;
}
static napi_value GetHeapTotalSize(napi_env env, napi_callback_info info)
{
NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
auto value = static_cast<uint32_t>(engine->GetHeapTotalSize());
napi_value result = nullptr;
NAPI_CALL(env, napi_create_uint32(env, value, &result));
return result;
}
static napi_value GetHeapUsedSize(napi_env env, napi_callback_info info)
{
NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
auto value = static_cast<uint32_t>(engine->GetHeapUsedSize());
napi_value result = nullptr;
NAPI_CALL(env, napi_create_uint32(env, value, &result));
return result;
}
static napi_value DfxInit(napi_env env, napi_value exports)
{
static napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("dumpHeapSnapshot", DumpHeapSnapshot),
DECLARE_NAPI_FUNCTION("buildNativeAndJsStackTrace", BuildNativeAndJsStackTrace),
DECLARE_NAPI_FUNCTION("startHeapTracking", StartHeapTracking),
DECLARE_NAPI_FUNCTION("stopHeapTracking", StopHeapTracking),
DECLARE_NAPI_FUNCTION("printStatisticResult", PrintStatisticResult),
DECLARE_NAPI_FUNCTION("startRuntimeStat", StartRuntimeStat),
DECLARE_NAPI_FUNCTION("stopRuntimeStat", StopRuntimeStat),
DECLARE_NAPI_FUNCTION("getArrayBufferSize", GetArrayBufferSize),
DECLARE_NAPI_FUNCTION("getHeapTotalSize", GetHeapTotalSize),
DECLARE_NAPI_FUNCTION("getHeapUsedSize", GetHeapUsedSize),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
return exports;
}
// dfx module define
static napi_module dfxModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = DfxInit,
.nm_modname = "dfx",
.nm_priv = reinterpret_cast<void*>(0),
.reserved = {0},
};
// dfx module register
extern "C"
__attribute__((constructor)) void RegisterModule()
{
napi_module_register(&dfxModule);
}
} // namespace OHOS::Js_sys_module::Dfx

View File

@ -0,0 +1,50 @@
# Copyright (c) 2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
ohos_shared_library("process") {
include_dirs = [
"//third_party/icu/icu4c/source/common",
"//third_party/node/src",
"//foundation/arkui/napi/interfaces/kits",
"//base/compileruntime/js_sys_module/process",
]
sources = [
"js_childprocess.cpp",
"js_process.cpp",
"native_module_process.cpp",
]
deps = [
"//foundation/arkui/napi/:ace_napi",
"//foundation/arkui/napi/:ace_napi_quickjs",
"//third_party/icu/icu4c:static_icuuc",
"//utils/native/base:utils",
]
if (is_standard_system) {
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
} else {
external_deps = [ "hilog:libhilog" ]
}
subsystem_name = "utils"
part_name = "jsapi_sys"
relative_install_dir = "module"
}
group("process_packages") {
deps = [ ":process" ]
}

View File

@ -0,0 +1,488 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "js_childprocess.h"
#include <map>
#include <vector>
#include <csignal>
#include <cstdlib>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/wait.h>
#include "securec.h"
#include "utils/log.h"
namespace OHOS::Js_sys_module::Process {
constexpr int MAXSIZE = 1024;
constexpr int TIME_EXCHANGE = 1000;
std::map<std::string, int> g_signalsMap = {
{"SIGHUP", 1},
{"SIGINT", 2},
{"SIGQUIT", 3},
{"SIGILL", 4},
{"SIGTRAP", 5},
{"SIGABRT", 6},
{"SIGBUS", 7},
{"SIGFPE", 8},
{"SIGKILL", 9},
{"SIGUSR1", 10},
{"SIGSEGV", 11},
{"SIGUSR2", 12},
{"SIGPIPE", 13},
{"SIGALRM", 14},
{"SIGTERM", 15},
{"SIGSTKFLT", 16},
{"SIGCHLD", 17},
{"SIGCONT", 18},
{"SIGSTOP", 19},
{"SIGTSTP", 20},
{"SIGTTIN", 21},
{"SIGTTOU", 22},
{"SIGURG", 23},
{"SIGXCPU", 24},
{"SIGXFSZ", 25},
{"SIGVTALRM", 26},
{"SIGPROF", 27},
{"SIGWINCH", 28},
{"SIGIO", 29},
{"SIGPWR", 30},
{"SIGSYS", 31}
};
void ChildProcess::Spawn(napi_env env, napi_value command)
{
int ret = pipe(stdOutFd_);
if (ret < 0) {
HILOG_ERROR("pipe1 failed %{public}d", errno);
return;
}
ret = pipe(stdErrFd_);
if (ret < 0) {
HILOG_ERROR("pipe2 failed %{public}d", errno);
return;
}
std::string strCommnd = RequireStrValue(env, command);
pid_t pid = fork();
if (!pid) {
close(stdErrFd_[0]);
close(stdOutFd_[0]);
dup2(stdOutFd_[1], 1);
dup2(stdErrFd_[1], 2); // 2:The value of parameter
if (execl("/bin/sh", "sh", "-c", strCommnd.c_str(), nullptr) == -1) {
HILOG_ERROR("execl command failed");
exit(127); // 127:The parameter value
}
} else if (pid > 0) {
if (optionsInfo_ == nullptr) {
HILOG_ERROR("optionsInfo_ is nullptr");
return;
}
optionsInfo_->pid = pid;
ppid_ = getpid();
CreateWorker(env);
napi_value resourceName = nullptr;
napi_create_string_utf8(env, "TimeoutListener", strlen("TimeoutListener"), &resourceName);
napi_create_async_work(
env, nullptr, resourceName, TimeoutListener,
[](napi_env env, napi_status status, void* data) {
OptionsInfo* optionsInfo = reinterpret_cast<OptionsInfo*>(data);
napi_delete_async_work(env, optionsInfo->worker);
delete optionsInfo;
optionsInfo = nullptr;
},
reinterpret_cast<void*>(optionsInfo_), &optionsInfo_->worker);
napi_queue_async_work(env, optionsInfo_->worker);
close(stdErrFd_[1]);
close(stdOutFd_[1]);
} else {
HILOG_ERROR("child process create failed");
}
}
napi_value ChildProcess::Wait(napi_env env)
{
napi_value promise = nullptr;
auto waitInfo = new WaitInfo;
napi_create_promise(env, &(waitInfo->deferred), &promise);
if (isWait_) {
int32_t status;
isWait_ = false;
if (optionsInfo_ == nullptr) {
napi_value res = nullptr;
napi_get_undefined(env, &res);
delete waitInfo;
waitInfo = nullptr;
HILOG_ERROR("optionsInfo_ is nullptr");
return res;
}
waitpid(optionsInfo_->pid, &status, 0);
exitCode_ = status;
}
isNeedRun_ = false;
napi_value result = nullptr;
napi_create_int32(env, static_cast<int8_t>(exitCode_), &result);
napi_resolve_deferred(env, waitInfo->deferred, result);
delete waitInfo;
waitInfo = nullptr;
return promise;
}
napi_value ChildProcess::GetOutput(napi_env env) const
{
if (stdOutInfo_ == nullptr) {
napi_value res = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &res));
HILOG_ERROR("stdOutInfo_ is nullptr");
return res;
}
NAPI_CALL(env, napi_create_promise(env, &stdOutInfo_->deferred, &stdOutInfo_->promise));
void* data = nullptr;
napi_value arrayBuffer = nullptr;
size_t bufferSize = stdOutInfo_->stdData.size() + 1;
NAPI_CALL(env, napi_create_arraybuffer(env, bufferSize, &data, &arrayBuffer));
if (memcpy_s(data, bufferSize, reinterpret_cast<const void*>(stdOutInfo_->stdData.c_str()),
stdOutInfo_->stdData.size()) != EOK) {
HILOG_ERROR("getOutput memcpy_s failed");
NAPI_CALL(env, napi_delete_async_work(env, stdOutInfo_->worker));
napi_value res = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &res));
return res;
}
napi_value result = nullptr;
NAPI_CALL(env, napi_create_typedarray(env, napi_uint8_array, bufferSize, arrayBuffer, 0, &result));
NAPI_CALL(env, napi_resolve_deferred(env, stdOutInfo_->deferred, result));
return stdOutInfo_->promise;
}
napi_value ChildProcess::GetErrorOutput(napi_env env) const
{
if (stdErrInfo_ == nullptr) {
napi_value res = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &res));
HILOG_ERROR("stdErrInfo_ is nullptr");
return res;
}
NAPI_CALL(env, napi_create_promise(env, &stdErrInfo_->deferred, &stdErrInfo_->promise));
void* data = nullptr;
napi_value arrayBuffer = nullptr;
size_t bufferSize = stdErrInfo_->stdData.size() + 1;
NAPI_CALL(env, napi_create_arraybuffer(env, bufferSize, &data, &arrayBuffer));
if (memcpy_s(data, bufferSize, reinterpret_cast<const void*>(stdErrInfo_->stdData.c_str()),
stdErrInfo_->stdData.size()) != EOK) {
HILOG_ERROR("getErrOutput memcpy_s failed");
NAPI_CALL(env, napi_delete_async_work(env, stdErrInfo_->worker));
napi_value res = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &res));
return res;
}
napi_value result = nullptr;
NAPI_CALL(env, napi_create_typedarray(env, napi_uint8_array, bufferSize, arrayBuffer, 0, &result));
NAPI_CALL(env, napi_resolve_deferred(env, stdErrInfo_->deferred, result));
return stdErrInfo_->promise;
}
napi_value ChildProcess::GetKilled(napi_env env) const
{
napi_value result = nullptr;
NAPI_CALL(env, napi_get_boolean(env, killed_, &result));
return result;
}
napi_value ChildProcess::Getpid(napi_env env) const
{
napi_value result = nullptr;
if (optionsInfo_ == nullptr) {
napi_value res = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &res));
HILOG_ERROR("optionsInfo_ is nullptr");
return res;
}
NAPI_CALL(env, napi_create_int32(env, optionsInfo_->pid, &result));
return result;
}
napi_value ChildProcess::Getppid(napi_env env) const
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_int32(env, ppid_, &result));
return result;
}
napi_value ChildProcess::GetExitCode(napi_env env) const
{
napi_value result = nullptr;
NAPI_CALL(env, napi_create_int32(env, static_cast<int8_t>(exitCode_), &result));
return result;
}
void ChildProcess::CreateWorker(napi_env env)
{
// getstdout
napi_value resourceName = nullptr;
stdOutInfo_ = new StdInfo();
if (stdOutInfo_ == nullptr) {
HILOG_ERROR("stdOutInfo_ is nullptr");
return;
}
stdOutInfo_->isNeedRun = &isNeedRun_;
stdOutInfo_->fd = stdOutFd_[0];
if (optionsInfo_ == nullptr) {
HILOG_ERROR("optionsInfo_ is nullptr");
return;
}
stdOutInfo_->pid = optionsInfo_->pid;
stdOutInfo_->maxBuffSize = optionsInfo_->maxBuffer;
napi_create_string_utf8(env, "ReadStdOut", NAPI_AUTO_LENGTH, &resourceName);
napi_create_async_work(env, nullptr, resourceName, ReadStdOut, EndStdOut,
reinterpret_cast<void*>(stdOutInfo_), &stdOutInfo_->worker);
napi_queue_async_work(env, stdOutInfo_->worker);
// getstderr
stdErrInfo_ = new StdInfo();
if (stdErrInfo_ == nullptr) {
HILOG_ERROR("stdErrInfo_ is nullptr");
return;
}
stdErrInfo_->isNeedRun = &isNeedRun_;
stdErrInfo_->fd = stdErrFd_[0];
stdErrInfo_->pid = optionsInfo_->pid;
stdErrInfo_->maxBuffSize = optionsInfo_->maxBuffer;
napi_create_string_utf8(env, "ReadStdErr", NAPI_AUTO_LENGTH, &resourceName);
napi_create_async_work(env, nullptr, resourceName, ReadStdErr, EndStdErr,
reinterpret_cast<void*>(stdErrInfo_), &stdErrInfo_->worker);
napi_queue_async_work(env, stdErrInfo_->worker);
}
void ChildProcess::ReadStdOut(napi_env env, void* data)
{
auto stdOutInfo = reinterpret_cast<StdInfo*>(data);
char childStdout[MAXSIZE] = {0};
if (stdOutInfo->isNeedRun == nullptr) {
return;
}
while (*(stdOutInfo->isNeedRun)) {
auto readSize = read(stdOutInfo->fd, childStdout, sizeof(childStdout) - 1);
if (readSize >= 0) {
stdOutInfo->stdData += childStdout;
}
if (stdOutInfo->stdData.size() > static_cast<size_t>(stdOutInfo->maxBuffSize) && *(stdOutInfo->isNeedRun)) {
if (!kill(stdOutInfo->pid, SIGKILL)) {
*(stdOutInfo->isNeedRun) = false;
stdOutInfo->stdData = stdOutInfo->stdData.substr(0, stdOutInfo->maxBuffSize);
} else {
HILOG_ERROR("stdOut maxBuff kill signal failed");
}
}
if (memset_s(childStdout, sizeof(childStdout), '\0', MAXSIZE) != EOK) {
HILOG_ERROR("getOutput memset_s failed");
return;
}
}
}
void ChildProcess::EndStdOut(napi_env env, napi_status status, void* buffer)
{
auto stdOutInfo = reinterpret_cast<StdInfo*>(buffer);
napi_delete_async_work(env, stdOutInfo->worker);
delete stdOutInfo;
stdOutInfo = nullptr;
}
void ChildProcess::ReadStdErr(napi_env env, void* data)
{
auto stdErrInfo = reinterpret_cast<StdInfo*>(data);
char childStderr[MAXSIZE] = {0};
if (stdErrInfo->isNeedRun == nullptr) {
return;
}
while (*(stdErrInfo->isNeedRun)) {
auto readSize = read(stdErrInfo->fd, childStderr, sizeof(childStderr) - 1);
if (readSize >= 0) {
stdErrInfo->stdData += childStderr;
}
if (stdErrInfo->stdData.size() > static_cast<size_t>(stdErrInfo->maxBuffSize) && *(stdErrInfo->isNeedRun)) {
if (!kill(stdErrInfo->pid, SIGKILL)) {
*(stdErrInfo->isNeedRun) = false;
stdErrInfo->stdData = stdErrInfo->stdData.substr(0, stdErrInfo->maxBuffSize);
} else {
HILOG_ERROR("stdErr maxBuff kill signal failed");
}
}
if (memset_s(childStderr, sizeof(childStderr), '\0', MAXSIZE) != EOK) {
HILOG_ERROR("getOutput memset_s failed");
return;
}
}
}
void ChildProcess::EndStdErr(napi_env env, napi_status status, void* buffer)
{
auto stdErrInfo = reinterpret_cast<StdInfo*>(buffer);
napi_delete_async_work(env, stdErrInfo->worker);
delete stdErrInfo;
stdErrInfo = nullptr;
}
int ChildProcess::GetValidSignal(napi_env env, const napi_value signo)
{
int32_t sig = 0;
napi_valuetype valuetype = napi_undefined;
napi_typeof(env, signo, &valuetype);
if (valuetype == napi_valuetype::napi_number) {
napi_get_value_int32(env, signo, &sig);
return sig;
} else if (valuetype == napi_valuetype::napi_string) {
std::string buffer = RequireStrValue(env, signo);
auto iter = g_signalsMap.find(buffer);
if (iter != g_signalsMap.end()) {
sig = iter->second;
return sig;
} else {
return g_signalsMap["SIGTERM"];
}
} else {
return g_signalsMap["SIGTERM"];
}
}
void ChildProcess::Kill(napi_env env, const napi_value signo)
{
int signal = GetValidSignal(env, signo);
std::vector<int32_t> signalType = {SIGINT, SIGQUIT, SIGKILL, SIGTERM};
if (optionsInfo_ == nullptr) {
HILOG_ERROR("optionsInfo_ is nullptr");
return;
}
if (!kill(optionsInfo_->pid, signal)) {
auto res = std::find(signalType.begin(), signalType.end(), static_cast<int32_t>(signal));
(res != signalType.end()) ? isNeedRun_ = false : 0;
killed_ = true;
} else {
HILOG_ERROR("kill signal failed");
}
}
void ChildProcess::Close()
{
int32_t status = 0;
if (optionsInfo_ == nullptr) {
HILOG_ERROR("optionsInfo_ is nullptr");
return;
}
if (isWait_ && !(waitpid(optionsInfo_->pid, &status, WNOHANG)) && isNeedRun_) {
if (!kill(optionsInfo_->pid, SIGKILL)) {
waitpid(optionsInfo_->pid, &status, 0);
isWait_ = false;
exitCode_ = status;
isNeedRun_ = false;
} else {
HILOG_ERROR("close kill SIGKILL signal failed");
}
}
}
void ChildProcess::TimeoutListener(napi_env env, void* data)
{
std::vector<int32_t> signalType = {SIGINT, SIGQUIT, SIGKILL, SIGTERM};
auto temp = reinterpret_cast<OptionsInfo*>(data);
int32_t timeout = temp->timeout * TIME_EXCHANGE;
if (timeout > 0) {
usleep(static_cast<size_t>(timeout));
if (*(temp->isNeedRun)) {
if (!kill(temp->pid, temp->killSignal)) {
auto res = std::find(signalType.begin(), signalType.end(), temp->killSignal);
(res != signalType.end()) ? *(temp->isNeedRun) = false : 0;
} else {
HILOG_ERROR("timeout kill signal failed");
}
}
}
}
void ChildProcess::InitOptionsInfo(napi_env env, napi_value options)
{
std::vector<std::string> keyStr = {"timeout", "killSignal", "maxBuffer"};
optionsInfo_ = new OptionsInfo();
if (optionsInfo_ == nullptr) {
HILOG_ERROR("optionsInfo_ is nullptr");
return;
}
size_t size = keyStr.size();
for (size_t i = 0; i < size; i++) {
napi_status status = napi_ok;
napi_value property = nullptr;
napi_get_named_property(env, options, keyStr[i].c_str(), &property);
switch (i) {
case 0:
status = napi_get_value_int32(env, property, &optionsInfo_->timeout);
if (status != napi_ok) {
optionsInfo_->timeout = 0;
}
break;
case 1:
optionsInfo_->killSignal = GetValidSignal(env, property);
break;
case 2: // 2:The parameter value
status = napi_get_value_int64(env, property, &optionsInfo_->maxBuffer);
if (status != napi_ok) {
optionsInfo_->maxBuffer = static_cast<int64_t>(MAXSIZE) * static_cast<int64_t>(MAXSIZE);
}
break;
default:
break;
}
}
optionsInfo_->isNeedRun = &isNeedRun_;
}
std::string ChildProcess::RequireStrValue(napi_env env, const napi_value strValue)
{
size_t bufferSize = 0;
if (napi_get_value_string_utf8(env, strValue, nullptr, 0, &bufferSize) != napi_ok) {
HILOG_ERROR("can not get strValue size");
return nullptr;
}
std::string result = "";
result.reserve(bufferSize + 1);
result.resize(bufferSize);
if (napi_get_value_string_utf8(env, strValue, result.data(), bufferSize + 1, &bufferSize) != napi_ok) {
HILOG_ERROR("can not get strValue value");
return nullptr;
}
return result;
}
ChildProcess::~ChildProcess()
{
close(stdOutFd_[0]);
close(stdErrFd_[0]);
if (isWait_) {
int32_t status = 0;
waitpid(optionsInfo_->pid, &status, 0);
}
isNeedRun_ = false;
}
} // namespace OHOS::Js_sys_module::Process

View File

@ -0,0 +1,166 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PROCESS_JS_CHILDPROCESS_H_
#define PROCESS_JS_CHILDPROCESS_H_
#include <string>
#include <sys/types.h>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
namespace OHOS::Js_sys_module::Process {
struct WaitInfo {
napi_async_work worker = nullptr;
napi_deferred deferred = nullptr;
int status = 0;
};
struct StdInfo {
napi_async_work worker = nullptr;
napi_deferred deferred = nullptr;
napi_value promise = nullptr;
std::string stdData = "";
bool *isNeedRun = nullptr;
int64_t maxBuffSize;
int fd = 0;
int pid = 0;
};
struct OptionsInfo {
napi_async_work worker = nullptr;
bool *isNeedRun = nullptr;
int32_t timeout = 0;
int32_t killSignal = 0;
int64_t maxBuffer = 0;
pid_t pid = 0;
};
class ChildProcess {
public:
/**
* Create child process object.
*/
explicit ChildProcess() {}
/**
* Close the target process.
*/
void Close();
/**
* Send a signal to process.
*
* @param env NAPI environment parameters.
* @param signal Number or string represents the signal sent.
*/
void Kill(napi_env env, const napi_value signo);
/**
* Wait for the child process to finish running, and return a promise object
* whose value is the exit code of the child process.
*
* @param env NAPI environment parameters.
*/
napi_value Wait(napi_env env);
/**
* Get the standard output of the child process.
*
* @param env NAPI environment parameters.
*/
napi_value GetOutput(napi_env env) const;
/**
* Get the standard error output of the child process.
*
* @param env NAPI environment parameters.
*/
napi_value GetErrorOutput(napi_env env) const;
/**
* Get kill status.
*
* @param env NAPI environment parameters.
*/
napi_value GetKilled(napi_env env) const;
/**
* Get the specific pid value.
*
* @param env NAPI environment parameters.
*/
napi_value Getpid(napi_env env) const;
/**
* Get the parent process ID.
*
* @param env NAPI environment parameters.
*/
napi_value Getppid(napi_env env) const;
/**
* Get exit status.
*
* @param env NAPI environment parameters.
*/
napi_value GetExitCode(napi_env env) const;
/**
* Initialization option information.
*
* @param env NAPI environment parameters.
* @param options Option parameter.
*/
void InitOptionsInfo(napi_env env, napi_value options);
/**
* Start a subprocess to execute shell commands.
*
* @param env NAPI environment parameters.
* @param command Command parameters.
*/
void Spawn(napi_env env, napi_value command);
/**
* ChildProcess destructor.
*/
virtual ~ChildProcess();
private:
static void ReadStdOut(napi_env env, void* data);
static void EndStdOut(napi_env env, napi_status status, void* buffer);
static void ReadStdErr(napi_env env, void* data);
static void EndStdErr(napi_env env, napi_status status, void* buffer);
static void TimeoutListener(napi_env env, void* data);
std::string RequireStrValue(napi_env env, const napi_value strValue);
int GetValidSignal(napi_env env, const napi_value signo);
void CreateWorker(napi_env env);
OptionsInfo* optionsInfo_ = nullptr;
StdInfo* stdOutInfo_ = nullptr;
StdInfo* stdErrInfo_ = nullptr;
int exitCode_ = 0;
int stdOutFd_[2] = {0};
int stdErrFd_[2] = {0};
int ppid_ = 0;
bool isNeedRun_ = true;
bool killed_ = false;
bool isWait_ = true;
};
} // namespace OHOS::Js_sys_module::Process
#endif // PROCESS_JS_CHILDPROCESS_H_

View File

@ -0,0 +1,576 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "js_process.h"
#include <cstdlib>
#include <vector>
#include <grp.h>
#include <pthread.h>
#include <pwd.h>
#include <sched.h>
#include <unistd.h>
#include <uv.h>
#include <sys/resource.h>
#include <sys/syscall.h>
#include <sys/sysinfo.h>
#include <sys/types.h>
#include "securec.h"
#include "utils/log.h"
namespace OHOS::Js_sys_module::Process {
namespace {
constexpr int NUM_OF_DATA = 4;
constexpr int PER_USER_RANGE = 100000;
constexpr int32_t NAPI_RETURN_ZERO = 0;
constexpr int32_t NAPI_RETURN_ONE = 1;
}
thread_local std::multimap<std::string, napi_ref> eventMap;
thread_local std::map<napi_ref, napi_ref> pendingUnHandledRejections;
// support events
thread_local std::string events = "UnHandleRejection";
napi_value Process::GetUid(napi_env env) const
{
napi_value result = nullptr;
auto processGetuid = static_cast<uint32_t>(getuid());
NAPI_CALL(env, napi_create_uint32(env, processGetuid, &result));
return result;
}
napi_value Process::GetGid(napi_env env) const
{
napi_value result = nullptr;
auto processGetgid = static_cast<uint32_t>(getgid());
NAPI_CALL(env, napi_create_uint32(env, processGetgid, &result));
return result;
}
napi_value Process::GetEUid(napi_env env) const
{
napi_value result = nullptr;
auto processGeteuid = static_cast<uint32_t>(geteuid());
NAPI_CALL(env, napi_create_uint32(env, processGeteuid, &result));
return result;
}
napi_value Process::GetEGid(napi_env env) const
{
napi_value result = nullptr;
auto processGetegid = static_cast<uint32_t>(getegid());
NAPI_CALL(env, napi_create_uint32(env, processGetegid, &result));
return result;
}
napi_value Process::GetGroups(napi_env env) const
{
napi_value result = nullptr;
int progroups = getgroups(0, nullptr);
if (progroups == -1) {
napi_throw_error(env, "-1", "getgroups initialize failed");
}
std::vector<gid_t> pgrous(progroups);
progroups = getgroups(progroups, pgrous.data());
if (progroups == -1) {
napi_throw_error(env, "-1", "getgroups");
}
pgrous.resize(static_cast<size_t>(progroups));
gid_t proegid = getegid();
if (std::find(pgrous.begin(), pgrous.end(), proegid) == pgrous.end()) {
pgrous.push_back(proegid);
}
std::vector<uint32_t> array;
for (auto iter = pgrous.begin(); iter != pgrous.end(); iter++) {
auto receive = static_cast<uint32_t>(*iter);
array.push_back(receive);
}
NAPI_CALL(env, napi_create_array(env, &result));
size_t len = array.size();
for (size_t i = 0; i < len; i++) {
napi_value numvalue = nullptr;
NAPI_CALL(env, napi_create_uint32(env, array[i], &numvalue));
NAPI_CALL(env, napi_set_element(env, result, i, numvalue));
}
return result;
}
napi_value Process::GetPid(napi_env env) const
{
napi_value result = nullptr;
auto proPid = static_cast<int32_t>(getpid());
napi_create_int32(env, proPid, &result);
return result;
}
napi_value Process::GetPpid(napi_env env) const
{
napi_value result = nullptr;
auto proPpid = static_cast<int32_t>(getppid());
napi_create_int32(env, proPpid, &result);
return result;
}
void Process::Chdir(napi_env env, napi_value args) const
{
size_t prolen = 0;
if (napi_get_value_string_utf8(env, args, nullptr, 0, &prolen) != napi_ok) {
HILOG_ERROR("can not get args size");
return;
}
std::string result = "";
result.reserve(prolen + 1);
result.resize(prolen);
if (napi_get_value_string_utf8(env, args, result.data(), prolen + 1, &prolen) != napi_ok) {
HILOG_ERROR("can not get args value");
return;
}
int proerr = 0;
proerr = uv_chdir(result.c_str());
if (proerr) {
napi_throw_error(env, "-1", "chdir");
}
}
napi_value Process::Kill(napi_env env, napi_value signal, napi_value proid)
{
int32_t pid = 0;
int32_t sig = 0;
napi_get_value_int32(env, proid, &pid);
napi_get_value_int32(env, signal, &sig);
uv_pid_t ownPid = uv_os_getpid();
// 64:The maximum valid signal value is 64.
if (sig > 64 && (!pid || pid == -1 || pid == ownPid || pid == -ownPid)) {
napi_throw_error(env, "0", "process exit");
}
bool flag = false;
int err = uv_kill(pid, sig);
if (!err) {
flag = true;
}
napi_value result = nullptr;
NAPI_CALL(env, napi_get_boolean(env, flag, &result));
return result;
}
napi_value Process::Uptime(napi_env env) const
{
napi_value result = nullptr;
struct sysinfo information = {0};
time_t systimer = 0;
double runsystime = 0.0;
if (sysinfo(&information)) {
napi_throw_error(env, "-1", "Failed to get sysinfo");
}
systimer = information.uptime;
if (systimer > 0) {
runsystime = static_cast<double>(systimer);
NAPI_CALL(env, napi_create_double(env, runsystime, &result));
} else {
napi_throw_error(env, "-1", "Failed to get systimer");
}
return result;
}
void Process::Exit(napi_env env, napi_value number) const
{
int32_t result = 0;
napi_get_value_int32(env, number, &result);
exit(result);
}
napi_value Process::Cwd(napi_env env) const
{
napi_value result = nullptr;
char buf[260 * NUM_OF_DATA] = { 0 }; // 260:Only numbers path String size is 260.
size_t length = sizeof(buf);
int err = uv_cwd(buf, &length);
if (err) {
napi_throw_error(env, "1", "uv_cwd");
}
napi_create_string_utf8(env, buf, length, &result);
return result;
}
void Process::Abort() const
{
exit(0);
}
void Process::On(napi_env env, napi_value str, napi_value function)
{
std::string result = "";
size_t bufferSize = 0;
if (napi_get_value_string_utf8(env, str, nullptr, NAPI_RETURN_ZERO, &bufferSize) != napi_ok) {
HILOG_ERROR("can not get str size");
return;
}
result.reserve(bufferSize + NAPI_RETURN_ONE);
result.resize(bufferSize);
if (napi_get_value_string_utf8(env, str, result.data(), bufferSize + NAPI_RETURN_ONE,
&bufferSize) != napi_ok) {
HILOG_ERROR("can not get str value");
return;
}
if (function == nullptr) {
HILOG_ERROR("function is nullptr");
return;
}
napi_ref myCallRef = nullptr;
napi_status status = napi_create_reference(env, function, 1, &myCallRef);
if (status != napi_ok) {
HILOG_ERROR("napi_create_reference is failed");
return;
}
if (!result.empty()) {
size_t pos = events.find(result);
if (pos == std::string::npos) {
HILOG_ERROR("illegal event");
return;
}
eventMap.insert(std::make_pair(result, myCallRef));
}
}
napi_value Process::Off(napi_env env, napi_value str)
{
size_t bufferSize = 0;
bool flag = false;
if (napi_get_value_string_utf8(env, str, nullptr, 0, &bufferSize) != napi_ok) {
HILOG_ERROR("can not get str size");
return nullptr;
}
std::string result = "";
result.reserve(bufferSize + 1);
result.resize(bufferSize);
if (napi_get_value_string_utf8(env, str, result.data(), bufferSize + 1, &bufferSize) != napi_ok) {
HILOG_ERROR("can not get str value");
return nullptr;
}
std::string temp = "";
temp = result;
auto iter = eventMap.equal_range(temp);
while (iter.first != iter.second) {
NAPI_CALL(env, napi_delete_reference(env, iter.first->second));
iter.first = eventMap.erase(iter.first);
flag = true;
}
napi_value convertResult = nullptr;
NAPI_CALL(env, napi_get_boolean(env, flag, &convertResult));
return convertResult;
}
napi_value Process::GetTid(napi_env env) const
{
napi_value result = nullptr;
auto proTid = static_cast<int32_t>(gettid());
napi_create_int32(env, proTid, &result);
return result;
}
napi_value Process::IsIsolatedProcess(napi_env env) const
{
napi_value result = nullptr;
bool flag = true;
auto prouid = static_cast<int32_t>(getuid());
auto uid = prouid % PER_USER_RANGE;
if ((uid >= 99000 && uid <= 99999) || // 99999:Only isolateuid numbers between 99000 and 99999.
(uid >= 9000 && uid <= 98999)) { // 98999:Only appuid numbers between 9000 and 98999.
NAPI_CALL(env, napi_get_boolean(env, flag, &result));
return result;
}
flag = false;
NAPI_CALL(env, napi_get_boolean(env, flag, &result));
return result;
}
napi_value Process::IsAppUid(napi_env env, napi_value uid) const
{
int32_t number = 0;
napi_value result = nullptr;
bool flag = true;
napi_get_value_int32(env, uid, &number);
if (number > 0) {
const auto appId = number % PER_USER_RANGE;
if (appId >= FIRST_APPLICATION_UID && appId <= LAST_APPLICATION_UID) {
napi_get_boolean(env, flag, &result);
return result;
}
flag = false;
NAPI_CALL(env, napi_get_boolean(env, flag, &result));
return result;
} else {
flag = false;
NAPI_CALL(env, napi_get_boolean(env, flag, &result));
return result;
}
}
napi_value Process::Is64Bit(napi_env env) const
{
napi_value result = nullptr;
bool flag = true;
auto size = sizeof(char*);
flag = (size == NUM_OF_DATA) ? false : true;
NAPI_CALL(env, napi_get_boolean(env, flag, &result));
return result;
}
napi_value Process::GetEnvironmentVar(napi_env env, napi_value name) const
{
napi_value convertResult = nullptr;
char buf[260 * NUM_OF_DATA] = { 0 }; // 260:Only numbers path String size is 260.
size_t length = sizeof(buf);
size_t bufferSize = 0;
if (napi_get_value_string_utf8(env, name, nullptr, 0, &bufferSize) != napi_ok) {
HILOG_ERROR("can not get name size");
return nullptr;
}
std::string result = "";
result.reserve(bufferSize + 1);
result.resize(bufferSize);
if (napi_get_value_string_utf8(env, name, result.data(), bufferSize + 1, &bufferSize) != napi_ok) {
HILOG_ERROR("can not get name value");
return nullptr;
}
std::string temp = "";
temp = result;
auto envNum = uv_os_getenv(temp.c_str(), buf, &length);
if (envNum == UV_ENOENT) {
NAPI_CALL(env, napi_get_undefined(env, &convertResult));
return convertResult;
}
napi_create_string_utf8(env, buf, strlen(buf), &convertResult);
return convertResult;
}
napi_value Process::GetUidForName(napi_env env, napi_value name) const
{
struct passwd *user = nullptr;
int32_t uid = 0;
napi_value convertResult = nullptr;
size_t bufferSize = 0;
if (napi_get_value_string_utf8(env, name, nullptr, 0, &bufferSize) != napi_ok) {
HILOG_ERROR("can not get name size");
return nullptr;
}
std::string result = "";
result.reserve(bufferSize + 1);
result.resize(bufferSize);
if (napi_get_value_string_utf8(env, name, result.data(), bufferSize + 1, &bufferSize) != napi_ok) {
HILOG_ERROR("can not get name value");
return nullptr;
}
std::string temp = "";
temp = result;
user = getpwnam(temp.c_str());
if (user != nullptr) {
uid = static_cast<int32_t>(user->pw_uid);
napi_create_int32(env, uid, &convertResult);
return convertResult;
}
napi_create_int32(env, (-1), &convertResult);
return convertResult;
}
napi_value Process::GetThreadPriority(napi_env env, napi_value tid) const
{
errno = 0;
int32_t proTid = 0;
napi_value result = nullptr;
napi_get_value_int32(env, tid, &proTid);
int32_t pri = getpriority(PRIO_PROCESS, proTid);
if (errno) {
napi_throw_error(env, "-1", "Invalid tid");
}
napi_create_int32(env, pri, &result);
return result;
}
napi_value Process::GetStartRealtime(napi_env env) const
{
struct timespec timespro = {0, 0};
struct timespec timessys = {0, 0};
napi_value result = nullptr;
auto res = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &timespro);
if (res) {
return 0;
}
auto res1 = clock_gettime(CLOCK_MONOTONIC, &timessys);
if (res1) {
return 0;
}
int whenpro = ConvertTime(timespro.tv_sec, timespro.tv_nsec);
int whensys = ConvertTime(timessys.tv_sec, timessys.tv_nsec);
auto timedif = (whensys - whenpro);
napi_create_int32(env, timedif, &result);
return result;
}
int Process::ConvertTime(time_t tvsec, int64_t tvnsec) const
{
return int(tvsec * 1000) + int(tvnsec / 1000000); // 98999:Only converttime numbers is 1000 and 1000000.
}
napi_value Process::GetPastCputime(napi_env env) const
{
struct timespec times = {0, 0};
napi_value result = nullptr;
auto res = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &times);
if (res) {
return 0;
}
int when = ConvertTime(times.tv_sec, times.tv_nsec);
napi_create_int32(env, when, &result);
return result;
}
napi_value Process::GetSystemConfig(napi_env env, napi_value name) const
{
int32_t number = 0;
napi_value result = nullptr;
napi_get_value_int32(env, name, &number);
auto configinfo = static_cast<int32_t>(sysconf(number));
napi_create_int32(env, configinfo, &result);
return result;
}
napi_value UnHandle(napi_env env, napi_value promise, napi_value reason)
{
napi_ref promiseRef = nullptr;
NAPI_CALL(env, napi_create_reference(env, promise, 1, &promiseRef));
napi_ref reasonRef = nullptr;
NAPI_CALL(env, napi_create_reference(env, reason, 1, &reasonRef));
pendingUnHandledRejections.insert(std::make_pair(promiseRef, reasonRef));
napi_value res = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &res));
return res;
}
napi_value AddHandle(napi_env env, napi_value promise)
{
auto iter = pendingUnHandledRejections.begin();
while (iter != pendingUnHandledRejections.end()) {
napi_value prom = nullptr;
NAPI_CALL(env, napi_get_reference_value(env, iter->first, &prom));
bool isEquals = false;
NAPI_CALL(env, napi_strict_equals(env, promise, prom, &isEquals));
if (isEquals) {
NAPI_CALL(env, napi_delete_reference(env, iter->first));
NAPI_CALL(env, napi_delete_reference(env, iter->second));
iter = pendingUnHandledRejections.erase(iter);
continue;
}
iter++;
}
napi_value res = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &res));
return res;
}
napi_value UnHandleRejection(napi_env env, napi_value promise, napi_value reason)
{
auto it = eventMap.find("UnHandleRejection");
if (it != eventMap.end()) {
napi_value global = nullptr;
NAPI_CALL(env, napi_get_global(env, &global));
size_t argc = 2; // 2 parameter size
napi_value args[] = {reason, promise};
auto iter = eventMap.equal_range("UnHandleRejection");
while (iter.first != iter.second) {
napi_value cb = nullptr;
NAPI_CALL(env, napi_get_reference_value(env, iter.first->second, &cb));
napi_value result = nullptr;
NAPI_CALL(env, napi_call_function(env, global, cb, argc, args, &result));
iter.first++;
}
}
napi_value res = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &res));
return res;
}
static napi_value OnUnHandleRejection(napi_env env, napi_callback_info info)
{
size_t argc = 3; // 3 parameter size
napi_value argv[3] = {0}; // 3 array length
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
int32_t event = 0;
NAPI_CALL(env, napi_get_value_int32(env, argv[0], &event));
if (event == static_cast<int32_t>(PromiseRejectionEvent::REJECT)) {
UnHandle(env, argv[1], argv[2]); // 2 array index
} else if (event == static_cast<int32_t>(PromiseRejectionEvent::HANDLE)) {
AddHandle(env, argv[1]);
}
napi_value res = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &res));
return res;
}
static napi_value CheckUnhandleRejections(napi_env env, napi_callback_info info)
{
if (!pendingUnHandledRejections.empty()) {
auto iter = pendingUnHandledRejections.begin();
while (iter != pendingUnHandledRejections.end()) {
napi_value promise = nullptr;
NAPI_CALL(env, napi_get_reference_value(env, iter->first, &promise));
napi_value reason = nullptr;
NAPI_CALL(env, napi_get_reference_value(env, iter->second, &reason));
UnHandleRejection(env, promise, reason);
NAPI_CALL(env, napi_delete_reference(env, iter->first));
NAPI_CALL(env, napi_delete_reference(env, iter->second));
iter = pendingUnHandledRejections.erase(iter);
}
}
napi_value res = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &res));
return res;
}
napi_value Process::SetRejectionCallback(napi_env env) const
{
napi_value cb = nullptr;
std::string callbackName = "onUnHandleRejection";
NAPI_CALL(env, napi_create_function(env, callbackName.c_str(), callbackName.size(), OnUnHandleRejection,
nullptr, &cb));
napi_ref unHandleRejectionCallbackRef = nullptr;
NAPI_CALL(env, napi_create_reference(env, cb, 1, &unHandleRejectionCallbackRef));
napi_ref checkUnhandleRejectionsRef = nullptr;
napi_value checkcb = nullptr;
std::string cbName = "CheckUnhandleRejections";
NAPI_CALL(env, napi_create_function(env, cbName.c_str(), cbName.size(), CheckUnhandleRejections,
nullptr, &checkcb));
NAPI_CALL(env, napi_create_reference(env, checkcb, 1, &checkUnhandleRejectionsRef));
napi_value res = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &res));
return res;
}
void Process::ClearReference(napi_env env)
{
auto iter = eventMap.begin();
while (iter != eventMap.end()) {
napi_status status = napi_delete_reference(env, iter->second);
if (status != napi_ok) {
napi_throw_error(env, nullptr, "ClearReference failed");
}
iter++;
}
eventMap.clear();
}
} // namespace OHOS::Js_sys_module::Process

View File

@ -0,0 +1,246 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PROCESS_JS_PROCESS_H_
#define PROCESS_JS_PROCESS_H_
#include <cstring>
#include <map>
#include <sys/time.h>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
namespace OHOS::Js_sys_module::Process {
using ClearRefCallback = void (*)(napi_env env);
enum class PromiseRejectionEvent : uint32_t { REJECT = 0, HANDLE };
class Process {
public:
/**
* Create process object
*/
explicit Process() {}
/**
* Process destructor.
*/
virtual ~Process() {}
/**
* Get process uid.
*
* @param env The parameter is NAPI environment variables.
*/
napi_value GetUid(napi_env env) const;
/**
* Get the user ID of the process.
*
* @param env The parameter is NAPI environment variables.
*/
napi_value GetGid(napi_env env) const;
/**
* Get the effective user identity of the process.
*
* @param env The parameter is NAPI environment variables.
*/
napi_value GetEUid(napi_env env) const;
/**
* Get the effective group ID of the process.
*
* @param env The parameter is NAPI environment variables.
*/
napi_value GetEGid(napi_env env) const;
/**
* Get an array with supplementary group ids.
*
* @param env The parameter is NAPI environment variables.s
*/
napi_value GetGroups(napi_env env) const;
/**
* Get the pid of the current process.
*
* @param env The parameter is NAPI environment variables.
*/
napi_value GetPid(napi_env env) const;
/**
* Get the pid of the parent process of the current process.
*
* @param env The parameter is NAPI environment variables.
*/
napi_value GetPpid(napi_env env) const;
/**
* Change the current working directory of the process.
*
* @param env The parameter is NAPI environment variables.
* @param args The parameter is the path.
*/
void Chdir(napi_env env, napi_value args) const;
/**
* Get the number of seconds the current system has been running.
*
* @param env The parameter is NAPI environment variables.
*/
napi_value Uptime(napi_env env) const;
/**
* Send a signal to the specified process and end the specified process.
*
* @param env The parameter is NAPI environment variables.
* @param signal The parameter is the signal sent.
* @param proid The parameter is the id of the process.
*/
napi_value Kill(napi_env env, napi_value signal, napi_value proid);
/**
* Causes the process to exit immediately and generate a core file.
*/
void Abort() const;
/**
* Store user-triggered events.
*
* @param env The parameter is NAPI environment variables.
* @param str The parameter is type of storage event.
* @param function The parameter is callback event.
*/
void On(napi_env env, napi_value str, napi_value function);
/**
* Delete user-stored events.
*
* @param env The parameter is NAPI environment variables.
* @param str The parameter is the type of delete event.
*/
napi_value Off(napi_env env, napi_value str);
/**
* Terminate the program.
*
* @param env The parameter is NAPI environment variables.
* @param number The parameter is the exit code of the process.
*/
void Exit(napi_env env, napi_value number) const;
/**
* Use this method to get the working directory of the process.
*
* @param env The parameter is NAPI environment variables.
*/
napi_value Cwd(napi_env env) const;
/**
* Get the tid of the current process.
*
* @param env The parameter is NAPI environment variables.
*/
napi_value GetTid(napi_env env) const;
/**
* Determines whether the process is isolated.
*
* @param env The parameter is NAPI environment variables.
*/
napi_value IsIsolatedProcess(napi_env env) const;
/**
* Determine whether the uid belongs to the application.
*
* @param env The parameter is NAPI environment variables.
* @param uid The parameter is the uid of the application.
*/
napi_value IsAppUid(napi_env env, napi_value uid) const;
/**
* Determine whether the operating environment is 64-bit.
*
* @param env The parameter is NAPI environment variables.
*/
napi_value Is64Bit(napi_env env) const;
/**
* Get process uid by process name.
*
* @param env The parameter is NAPI environment variables.
* @param name The parameter is the process name.
*/
napi_value GetUidForName(napi_env env, napi_value name) const;
/**
* Get thread priority based on specified tid.
*
* @param env The parameter is NAPI environment variables.
* @param tid The parameter is the specified thread tid.
*/
napi_value GetThreadPriority(napi_env env, napi_value tid) const;
/**
* Get the real-time elapsed time from system startup to process startup.
*/
napi_value GetStartRealtime(napi_env env) const;
/**
* Get the CPU time from the process startup to the current time.
*
* @param env The parameter is NAPI environment variables.
*/
napi_value GetPastCputime(napi_env env) const;
/**
* Get system configuration information.
*
* @param env The parameter is NAPI environment variables.
* @param name The parameter is the name of the specified system configuration parameter.
*/
napi_value GetSystemConfig(napi_env env, napi_value name) const;
/**
* Use this method to get the value corresponding to the environment variable.
*
* @param env The parameter is NAPI environment variables.
* @param name The parameter is the environment variable name.
*/
napi_value GetEnvironmentVar(napi_env env, napi_value name) const;
/**
* Set reject callback.
*
* @param env The parameter is NAPI environment variables.
*/
napi_value SetRejectionCallback(napi_env env) const;
/**
* Clear references to callbacks.
*
* @param env The parameter is NAPI environment variables.
*/
static void ClearReference(napi_env env);
private:
int ConvertTime(time_t tvsec, int64_t tvnsec) const;
private:
int FIRST_APPLICATION_UID = 10000;
int LAST_APPLICATION_UID = 19999;
};
} // namespace OHOS::Js_sys_module::Process
#endif // PROCESS_JS_PROCESS_H_

View File

@ -0,0 +1,568 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cassert>
#include <vector>
#include <grp.h>
#include <sys/types.h>
#include <unistd.h>
#include "js_childprocess.h"
#include "js_process.h"
#include "securec.h"
#include "utils/log.h"
namespace OHOS::Js_sys_module::Process {
static napi_value DealType(napi_env env, napi_value args[], size_t argsSize)
{
if (args[0] != nullptr) {
napi_valuetype valueType = napi_undefined;
NAPI_CALL(env, napi_typeof(env, args[0], &valueType));
NAPI_ASSERT(env, valueType == napi_string, "Wrong argument typr. String expected");
} else {
HILOG_ERROR("command is null");
NAPI_CALL(env, napi_throw_error(env, "", "command is empty"));
}
std::vector<std::string> keyStr = {"timeout", "killSignal", "maxBuffer"};
if (args[1] == nullptr) {
return nullptr;
}
size_t size = keyStr.size();
for (size_t i = 0; i < size; i++) {
napi_valuetype propertyType = napi_undefined;
napi_value property = nullptr;
NAPI_CALL(env, napi_get_named_property(env, args[1], keyStr[i].c_str(), &property));
switch (i) {
case 0:
{
NAPI_CALL(env, napi_typeof(env, property, &propertyType));
NAPI_ASSERT(env, propertyType == napi_number || propertyType == napi_undefined,
"Wrong timeout argument typr. Number expected");
int timeout = 0;
NAPI_CALL(env, napi_get_value_int32(env, property, &timeout));
if (timeout < 0) {
NAPI_CALL(env, napi_throw_error(env, "", "options timeout is lessthen zero"));
}
break;
}
case 1:
NAPI_CALL(env, napi_typeof(env, property, &propertyType));
NAPI_ASSERT(env, propertyType == napi_string || propertyType == napi_number
|| propertyType == napi_undefined,
"Wrong KillSignal argument typr. String or number expected");
break;
case 2: // 2:The parameter value
NAPI_CALL(env, napi_typeof(env, property, &propertyType));
NAPI_ASSERT(env, propertyType == napi_number || propertyType == napi_undefined,
"Wrong maxBuffer argument typr. Number expected");
break;
default:
break;
}
}
return nullptr;
}
static napi_value ChildProcessConstructor(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
void* data = nullptr;
size_t argc = 2;
napi_value args[2] = { nullptr };
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, &data));
DealType(env, args, argc);
auto objectInfo = new ChildProcess();
objectInfo->InitOptionsInfo(env, args[1]);
objectInfo->Spawn(env, args[0]);
NAPI_CALL(env, napi_wrap(
env, thisVar, objectInfo,
[](napi_env env, void* data, void* hint) {
auto objectResult = reinterpret_cast<ChildProcess*>(data);
if (objectResult != nullptr) {
delete objectResult;
objectResult = nullptr;
}
},
nullptr, nullptr));
return thisVar;
}
static napi_value Wait(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
ChildProcess* object = nullptr;
NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
napi_value result = object->Wait(env);
return result;
}
static napi_value GetOutput(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
ChildProcess* object = nullptr;
NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
napi_value result = object->GetOutput(env);
return result;
}
static napi_value Close(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
ChildProcess* object = nullptr;
NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
object->Close();
napi_value result = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &result));
return result;
}
static napi_value GetErrorOutput(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
ChildProcess* object = nullptr;
NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
napi_value result = object->GetErrorOutput(env);
return result;
}
static napi_value Kill(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
size_t requireArgc = 1;
size_t argc = 1;
napi_value args = nullptr;
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr));
NAPI_ASSERT(env, argc >= requireArgc, "Wrong number of arguments");
napi_valuetype valuetype;
NAPI_CALL(env, napi_typeof(env, args, &valuetype));
if ((valuetype != napi_valuetype::napi_number) && (valuetype != napi_valuetype::napi_string)) {
napi_throw_error(env, nullptr, "The parameter type is incorrect");
}
ChildProcess* object = nullptr;
NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
object->Kill(env, args);
napi_value result = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &result));
return result;
}
static napi_value GetKilled(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
ChildProcess* object = nullptr;
NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
napi_value result = object->GetKilled(env);
return result;
}
static napi_value Getpid(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
ChildProcess* object = nullptr;
NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
napi_value result = object->Getpid(env);
return result;
}
static napi_value Getppid(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
ChildProcess* object = nullptr;
NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
napi_value result = object->Getppid(env);
return result;
}
static napi_value GetExitCode(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
ChildProcess* object = nullptr;
NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
napi_value result = object->GetExitCode(env);
return result;
}
static napi_value RunCommand(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
size_t argc = 2;
napi_value args[2] = { nullptr };
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
const char* childProcessClassName = "ChildProcess";
napi_value childProcessClass = nullptr;
napi_property_descriptor childProcessDesc[] = {
DECLARE_NAPI_FUNCTION("close", Close),
DECLARE_NAPI_FUNCTION("kill", Kill),
DECLARE_NAPI_FUNCTION("getOutput", GetOutput),
DECLARE_NAPI_FUNCTION("getErrorOutput", GetErrorOutput),
DECLARE_NAPI_FUNCTION("wait", Wait),
DECLARE_NAPI_GETTER("killed", GetKilled),
DECLARE_NAPI_GETTER("pid", Getpid),
DECLARE_NAPI_GETTER("ppid", Getppid),
DECLARE_NAPI_GETTER("exitCode", GetExitCode),
};
NAPI_CALL(env, napi_define_class(env, childProcessClassName, strlen(childProcessClassName),
ChildProcessConstructor, nullptr,
sizeof(childProcessDesc) / sizeof(childProcessDesc[0]), childProcessDesc,
&childProcessClass));
napi_value result = nullptr;
NAPI_CALL(env, napi_new_instance(env, childProcessClass, argc, args, &result));
return result;
}
static napi_value GetUid(napi_env env, [[maybe_unused]] napi_callback_info info)
{
Process object;
return object.GetUid(env);
}
static napi_value GetGid(napi_env env, [[maybe_unused]] napi_callback_info info)
{
Process object;
return object.GetGid(env);
}
static napi_value GetEUid(napi_env env, [[maybe_unused]] napi_callback_info info)
{
Process object;
return object.GetEUid(env);
}
static napi_value GetEGid(napi_env env, [[maybe_unused]] napi_callback_info info)
{
Process object;
return object.GetEGid(env);
}
static napi_value GetGroups(napi_env env, [[maybe_unused]] napi_callback_info info)
{
Process object;
return object.GetGroups(env);
}
static napi_value GetPid(napi_env env, [[maybe_unused]] napi_callback_info info)
{
Process object;
return object.GetPid(env);
}
static napi_value GetPpid(napi_env env, [[maybe_unused]] napi_callback_info info)
{
Process object;
return object.GetPpid(env);
}
static napi_value Chdir(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
size_t requireArgc = 1;
size_t argc = 1;
napi_value args = nullptr;
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr));
NAPI_ASSERT(env, argc >= requireArgc, "Wrong nuamber of arguments");
napi_valuetype valuetype;
NAPI_CALL(env, napi_typeof(env, args, &valuetype));
NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument type. String expected");
Process object;
object.Chdir(env, args);
napi_value result = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &result));
return result;
}
static napi_value Abort(napi_env env, [[maybe_unused]] napi_callback_info info)
{
Process object;
object.Abort();
napi_value res = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &res));
return res;
}
static napi_value Cwd(napi_env env, [[maybe_unused]] napi_callback_info info)
{
Process object;
return object.Cwd(env);
}
static napi_value Exit(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
size_t argc = 1;
napi_value args = nullptr;
napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr);
napi_valuetype valuetype;
NAPI_CALL(env, napi_typeof(env, args, &valuetype));
NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type.number error");
Process object;
object.Exit(env, args);
napi_value res = nullptr;
NAPI_CALL(env, napi_get_undefined(env, &res));
return res;
}
static napi_value On(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
bool flag = true;
napi_value result = nullptr;
size_t requireArgc = 2;
size_t argc = 2;
napi_value args[2] = { nullptr };
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
NAPI_ASSERT(env, argc >= requireArgc, "Wrong number of arguments");
napi_valuetype valuetype0;
NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0));
if (valuetype0 != napi_valuetype::napi_string) {
flag = false;
NAPI_CALL(env, napi_get_boolean(env, flag, &result));
return result;
}
napi_valuetype valuetype1;
NAPI_CALL(env, napi_typeof(env, args[1], &valuetype1));
Process object;
object.On(env, args[0], args[1]);
NAPI_CALL(env, napi_get_boolean(env, flag, &result));
return result;
}
static napi_value Off(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
size_t argc = 1;
napi_value args = nullptr;
napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr);
Process object;
napi_value result = object.Off(env, args);
return result;
}
static napi_value Uptime(napi_env env, [[maybe_unused]] napi_callback_info info)
{
Process object;
return object.Uptime(env);
}
static napi_value KillSig(napi_env env, napi_callback_info info)
{
size_t argc = 2;
napi_value argv[2] = {0};
napi_value thisVar = nullptr;
void* data = nullptr;
napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
Process object;
napi_value result = nullptr;
result = object.Kill(env, argv[0], argv[1]);
return result;
}
static napi_value GetTid(napi_env env, [[maybe_unused]] napi_callback_info info)
{
Process object;
return object.GetTid(env);
}
static napi_value IsIsolatedProcess(napi_env env, [[maybe_unused]] napi_callback_info info)
{
Process object;
return object.IsIsolatedProcess(env);
}
static napi_value IsAppUid(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
size_t argc = 1;
napi_value args = nullptr;
napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr);
napi_valuetype valuetype;
NAPI_CALL(env, napi_typeof(env, args, &valuetype));
NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type.String error");
Process object;
return object.IsAppUid(env, args);
}
static napi_value Is64Bit(napi_env env, [[maybe_unused]] napi_callback_info info)
{
Process object;
return object.Is64Bit(env);
}
static napi_value GetUidForName(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
size_t argc = 1;
napi_value args = nullptr;
napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr);
napi_valuetype valuetype;
NAPI_CALL(env, napi_typeof(env, args, &valuetype));
NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument type.String error");
Process object;
return object.GetUidForName(env, args);
}
static napi_value GetThreadPriority(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
size_t argc = 1;
napi_value args = nullptr;
napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr);
napi_valuetype valuetype;
NAPI_CALL(env, napi_typeof(env, args, &valuetype));
NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type.String error");
Process object;
return object.GetThreadPriority(env, args);
}
static napi_value GetStartRealtime(napi_env env, [[maybe_unused]] napi_callback_info info)
{
Process object;
return object.GetStartRealtime(env);
}
static napi_value GetPastCputime(napi_env env, [[maybe_unused]] napi_callback_info info)
{
Process object;
return object.GetPastCputime(env);
}
static napi_value GetSystemConfig(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
size_t argc = 1;
napi_value args = nullptr;
napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr);
napi_valuetype valuetype;
NAPI_CALL(env, napi_typeof(env, args, &valuetype));
NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type.String error");
Process object;
return object.GetSystemConfig(env, args);
}
static napi_value GetEnvironmentVar(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
size_t argc = 1;
napi_value args = nullptr;
napi_get_cb_info(env, info, &argc, &args, &thisVar, nullptr);
napi_valuetype valuetype;
NAPI_CALL(env, napi_typeof(env, args, &valuetype));
NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument type.String error");
Process object;
return object.GetEnvironmentVar(env, args);
}
static napi_value Init(napi_env env, napi_value exports)
{
Process object;
object.SetRejectionCallback(env);
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("runCmd", RunCommand),
DECLARE_NAPI_GETTER("uid", GetUid),
DECLARE_NAPI_GETTER("gid", GetGid),
DECLARE_NAPI_GETTER("euid", GetEUid),
DECLARE_NAPI_GETTER("egid", GetEGid),
DECLARE_NAPI_GETTER("groups", GetGroups),
DECLARE_NAPI_GETTER("pid", GetPid),
DECLARE_NAPI_GETTER("ppid", GetPpid),
DECLARE_NAPI_FUNCTION("uptime", Uptime),
DECLARE_NAPI_FUNCTION("kill", KillSig),
DECLARE_NAPI_FUNCTION("chdir", Chdir),
DECLARE_NAPI_FUNCTION("abort", Abort),
DECLARE_NAPI_FUNCTION("cwd", Cwd),
DECLARE_NAPI_FUNCTION("on", On),
DECLARE_NAPI_FUNCTION("off", Off),
DECLARE_NAPI_FUNCTION("exit", Exit),
DECLARE_NAPI_GETTER("tid", GetTid),
DECLARE_NAPI_FUNCTION("getStartRealtime", GetStartRealtime),
DECLARE_NAPI_FUNCTION("getPastCpuTime", GetPastCputime),
DECLARE_NAPI_FUNCTION("isIsolatedProcess", IsIsolatedProcess),
DECLARE_NAPI_FUNCTION("is64Bit", Is64Bit),
DECLARE_NAPI_FUNCTION("isAppUid", IsAppUid),
DECLARE_NAPI_FUNCTION("getUidForName", GetUidForName),
DECLARE_NAPI_FUNCTION("getThreadPriority", GetThreadPriority),
DECLARE_NAPI_FUNCTION("getSystemConfig", GetSystemConfig),
DECLARE_NAPI_FUNCTION("getEnvironmentVar", GetEnvironmentVar),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
napi_value obj = nullptr;
NAPI_CALL(env, napi_create_object(env, &obj));
NAPI_CALL(env, napi_wrap(
env, obj, reinterpret_cast<void*>(Process::ClearReference),
[](napi_env env, void* data, void* hint) {
if (data != nullptr) {
ClearRefCallback clearParameters = reinterpret_cast<ClearRefCallback>(data);
clearParameters(env);
}
},
nullptr, nullptr));
NAPI_CALL(env, napi_set_named_property(env, exports, "obj", obj));
return exports;
}
static napi_module processModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = Init,
.nm_modname = "process",
.nm_priv = reinterpret_cast<void*>(0),
.reserved = { 0 },
};
extern "C" __attribute__ ((constructor)) void RegisterModule()
{
napi_module_register(&processModule);
}
} // namespace OHOS::Js_sys_module::Process

View File

@ -0,0 +1,66 @@
# Copyright (c) 2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/test.gni")
if (is_standard_system) {
module_output_path = "jsapi_sys/process"
}
ohos_unittest("test_process_unittest") {
module_out_path = module_output_path
configs = [ "//arkcompiler/ets_runtime:ark_jsruntime_public_config" ]
include_dirs = [
"//base/compileruntime/js_sys_module/process",
"//arkcompiler/ets_runtime",
"//foundation/arkui/napi",
"//foundation/arkui/napi/interfaces/kits",
"//foundation/arkui/napi/native_engine",
"//foundation/arkui/napi/native_engine/impl/ark",
"//third_party/bounds_checking_function/include",
"//third_party/googletest/include",
"//third_party/node/src",
]
cflags = [ "-g3" ]
sources = [
"test_ark.cpp",
"test_process.cpp",
]
deps = [
"//arkcompiler/ets_runtime:libark_jsruntime",
"//base/compileruntime/js_sys_module/process:process_packages",
"//foundation/arkui/napi/:ace_napi",
"//foundation/arkui/napi/:ace_napi_ark",
"//third_party/bounds_checking_function:libsec_static",
"//third_party/googletest:gtest",
"//third_party/googletest:gtest_main",
"//third_party/icu/icu4c:static_icuuc",
"//third_party/libuv:uv_static",
"//utils/native/base:utils",
]
if (is_standard_system) {
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
} else {
external_deps = [ "hilog:libhilog" ]
}
}
group("unittest") {
testonly = true
deps = [ ":test_process_unittest" ]
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TEST_UNITTEST_TEST_H_
#define TEST_UNITTEST_TEST_H_
#include "native_engine.h"
#include "gtest/gtest.h"
class NativeEngineTest : public testing::Test {
public:
/**
* NativeEngineTest constructor.
*/
NativeEngineTest();
/**
* NativeEngineTest destructor.
*/
virtual ~NativeEngineTest();
/**
* Set function.
*/
void SetUp() override {}
/**
* TearDown function.
*/
void TearDown() override {}
protected:
NativeEngine *engine_;
};
#endif // TEST_UNITTEST_TEST_H_

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "test.h"
#include "utils/log.h"
#include "ark_native_engine.h"
using panda::RuntimeOption;
static NativeEngine *g_nativeEngine = nullptr;
NativeEngineTest::NativeEngineTest()
{
engine_ = g_nativeEngine;
}
NativeEngineTest::~NativeEngineTest() {}
int main(int argc, char **argv)
{
testing::GTEST_FLAG(output) = "xml:./";
testing::InitGoogleTest(&argc, argv);
// Setup
RuntimeOption option;
option.SetGcType(RuntimeOption::GC_TYPE::GEN_GC);
const int64_t poolSize = 0x1000000; // 16M
option.SetGcPoolSize(poolSize);
option.SetLogLevel(RuntimeOption::LOG_LEVEL::ERROR);
option.SetDebuggerLibraryPath("");
EcmaVM *vm = panda::JSNApi::CreateJSVM(option);
if (vm == nullptr) {
return 0;
}
g_nativeEngine = new ArkNativeEngine(vm, nullptr);
int ret = testing::UnitTest::GetInstance()->Run();
g_nativeEngine->Loop(LOOP_NOWAIT);
delete g_nativeEngine;
g_nativeEngine = nullptr;
panda::JSNApi::DestroyJSVM(vm);
vm = nullptr;
return ret;
}

View File

@ -0,0 +1,160 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <ctime>
#include "test.h"
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "securec.h"
#include "utils/log.h"
#include "js_childprocess.h"
#include "js_process.h"
#define ASSERT_CHECK_CALL(call) \
{ \
ASSERT_EQ(call, napi_ok); \
}
#define ASSERT_CHECK_VALUE_TYPE(env, value, type) \
{ \
napi_valuetype valueType = napi_undefined; \
ASSERT_TRUE(value != nullptr); \
ASSERT_CHECK_CALL(napi_typeof(env, value, &valueType)); \
ASSERT_EQ(valueType, type); \
}
static OHOS::Js_sys_module::Process::ChildProcess RunCommand(napi_env env, napi_value command, napi_value options)
{
OHOS::Js_sys_module::Process::ChildProcess objectInfo;
objectInfo.InitOptionsInfo(env, options);
objectInfo.Spawn(env, command);
return objectInfo;
}
/**
* @tc.name: ProcessUptimeTest001
* @tc.desc: Test process Uptime.
* @tc.type: FUNC
*/
HWTEST_F(NativeEngineTest, ProcessUptimeTest001, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)engine_;
OHOS::Js_sys_module::Process::Process process;
napi_value timeStart = process.Uptime(env);
sleep(1);
napi_value timeEnd = process.Uptime(env);
double start = 0;
double end = 0;
napi_get_value_double(env, timeStart, &start);
napi_get_value_double(env, timeEnd, &end);
ASSERT_EQ(end - start, 1);
}
/**
* @tc.name: ProcessKillTest001
* @tc.desc: Test process kill signal.
* @tc.type: FUNC
*/
HWTEST_F(NativeEngineTest, ProcessKillTest001, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)engine_;
OHOS::Js_sys_module::Process::Process process;
std::string command("ls; sleep 1");
napi_value temp = nullptr;
napi_create_string_utf8(env, command.c_str(), command.length(), &temp);
OHOS::Js_sys_module::Process::ChildProcess childprocess = RunCommand(env, temp, nullptr);
napi_value pid = childprocess.Getpid(env);
napi_value signal = nullptr;
napi_create_int32(env, 9, &signal);
napi_value result = process.Kill(env, pid, signal);
bool res = false;
napi_get_value_bool(env, result, &res);
ASSERT_TRUE(res);
}
/**
* @tc.name: ProcessKillTest002
* @tc.desc: Test process kill signal.
* @tc.type: FUNC
*/
HWTEST_F(NativeEngineTest, ProcessKillTest002, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)engine_;
OHOS::Js_sys_module::Process::Process process;
std::string command("ls; sleep 1");
napi_value temp = nullptr;
napi_create_string_utf8(env, command.c_str(), command.length(), &temp);
OHOS::Js_sys_module::Process::ChildProcess childprocess = RunCommand(env, temp, nullptr);
napi_value pid = childprocess.Getpid(env);
napi_value signal = nullptr;
napi_create_int32(env, 999, &signal);
napi_value result = process.Kill(env, pid, signal);
bool res = false;
napi_get_value_bool(env, result, &res);
ASSERT_FALSE(res);
}
/**
* @tc.name: ProcessRunCmdTest001
* @tc.desc: Test process RunCmd fork process.
* @tc.type: FUNC
*/
HWTEST_F(NativeEngineTest, ProcessRunCmdTest001, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)engine_;
OHOS::Js_sys_module::Process::Process process;
std::string command("each abc");
napi_value temp = nullptr;
napi_create_string_utf8(env, command.c_str(), command.length(), &temp);
OHOS::Js_sys_module::Process::ChildProcess childprocess = RunCommand(env, temp, nullptr);
napi_value output = childprocess.GetOutput(env);
bool res = false;
napi_is_promise(env, output, &res);
ASSERT_TRUE(res);
}
/**
* @tc.name: ProcessRunCmdTest002
* @tc.desc: Test process RunCmd fork process.
* @tc.type: FUNC
*/
HWTEST_F(NativeEngineTest, ProcessRunCmdTest002, testing::ext::TestSize.Level0)
{
napi_env env = (napi_env)engine_;
OHOS::Js_sys_module::Process::Process process;
std::string command("mkdir test.txt");
napi_value temp = nullptr;
napi_create_string_utf8(env, command.c_str(), command.length(), &temp);
OHOS::Js_sys_module::Process::ChildProcess childprocess = RunCommand(env, temp, nullptr);
napi_value errorOutput = childprocess.GetErrorOutput(env);
bool res = false;
napi_is_promise(env, errorOutput, &res);
ASSERT_TRUE(res);
}