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
|
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];
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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 (...) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user