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:
@@ -47,8 +47,7 @@ Arguments::~Arguments()
|
||||
void
|
||||
Arguments::Parse(int argc, const char* const* argv)
|
||||
{
|
||||
int argi;
|
||||
for (argi = 1; argi < argc; argi ++) {
|
||||
for (int argi = 1; argi < argc; argi++) {
|
||||
const char* arg = argv[argi];
|
||||
|
||||
if (*arg == '-') {
|
||||
@@ -56,13 +55,13 @@ Arguments::Parse(int argc, const char* const* argv)
|
||||
fUsageRequested = true;
|
||||
else if (strcmp(arg, "-t") == 0 || strcmp(arg, "--title") == 0) {
|
||||
// title
|
||||
if (argi >= argc)
|
||||
if ((argi + 1) >= argc)
|
||||
fUsageRequested = true;
|
||||
else
|
||||
fTitle = argv[++argi];
|
||||
} else if (strcmp(arg, "-w") == 0
|
||||
|| strcmp(arg, "--working-directory") == 0) {
|
||||
if (argi >= argc)
|
||||
if ((argi + 1) >= argc)
|
||||
fUsageRequested = true;
|
||||
else
|
||||
fWorkingDirectory = argv[++argi];
|
||||
|
||||
@@ -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]>
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
@@ -8,12 +8,12 @@
|
||||
* Jeremiah Bailey, <[email protected]>
|
||||
* Ingo Weinhold, <[email protected]>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ARGUMENTS_H
|
||||
#define ARGUMENTS_H
|
||||
|
||||
|
||||
#include <Rect.h>
|
||||
#include <String.h>
|
||||
|
||||
class Arguments {
|
||||
public:
|
||||
@@ -23,8 +23,8 @@ public:
|
||||
void Parse(int argc, const char* const* argv);
|
||||
|
||||
BRect Bounds() const { return fBounds; }
|
||||
const char* Title() const { return fTitle; }
|
||||
const char* WorkingDir() const { return fWorkingDirectory; }
|
||||
BString Title() const { return fTitle; }
|
||||
BString WorkingDir() const { return fWorkingDirectory; }
|
||||
bool StandardShell() const { return fStandardShell; }
|
||||
bool FullScreen() const { return fFullScreen; }
|
||||
bool UsageRequested() const { return fUsageRequested; }
|
||||
@@ -39,8 +39,8 @@ private:
|
||||
bool fFullScreen;
|
||||
int fShellArgumentCount;
|
||||
const char** fShellArguments;
|
||||
const char* fTitle;
|
||||
const char* fWorkingDirectory;
|
||||
BString fTitle;
|
||||
BString fWorkingDirectory;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -62,7 +62,6 @@ TermApp::TermApp()
|
||||
BApplication(TERM_SIGNATURE),
|
||||
fChildCleanupThread(-1),
|
||||
fTerminating(false),
|
||||
fStartFullscreen(false),
|
||||
fTermWindow(NULL),
|
||||
fArgs(NULL)
|
||||
{
|
||||
@@ -137,7 +136,7 @@ TermApp::ReadyToRun()
|
||||
}
|
||||
|
||||
// using BScreen::Frame isn't enough
|
||||
if (fStartFullscreen)
|
||||
if (fArgs->FullScreen())
|
||||
BMessenger(fTermWindow).SendMessage(FULLSCREEN);
|
||||
}
|
||||
|
||||
@@ -205,16 +204,6 @@ TermApp::ArgvReceived(int32 argc, char **argv)
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
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 (strcmp(mimetype, PREFFILE_MIMETYPE) == 0) {
|
||||
|
||||
BEntry ent(&ref);
|
||||
BPath path(&ent);
|
||||
PrefHandler::Default()->OpenText(path.Path());
|
||||
@@ -259,7 +247,7 @@ status_t
|
||||
TermApp::_MakeTermWindow()
|
||||
{
|
||||
try {
|
||||
fTermWindow = new TermWindow(fWindowTitle, fArgs);
|
||||
fTermWindow = new TermWindow(*fArgs);
|
||||
} catch (int error) {
|
||||
return (status_t)error;
|
||||
} catch (...) {
|
||||
|
||||
@@ -55,9 +55,6 @@ private:
|
||||
private:
|
||||
thread_id fChildCleanupThread;
|
||||
bool fTerminating;
|
||||
bool fStartFullscreen;
|
||||
BString fWindowTitle;
|
||||
BString fWorkingDirectory;
|
||||
|
||||
BWindow* fTermWindow;
|
||||
Arguments* fArgs;
|
||||
|
||||
@@ -181,9 +181,9 @@ struct TermWindow::Session {
|
||||
// #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),
|
||||
fTitleUpdateRunner(this, BMessage(kUpdateTitles), 1000000),
|
||||
fNextSessionID(0),
|
||||
@@ -216,7 +216,7 @@ TermWindow::TermWindow(const BString& title, Arguments* args)
|
||||
get_key_map(&fKeymap, &fKeymapChars);
|
||||
|
||||
// apply the title settings
|
||||
fTitle.pattern = title;
|
||||
fTitle.pattern = args.Title();
|
||||
if (fTitle.pattern.Length() == 0) {
|
||||
fTitle.pattern = B_TRANSLATE_SYSTEM_NAME("Terminal");
|
||||
|
||||
@@ -228,7 +228,7 @@ TermWindow::TermWindow(const BString& title, Arguments* args)
|
||||
fTitle.patternUserDefined = true;
|
||||
|
||||
fTitle.title = fTitle.pattern;
|
||||
fTitle.pattern = title;
|
||||
fTitle.pattern = args.Title();
|
||||
|
||||
_TitleSettingsChanged();
|
||||
|
||||
@@ -259,7 +259,7 @@ TermWindow::TermWindow(const BString& title, Arguments* args)
|
||||
|
||||
// init the GUI and add a tab
|
||||
_InitWindow();
|
||||
_AddTab(args);
|
||||
_AddTab(&args, args.WorkingDir());
|
||||
|
||||
// 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.
|
||||
@@ -749,19 +749,22 @@ TermWindow::MessageReceived(BMessage *message)
|
||||
{
|
||||
// Set our current working directory to that of the active tab, so
|
||||
// that the new terminal and its shell inherit it.
|
||||
// Note: That's a bit lame. We should rather fork() and change the
|
||||
// CWD in the child, but since ATM there aren't any side effects of
|
||||
// changing our CWD, we save ourselves the trouble.
|
||||
const char* argv[] = {NULL, NULL, NULL};
|
||||
int32 argc = 0;
|
||||
|
||||
ActiveProcessInfo activeProcessInfo;
|
||||
if (_ActiveTermView()->GetActiveProcessInfo(activeProcessInfo))
|
||||
chdir(activeProcessInfo.CurrentDirectory());
|
||||
if (_ActiveTermView()->GetActiveProcessInfo(activeProcessInfo)) {
|
||||
argv[0] = "-w";
|
||||
argv[1] = activeProcessInfo.CurrentDirectory();
|
||||
argc = 2;
|
||||
}
|
||||
|
||||
app_info info;
|
||||
be_app->GetAppInfo(&info);
|
||||
|
||||
// try launching two different ways to work around possible problems
|
||||
if (be_roster->Launch(&info.ref) != B_OK)
|
||||
be_roster->Launch(TERM_SIGNATURE);
|
||||
if (be_roster->Launch(&info.ref, argc, argv) != B_OK)
|
||||
be_roster->Launch(TERM_SIGNATURE, argc, argv);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1341,7 +1344,7 @@ TermWindow::_NewTab()
|
||||
|
||||
|
||||
void
|
||||
TermWindow::_AddTab(Arguments* args, const BString& currentDirectory)
|
||||
TermWindow::_AddTab(const Arguments* args, const BString& currentDirectory)
|
||||
{
|
||||
int argc = 0;
|
||||
const char* const* argv = NULL;
|
||||
|
||||
@@ -58,8 +58,7 @@ class TermWindow : public BWindow, private SmartTabView::Listener,
|
||||
private TermView::Listener, private SetTitleDialog::Listener,
|
||||
private TerminalRoster::Listener {
|
||||
public:
|
||||
TermWindow(const BString& title,
|
||||
Arguments* args);
|
||||
TermWindow(const Arguments& args);
|
||||
virtual ~TermWindow();
|
||||
|
||||
void SessionChanged();
|
||||
@@ -154,7 +153,7 @@ private:
|
||||
void _DoPrint();
|
||||
|
||||
void _NewTab();
|
||||
void _AddTab(Arguments* args,
|
||||
void _AddTab(const Arguments* args,
|
||||
const BString& currentDirectory
|
||||
= BString());
|
||||
void _RemoveTab(int32 index);
|
||||
|
||||
Reference in New Issue
Block a user