@camjn/getargv 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/binding.d.ts +8 -0
- package/dist/binding.js +7 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +33 -0
- package/package.json +14 -3
- package/src/getargv.c +78 -56
- package/.github/workflows/node.yml +0 -44
- package/lib/binding.ts +0 -11
- package/test/test_binding.js +0 -24
- package/tsconfig.json +0 -17
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ After checking out the repo, run `npm i` to install dependencies. Then, run `npm
|
|
|
25
25
|
|
|
26
26
|
TS code goes in the `lib` dir, C code goes in the `src` dir.
|
|
27
27
|
|
|
28
|
-
To install this module onto your local machine, run `npm install`. To release a new version, run `npm version patch` to update the version number in `package.json` and create a git tag for the version, and push git commits and the created tag to the git origin; and then run `npm publish`, which will push the module to npm
|
|
28
|
+
To install this module onto your local machine, run `npm install`. To release a new version, run `npm version patch` to update the version number in `package.json` and create a git tag for the version, and push git commits and the created tag to the git origin; and then run `npm publish`, which will push the module to [npm](https://www.npmjs.com).
|
|
29
29
|
|
|
30
30
|
## Contributing
|
|
31
31
|
|
package/dist/binding.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const addon = require('../build/Release/getargv_native');
|
|
3
|
+
exports.PID_MAX = addon.PID_MAX;
|
|
4
|
+
exports.ARG_MAX = addon.ARG_MAX;
|
|
5
|
+
exports.get_argv_of_pid = addon.get_argv_of_pid;
|
|
6
|
+
exports.get_argv_and_argc_of_pid = addon.get_argv_and_argc_of_pid;
|
|
7
|
+
module.exports = addon;
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const { get_argv_of_pid } = require('./binding');
|
|
3
|
+
function exit(msg) {
|
|
4
|
+
console.error(msg);
|
|
5
|
+
process.exitCode = -1;
|
|
6
|
+
}
|
|
7
|
+
// [node, script] are first two args
|
|
8
|
+
if (process.argv.length < 3) {
|
|
9
|
+
exit("a pid argument is required");
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
const pid = Number.parseInt(process.argv.pop());
|
|
13
|
+
if (!Number.isInteger(pid)) {
|
|
14
|
+
exit("pid is not a number");
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
const nuls_index = process.argv.indexOf("-0");
|
|
18
|
+
const keep_nuls = nuls_index != -1;
|
|
19
|
+
if (keep_nuls)
|
|
20
|
+
process.argv.splice(nuls_index, 1);
|
|
21
|
+
const skip_index = process.argv.indexOf("-s");
|
|
22
|
+
let skip = 0;
|
|
23
|
+
if (skip_index > -1) {
|
|
24
|
+
skip = Number.parseInt(process.argv[skip_index + 1]);
|
|
25
|
+
if (!Number.isInteger(skip))
|
|
26
|
+
exit("argument to skip flag (-s) is not a number");
|
|
27
|
+
}
|
|
28
|
+
if (process.exitCode == undefined) {
|
|
29
|
+
const args = get_argv_of_pid(pid, !keep_nuls, skip);
|
|
30
|
+
process.stdout.write(args);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
package/package.json
CHANGED
|
@@ -16,15 +16,26 @@
|
|
|
16
16
|
"name": "@camjn/getargv",
|
|
17
17
|
"homepage": "https://getargv.narzt.cam/",
|
|
18
18
|
"author": "Camden Narzt <getargv@narzt.cam>",
|
|
19
|
-
"version": "0.0.
|
|
19
|
+
"version": "0.0.4",
|
|
20
20
|
"description": "This library allows you to query the arguments of other processes on macOS.",
|
|
21
|
-
"main": "
|
|
21
|
+
"main": "dist/binding.js",
|
|
22
22
|
"scripts": {
|
|
23
23
|
"build": "node-gyp configure build",
|
|
24
24
|
"pretest": "tsc",
|
|
25
25
|
"test": "node --napi-modules ./test/test_binding.js",
|
|
26
|
-
"
|
|
26
|
+
"precli": "tsc",
|
|
27
|
+
"prepack": "tsc",
|
|
28
|
+
"cli": "node dist/cli.js",
|
|
29
|
+
"console": "node --napi-modules -r ./build/Release/getargv_native -e 'const GetArgv = require.cache[Object.keys(require.cache)[0]].exports;' -i"
|
|
27
30
|
},
|
|
31
|
+
"files": [
|
|
32
|
+
"/README.md",
|
|
33
|
+
"/logo.svg",
|
|
34
|
+
"/dist",
|
|
35
|
+
"/src",
|
|
36
|
+
"/binding.gyp",
|
|
37
|
+
"/package.json"
|
|
38
|
+
],
|
|
28
39
|
"gypfile": true,
|
|
29
40
|
"repository": {
|
|
30
41
|
"type": "git",
|
package/src/getargv.c
CHANGED
|
@@ -1,45 +1,43 @@
|
|
|
1
1
|
#include <errno.h>
|
|
2
2
|
#include <libgetargv.h>
|
|
3
3
|
#include <node_api.h>
|
|
4
|
-
#include <stdint.h>
|
|
5
4
|
#include <stdlib.h>
|
|
6
5
|
#include <string.h>
|
|
7
|
-
#include <sys/
|
|
6
|
+
#include <sys/syslimits.h>
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
#define STR1(x) #x
|
|
9
|
+
#define STR2(x) STR1(x)
|
|
10
|
+
#define ARG_MAX_STR STR2(ARG_MAX)
|
|
11
|
+
|
|
12
|
+
napi_value get_undefined(napi_env env) {
|
|
13
|
+
napi_value undef;
|
|
14
|
+
if (napi_get_undefined(env, &undef) != napi_ok) {
|
|
13
15
|
napi_throw_error(env, "ERR_INTERNAL_ASSERTION",
|
|
14
|
-
"
|
|
16
|
+
"Unable to get 'undefined' constant");
|
|
15
17
|
}
|
|
18
|
+
return undef;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
napi_value create_system_error(napi_env env, errno_t err) {
|
|
22
|
+
//we skip checking status in here because we already have a failure
|
|
23
|
+
napi_value code;
|
|
24
|
+
napi_create_string_utf8(env, "ERR_SYSTEM_ERROR", NAPI_AUTO_LENGTH, &code);
|
|
16
25
|
|
|
17
26
|
napi_value msg;
|
|
18
|
-
|
|
19
|
-
napi_create_string_utf8(env, strerror(err), NAPI_AUTO_LENGTH, &msg)) {
|
|
20
|
-
napi_throw_error(env, "ERR_INTERNAL_ASSERTION",
|
|
21
|
-
"Failed to create String object");
|
|
22
|
-
}
|
|
27
|
+
napi_create_string_utf8(env, strerror(err), NAPI_AUTO_LENGTH, &msg);
|
|
23
28
|
|
|
24
29
|
napi_value error;
|
|
25
|
-
|
|
26
|
-
napi_throw_error(env, "ERR_INTERNAL_ASSERTION",
|
|
27
|
-
"Failed to create Error object");
|
|
28
|
-
}
|
|
30
|
+
napi_create_error(env, code, msg, &error);
|
|
29
31
|
|
|
30
32
|
napi_value value;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
napi_create_int32(env, err, &value);
|
|
34
|
+
|
|
35
|
+
napi_set_named_property(env, error, "errno", value);
|
|
34
36
|
|
|
35
|
-
if (napi_ok != napi_set_named_property(env, error, "errno", value)) {
|
|
36
|
-
napi_throw_error(env, "ERR_INTERNAL_ASSERTION",
|
|
37
|
-
"Failed to set property on Error object");
|
|
38
|
-
}
|
|
39
37
|
return error;
|
|
40
38
|
}
|
|
41
39
|
|
|
42
|
-
|
|
40
|
+
struct GetArgvOptions parseTripleArgs(napi_env env, napi_callback_info info) {
|
|
43
41
|
size_t argc = 3;
|
|
44
42
|
napi_value argv[argc];
|
|
45
43
|
|
|
@@ -83,37 +81,15 @@ napi_value GetArgvOfPid(napi_env env, napi_callback_info info) {
|
|
|
83
81
|
if (skip < 0 || skip > ARG_MAX) {
|
|
84
82
|
// or ERR_OUT_OF_RANGE
|
|
85
83
|
napi_throw_range_error(env, "ERR_INVALID_ARG_VALUE",
|
|
86
|
-
"Invalid number was passed as third argument"
|
|
84
|
+
"Invalid number was passed as third argument, "
|
|
85
|
+
"must be between 0 and " ARG_MAX_STR "");
|
|
87
86
|
}
|
|
88
87
|
}
|
|
89
|
-
|
|
90
|
-
napi_value args;
|
|
91
|
-
if (napi_get_undefined(env, &args) != napi_ok) {
|
|
92
|
-
napi_throw_error(env, "ERR_INTERNAL_ASSERTION",
|
|
93
|
-
"Unable to get 'undefined' constant");
|
|
94
|
-
}
|
|
95
88
|
struct GetArgvOptions options = {.pid = pid, .nuls = nuls, .skip = skip};
|
|
96
|
-
|
|
97
|
-
if (!get_argv_of_pid(&options, &result)) {
|
|
98
|
-
napi_value error = create_system_error(env, errno);
|
|
99
|
-
|
|
100
|
-
napi_throw(env, error);
|
|
101
|
-
} else {
|
|
102
|
-
if (napi_create_string_utf8(env, result.start_pointer,
|
|
103
|
-
result.end_pointer - result.start_pointer + 1,
|
|
104
|
-
&args) != napi_ok) {
|
|
105
|
-
// args not guaranteed to be utf8 or even latin1/ascii, but ruby, swift,
|
|
106
|
-
// and node all want strings to be properly encoded
|
|
107
|
-
napi_throw_error(env, "ERR_INTERNAL_ASSERTION",
|
|
108
|
-
"Unable to create return value");
|
|
109
|
-
}
|
|
110
|
-
free(result.buffer);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return args;
|
|
89
|
+
return options;
|
|
114
90
|
}
|
|
115
91
|
|
|
116
|
-
|
|
92
|
+
pid_t parseSingleArg(napi_env env, napi_callback_info info) {
|
|
117
93
|
size_t argc = 1;
|
|
118
94
|
napi_value argv[argc];
|
|
119
95
|
|
|
@@ -126,7 +102,7 @@ napi_value GetArgvAndArgcOfPid(napi_env env, napi_callback_info info) {
|
|
|
126
102
|
"The \"pid\" argument must be specified");
|
|
127
103
|
} else if (argc > 1) {
|
|
128
104
|
napi_throw_type_error(env, "ERR_TOO_MANY_ARGS",
|
|
129
|
-
"Too many arguments were provided, max:
|
|
105
|
+
"Too many arguments were provided, max: 1");
|
|
130
106
|
}
|
|
131
107
|
|
|
132
108
|
pid_t pid = 0;
|
|
@@ -140,11 +116,37 @@ napi_value GetArgvAndArgcOfPid(napi_env env, napi_callback_info info) {
|
|
|
140
116
|
"Invalid PID was passed as first argument");
|
|
141
117
|
}
|
|
142
118
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
119
|
+
return pid;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
napi_value GetArgvOfPid(napi_env env, napi_callback_info info) {
|
|
123
|
+
struct GetArgvOptions options = parseTripleArgs(env, info);
|
|
124
|
+
napi_value args = get_undefined(env);
|
|
125
|
+
|
|
126
|
+
struct ArgvResult result;
|
|
127
|
+
if (!get_argv_of_pid(&options, &result)) {
|
|
128
|
+
napi_value error = create_system_error(env, errno);
|
|
129
|
+
|
|
130
|
+
napi_throw(env, error);
|
|
131
|
+
} else {
|
|
132
|
+
if (napi_create_string_utf8(env, result.start_pointer,
|
|
133
|
+
result.end_pointer - result.start_pointer + 1,
|
|
134
|
+
&args) != napi_ok) {
|
|
135
|
+
// args not guaranteed to be utf8 or even latin1/ascii, but ruby, swift,
|
|
136
|
+
// and node all want strings to be properly encoded
|
|
137
|
+
napi_throw_error(env, "ERR_INTERNAL_ASSERTION",
|
|
138
|
+
"Unable to create return value");
|
|
139
|
+
}
|
|
140
|
+
free(result.buffer);
|
|
147
141
|
}
|
|
142
|
+
|
|
143
|
+
return args;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
napi_value GetArgvAndArgcOfPid(napi_env env, napi_callback_info info) {
|
|
147
|
+
pid_t pid = parseSingleArg(env, info);
|
|
148
|
+
napi_value args = get_undefined(env);
|
|
149
|
+
|
|
148
150
|
struct ArgvArgcResult result;
|
|
149
151
|
if (!get_argv_and_argc_of_pid(pid, &result)) {
|
|
150
152
|
napi_value error = create_system_error(env, errno);
|
|
@@ -180,7 +182,6 @@ napi_value GetArgvAndArgcOfPid(napi_env env, napi_callback_info info) {
|
|
|
180
182
|
}
|
|
181
183
|
|
|
182
184
|
napi_value Init(napi_env env, napi_value exports) {
|
|
183
|
-
// Module initialization code goes here
|
|
184
185
|
napi_value get_argv_of_pid_fn;
|
|
185
186
|
if (napi_create_function(env, "get_argv_of_pid", NAPI_AUTO_LENGTH,
|
|
186
187
|
GetArgvOfPid, NULL,
|
|
@@ -207,6 +208,27 @@ napi_value Init(napi_env env, napi_value exports) {
|
|
|
207
208
|
"Unable to populate exports");
|
|
208
209
|
}
|
|
209
210
|
|
|
211
|
+
napi_value pid_max_constant;
|
|
212
|
+
if (napi_create_uint32(env, _PID_MAX, &pid_max_constant) != napi_ok) {
|
|
213
|
+
napi_throw_error(env, "ERR_INTERNAL_ASSERTION",
|
|
214
|
+
"Unable to create constant");
|
|
215
|
+
}
|
|
216
|
+
if (napi_set_named_property(env, exports, "PID_MAX", pid_max_constant) !=
|
|
217
|
+
napi_ok) {
|
|
218
|
+
napi_throw_error(env, "ERR_INTERNAL_ASSERTION",
|
|
219
|
+
"Unable to populate exports");
|
|
220
|
+
}
|
|
221
|
+
napi_value arg_max_constant;
|
|
222
|
+
if (napi_create_uint32(env, ARG_MAX, &arg_max_constant) != napi_ok) {
|
|
223
|
+
napi_throw_error(env, "ERR_INTERNAL_ASSERTION",
|
|
224
|
+
"Unable to create constant");
|
|
225
|
+
}
|
|
226
|
+
if (napi_set_named_property(env, exports, "ARG_MAX", arg_max_constant) !=
|
|
227
|
+
napi_ok) {
|
|
228
|
+
napi_throw_error(env, "ERR_INTERNAL_ASSERTION",
|
|
229
|
+
"Unable to populate exports");
|
|
230
|
+
}
|
|
231
|
+
|
|
210
232
|
return exports;
|
|
211
233
|
}
|
|
212
234
|
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
name: Node.js
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [ "main" ]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [ "main" ]
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
build:
|
|
11
|
-
runs-on: macos-latest
|
|
12
|
-
strategy:
|
|
13
|
-
matrix:
|
|
14
|
-
node-version:
|
|
15
|
-
- 16.x
|
|
16
|
-
- 18.x
|
|
17
|
-
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
|
18
|
-
steps:
|
|
19
|
-
- uses: actions/checkout@v3
|
|
20
|
-
with:
|
|
21
|
-
repository: getargv/getargv
|
|
22
|
-
path: getargv
|
|
23
|
-
token: ${{ secrets.GH_PAT }}
|
|
24
|
-
- name: Build libgetargv
|
|
25
|
-
run: make install_dylib
|
|
26
|
-
working-directory: getargv
|
|
27
|
-
- uses: actions/checkout@v3
|
|
28
|
-
with:
|
|
29
|
-
path: getargv.js
|
|
30
|
-
- name: Use Node.js ${{ matrix.node-version }}
|
|
31
|
-
uses: actions/setup-node@v3
|
|
32
|
-
with:
|
|
33
|
-
node-version: ${{ matrix.node-version }}
|
|
34
|
-
cache: 'npm'
|
|
35
|
-
check-latest: true
|
|
36
|
-
cache-dependency-path: ./getargv.js/package-lock.json
|
|
37
|
-
- run: npm ci
|
|
38
|
-
working-directory: getargv.js
|
|
39
|
-
- run: cat /Users/runner/.npm/_logs/*-debug.log && false
|
|
40
|
-
if: ${{ failure() }}
|
|
41
|
-
- run: npm run build --if-present
|
|
42
|
-
working-directory: getargv.js
|
|
43
|
-
- run: npm test
|
|
44
|
-
working-directory: getargv.js
|
package/lib/binding.ts
DELETED
package/test/test_binding.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
const Getargv = require("../dist/binding.js");
|
|
2
|
-
const assert = require("assert");
|
|
3
|
-
const process = require("process");
|
|
4
|
-
|
|
5
|
-
function expected_args() {
|
|
6
|
-
return [process.argv0, ...process.execArgv, ...process.argv.slice(1)].map(a => a.replace(process.cwd(), "."));
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
assert(Getargv, "The export is undefined");
|
|
10
|
-
|
|
11
|
-
function test_Get_Argv_Of_Pid() {
|
|
12
|
-
const result = Getargv.get_argv_of_pid(process.pid);
|
|
13
|
-
assert.strictEqual(result, expected_args().join("\0") + "\0", "Unexpected value returned");
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function test_Get_Argv_And_Argc_Of_Pid() {
|
|
17
|
-
const result = Getargv.get_argv_and_argc_of_pid(process.pid);
|
|
18
|
-
assert.deepStrictEqual(result, expected_args(), "Unexpected value returned");
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
assert.doesNotThrow(test_Get_Argv_Of_Pid, undefined, "test_Get_Argv_Of_Pid threw an expection");
|
|
22
|
-
assert.doesNotThrow(test_Get_Argv_And_Argc_Of_Pid, undefined, "test_Get_Argv_And_Argc_Of_Pid threw an expection");
|
|
23
|
-
|
|
24
|
-
console.log("Tests passed & everything looks OK!");
|
package/tsconfig.json
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"declaration": true,
|
|
4
|
-
"lib": [ "esnext" ],
|
|
5
|
-
"module": "commonjs",
|
|
6
|
-
"outDir": "./dist",
|
|
7
|
-
"rootDir": "./lib",
|
|
8
|
-
"strict": true,
|
|
9
|
-
"target": "es6",
|
|
10
|
-
"types": [
|
|
11
|
-
"node"
|
|
12
|
-
],
|
|
13
|
-
"typeRoots": [
|
|
14
|
-
"node_modules/@types"
|
|
15
|
-
]
|
|
16
|
-
}
|
|
17
|
-
}
|