Terminal: Don't chdir() but pass the working directory down to _Spawn().

If we change our current directory, it will be retained as a reference
down inside the VFS, preventing filesystems from being unmounted,
among other things.

Fixes #19684.
This commit is contained in:
Augustin Cavalier
2025-07-15 17:32:07 -04:00
parent 38e619c671
commit bdda979744
6 changed files with 30 additions and 44 deletions
+3 -4
View File
@@ -47,8 +47,7 @@ Arguments::~Arguments()
void void
Arguments::Parse(int argc, const char* const* argv) Arguments::Parse(int argc, const char* const* argv)
{ {
int argi; for (int argi = 1; argi < argc; argi++) {
for (argi = 1; argi < argc; argi ++) {
const char* arg = argv[argi]; const char* arg = argv[argi];
if (*arg == '-') { if (*arg == '-') {
@@ -56,13 +55,13 @@ Arguments::Parse(int argc, const char* const* argv)
fUsageRequested = true; fUsageRequested = true;
else if (strcmp(arg, "-t") == 0 || strcmp(arg, "--title") == 0) { else if (strcmp(arg, "-t") == 0 || strcmp(arg, "--title") == 0) {
// title // title
if (argi >= argc) if ((argi + 1) >= argc)
fUsageRequested = true; fUsageRequested = true;
else else
fTitle = argv[++argi]; fTitle = argv[++argi];
} else if (strcmp(arg, "-w") == 0 } else if (strcmp(arg, "-w") == 0
|| strcmp(arg, "--working-directory") == 0) { || strcmp(arg, "--working-directory") == 0) {
if (argi >= argc) if ((argi + 1) >= argc)
fUsageRequested = true; fUsageRequested = true;
else else
fWorkingDirectory = argv[++argi]; fWorkingDirectory = argv[++argi];
+7 -7
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2005-2018, Haiku, Inc. All rights reserved. * Copyright 2005-2025, Haiku, Inc. All rights reserved.
* Copyright 2005, Ingo Weinhold, <[email protected]> * Copyright 2005, Ingo Weinhold, <[email protected]>
* *
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
@@ -8,12 +8,12 @@
* Jeremiah Bailey, <[email protected]> * Jeremiah Bailey, <[email protected]>
* Ingo Weinhold, <[email protected]> * Ingo Weinhold, <[email protected]>
*/ */
#ifndef ARGUMENTS_H #ifndef ARGUMENTS_H
#define ARGUMENTS_H #define ARGUMENTS_H
#include <Rect.h> #include <Rect.h>
#include <String.h>
class Arguments { class Arguments {
public: public:
@@ -23,8 +23,8 @@ public:
void Parse(int argc, const char* const* argv); void Parse(int argc, const char* const* argv);
BRect Bounds() const { return fBounds; } BRect Bounds() const { return fBounds; }
const char* Title() const { return fTitle; } BString Title() const { return fTitle; }
const char* WorkingDir() const { return fWorkingDirectory; } BString WorkingDir() const { return fWorkingDirectory; }
bool StandardShell() const { return fStandardShell; } bool StandardShell() const { return fStandardShell; }
bool FullScreen() const { return fFullScreen; } bool FullScreen() const { return fFullScreen; }
bool UsageRequested() const { return fUsageRequested; } bool UsageRequested() const { return fUsageRequested; }
@@ -39,8 +39,8 @@ private:
bool fFullScreen; bool fFullScreen;
int fShellArgumentCount; int fShellArgumentCount;
const char** fShellArguments; const char** fShellArguments;
const char* fTitle; BString fTitle;
const char* fWorkingDirectory; BString fWorkingDirectory;
}; };
+2 -14
View File
@@ -62,7 +62,6 @@ TermApp::TermApp()
BApplication(TERM_SIGNATURE), BApplication(TERM_SIGNATURE),
fChildCleanupThread(-1), fChildCleanupThread(-1),
fTerminating(false), fTerminating(false),
fStartFullscreen(false),
fTermWindow(NULL), fTermWindow(NULL),
fArgs(NULL) fArgs(NULL)
{ {
@@ -137,7 +136,7 @@ TermApp::ReadyToRun()
} }
// using BScreen::Frame isn't enough // using BScreen::Frame isn't enough
if (fStartFullscreen) if (fArgs->FullScreen())
BMessenger(fTermWindow).SendMessage(FULLSCREEN); BMessenger(fTermWindow).SendMessage(FULLSCREEN);
} }
@@ -205,16 +204,6 @@ TermApp::ArgvReceived(int32 argc, char **argv)
PostMessage(B_QUIT_REQUESTED); PostMessage(B_QUIT_REQUESTED);
return; return;
} }
if (fArgs->Title() != NULL)
fWindowTitle = fArgs->Title();
if (fArgs->WorkingDir() != NULL) {
fWorkingDirectory = fArgs->WorkingDir();
chdir(fWorkingDirectory);
}
fStartFullscreen = fArgs->FullScreen();
} }
@@ -239,7 +228,6 @@ TermApp::RefsReceived(BMessage* message)
// if App opened by Pref file // if App opened by Pref file
if (strcmp(mimetype, PREFFILE_MIMETYPE) == 0) { if (strcmp(mimetype, PREFFILE_MIMETYPE) == 0) {
BEntry ent(&ref); BEntry ent(&ref);
BPath path(&ent); BPath path(&ent);
PrefHandler::Default()->OpenText(path.Path()); PrefHandler::Default()->OpenText(path.Path());
@@ -259,7 +247,7 @@ status_t
TermApp::_MakeTermWindow() TermApp::_MakeTermWindow()
{ {
try { try {
fTermWindow = new TermWindow(fWindowTitle, fArgs); fTermWindow = new TermWindow(*fArgs);
} catch (int error) { } catch (int error) {
return (status_t)error; return (status_t)error;
} catch (...) { } catch (...) {
-3
View File
@@ -55,9 +55,6 @@ private:
private: private:
thread_id fChildCleanupThread; thread_id fChildCleanupThread;
bool fTerminating; bool fTerminating;
bool fStartFullscreen;
BString fWindowTitle;
BString fWorkingDirectory;
BWindow* fTermWindow; BWindow* fTermWindow;
Arguments* fArgs; Arguments* fArgs;
+16 -13
View File
@@ -181,9 +181,9 @@ struct TermWindow::Session {
// #pragma mark - TermWindow // #pragma mark - TermWindow
TermWindow::TermWindow(const BString& title, Arguments* args) TermWindow::TermWindow(const Arguments& args)
: :
BWindow(BRect(0, 0, 0, 0), title, B_DOCUMENT_WINDOW, BWindow(BRect(0, 0, 0, 0), args.Title(), B_DOCUMENT_WINDOW,
B_CURRENT_WORKSPACE | B_QUIT_ON_WINDOW_CLOSE), B_CURRENT_WORKSPACE | B_QUIT_ON_WINDOW_CLOSE),
fTitleUpdateRunner(this, BMessage(kUpdateTitles), 1000000), fTitleUpdateRunner(this, BMessage(kUpdateTitles), 1000000),
fNextSessionID(0), fNextSessionID(0),
@@ -216,7 +216,7 @@ TermWindow::TermWindow(const BString& title, Arguments* args)
get_key_map(&fKeymap, &fKeymapChars); get_key_map(&fKeymap, &fKeymapChars);
// apply the title settings // apply the title settings
fTitle.pattern = title; fTitle.pattern = args.Title();
if (fTitle.pattern.Length() == 0) { if (fTitle.pattern.Length() == 0) {
fTitle.pattern = B_TRANSLATE_SYSTEM_NAME("Terminal"); fTitle.pattern = B_TRANSLATE_SYSTEM_NAME("Terminal");
@@ -228,7 +228,7 @@ TermWindow::TermWindow(const BString& title, Arguments* args)
fTitle.patternUserDefined = true; fTitle.patternUserDefined = true;
fTitle.title = fTitle.pattern; fTitle.title = fTitle.pattern;
fTitle.pattern = title; fTitle.pattern = args.Title();
_TitleSettingsChanged(); _TitleSettingsChanged();
@@ -259,7 +259,7 @@ TermWindow::TermWindow(const BString& title, Arguments* args)
// init the GUI and add a tab // init the GUI and add a tab
_InitWindow(); _InitWindow();
_AddTab(args); _AddTab(&args, args.WorkingDir());
// Announce our window as no longer minimized. That's not true, since it's // Announce our window as no longer minimized. That's not true, since it's
// still hidden at this point, but it will be shown very soon. // still hidden at this point, but it will be shown very soon.
@@ -749,19 +749,22 @@ TermWindow::MessageReceived(BMessage *message)
{ {
// Set our current working directory to that of the active tab, so // Set our current working directory to that of the active tab, so
// that the new terminal and its shell inherit it. // that the new terminal and its shell inherit it.
// Note: That's a bit lame. We should rather fork() and change the const char* argv[] = {NULL, NULL, NULL};
// CWD in the child, but since ATM there aren't any side effects of int32 argc = 0;
// changing our CWD, we save ourselves the trouble.
ActiveProcessInfo activeProcessInfo; ActiveProcessInfo activeProcessInfo;
if (_ActiveTermView()->GetActiveProcessInfo(activeProcessInfo)) if (_ActiveTermView()->GetActiveProcessInfo(activeProcessInfo)) {
chdir(activeProcessInfo.CurrentDirectory()); argv[0] = "-w";
argv[1] = activeProcessInfo.CurrentDirectory();
argc = 2;
}
app_info info; app_info info;
be_app->GetAppInfo(&info); be_app->GetAppInfo(&info);
// try launching two different ways to work around possible problems // try launching two different ways to work around possible problems
if (be_roster->Launch(&info.ref) != B_OK) if (be_roster->Launch(&info.ref, argc, argv) != B_OK)
be_roster->Launch(TERM_SIGNATURE); be_roster->Launch(TERM_SIGNATURE, argc, argv);
break; break;
} }
@@ -1341,7 +1344,7 @@ TermWindow::_NewTab()
void void
TermWindow::_AddTab(Arguments* args, const BString& currentDirectory) TermWindow::_AddTab(const Arguments* args, const BString& currentDirectory)
{ {
int argc = 0; int argc = 0;
const char* const* argv = NULL; const char* const* argv = NULL;
+2 -3
View File
@@ -58,8 +58,7 @@ class TermWindow : public BWindow, private SmartTabView::Listener,
private TermView::Listener, private SetTitleDialog::Listener, private TermView::Listener, private SetTitleDialog::Listener,
private TerminalRoster::Listener { private TerminalRoster::Listener {
public: public:
TermWindow(const BString& title, TermWindow(const Arguments& args);
Arguments* args);
virtual ~TermWindow(); virtual ~TermWindow();
void SessionChanged(); void SessionChanged();
@@ -154,7 +153,7 @@ private:
void _DoPrint(); void _DoPrint();
void _NewTab(); void _NewTab();
void _AddTab(Arguments* args, void _AddTab(const Arguments* args,
const BString& currentDirectory const BString& currentDirectory
= BString()); = BString());
void _RemoveTab(int32 index); void _RemoveTab(int32 index);