Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add optional support to replace argv[0] (fixes #472) #627

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ interface IBasePtyForkOptions {
export interface IPtyForkOptions extends IBasePtyForkOptions {
uid?: number;
gid?: number;
argv0?: string;
}

export interface IWindowsPtyForkOptions extends IBasePtyForkOptions {
Expand Down
2 changes: 1 addition & 1 deletion src/native.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ interface IWinptyNative {
}

interface IUnixNative {
fork(file: string, args: string[], parsedEnv: string[], cwd: string, cols: number, rows: number, uid: number, gid: number, useUtf8: boolean, helperPath: string, onExitCallback: (code: number, signal: number) => void): IUnixProcess;
fork(file: string, args: string[], parsedEnv: string[], cwd: string, cols: number, rows: number, uid: number, gid: number, useUtf8: boolean, helperPath: string, onExitCallback: (code: number, signal: number) => void, argv0: string): IUnixProcess;
open(cols: number, rows: number): IUnixOpenProcess;
process(fd: number, pty?: string): string;
resize(fd: number, cols: number, rows: number): void;
Expand Down
20 changes: 13 additions & 7 deletions src/unix/pty.cc
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ pty_posix_spawn(char** argv, char** env,
NAN_METHOD(PtyFork) {
Nan::HandleScope scope;

if (info.Length() != 11 ||
if (info.Length() != 12 ||
!info[0]->IsString() ||
!info[1]->IsArray() ||
!info[2]->IsArray() ||
Expand All @@ -169,9 +169,10 @@ NAN_METHOD(PtyFork) {
!info[7]->IsNumber() ||
!info[8]->IsBoolean() ||
!info[9]->IsString() ||
!info[10]->IsFunction()) {
!info[10]->IsFunction() ||
!info[11]->IsString()) {
return Nan::ThrowError(
"Usage: pty.fork(file, args, env, cwd, cols, rows, uid, gid, utf8, helperPath, onexit)");
"Usage: pty.fork(file, args, env, cwd, cols, rows, uid, gid, utf8, helperPath, onexit, argv0)");
}

// file
Expand Down Expand Up @@ -247,19 +248,23 @@ NAN_METHOD(PtyFork) {
// helperPath
Nan::Utf8String helper_path(info[9]);

// argv0
Nan::Utf8String argv0(info[11]);

pid_t pid;
int master;
#if defined(__APPLE__)
int argc = argv_->Length();
int argl = argc + 4;
int argl = argc + 5;
char **argv = new char*[argl];
argv[0] = strdup(*helper_path);
argv[1] = strdup(*cwd_);
argv[2] = strdup(*file);
argv[3] = strdup(*argv0);
argv[argl - 1] = NULL;
for (int i = 0; i < argc; i++) {
Nan::Utf8String arg(Nan::Get(argv_, i).ToLocalChecked());
argv[i + 3] = strdup(*arg);
argv[i + 4] = strdup(*arg);
}

int err = -1;
Expand All @@ -276,7 +281,7 @@ NAN_METHOD(PtyFork) {
int argc = argv_->Length();
int argl = argc + 2;
char **argv = new char*[argl];
argv[0] = strdup(*file);
argv[0] = strdup(*argv0);
argv[argl - 1] = NULL;
for (int i = 0; i < argc; i++) {
Nan::Utf8String arg(Nan::Get(argv_, i).ToLocalChecked());
Expand Down Expand Up @@ -342,7 +347,8 @@ NAN_METHOD(PtyFork) {
{
char **old = environ;
environ = env;
execvp(argv[0], argv);
char* file_ = strdup(*file);
execvp(file_, argv);
environ = old;
perror("execvp(3) failed.");
_exit(1);
Expand Down
2 changes: 1 addition & 1 deletion src/unix/spawn-helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ int main (int argc, char** argv) {

char *cwd = argv[1];
char *file = argv[2];
argv = &argv[2];
argv = &argv[3];

if (strlen(cwd) && chdir(cwd) == -1) {
_exit(1);
Expand Down
25 changes: 25 additions & 0 deletions src/unixTerminal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,31 @@ if (process.platform !== 'win32') {
}
});
});
it('should default argv0 to file', (done) => {
const term = new UnixTerminal('/bin/sh',
[ '-c', 'echo $0' ]);
let argv0 = '';
term.on('data', (data) => {
argv0 = argv0.concat(data);
});
term.on('exit', () => {
assert.strictEqual(argv0.trim(), '/bin/sh');
done();
});
});
it('should allow an alternate argv0', (done) => {
const term = new UnixTerminal('/bin/sh',
[ '-c', 'echo $0' ],
{ argv0: 'alternate' });
let argv0 = '';
term.on('data', (data) => {
argv0 = argv0.concat(data);
});
term.on('exit', () => {
assert.strictEqual(argv0.trim(), 'alternate');
done();
});
});
});
});
}
4 changes: 3 additions & 1 deletion src/unixTerminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,10 @@ export class UnixTerminal extends Terminal {
this.emit('exit', code, signal);
};

const argv0 = opt.argv0 ?? file;

// fork
const term = pty.fork(file, args, parsedEnv, cwd, this._cols, this._rows, uid, gid, (encoding === 'utf8'), helperPath, onexit);
const term = pty.fork(file, args, parsedEnv, cwd, this._cols, this._rows, uid, gid, (encoding === 'utf8'), helperPath, onexit, argv0);

this._socket = new PipeSocket(term.fd);
if (encoding !== null) {
Expand Down
6 changes: 6 additions & 0 deletions typings/node-pty.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ declare module 'node-pty' {
*/
uid?: number;
gid?: number;

/**
* Alternate argv[0] to use instead of the file being launched. Can be used to launch a shell
* as a login shell, e.g. using `"-sh"` when launching /bin/sh.
*/
argv0?: string;
}

export interface IWindowsPtyForkOptions extends IBasePtyForkOptions {
Expand Down