update nix build
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
This commit is contained in:
175
main.cc
175
main.cc
@@ -12,6 +12,7 @@
|
||||
#include "Command.h"
|
||||
#include "Frontend.h"
|
||||
#include "TerminalFrontend.h"
|
||||
|
||||
#if defined(KTE_BUILD_GUI)
|
||||
#include "GUIFrontend.h"
|
||||
#endif
|
||||
@@ -25,156 +26,52 @@ static void
|
||||
PrintUsage(const char *prog)
|
||||
{
|
||||
std::cerr << "Usage: " << prog << " [OPTIONS] [files]\n"
|
||||
<< "Options:\n"
|
||||
<< " -g, --gui Use GUI frontend (if built)\n"
|
||||
<< " -t, --term Use terminal (ncurses) frontend [default]\n"
|
||||
<< " -h, --help Show this help and exit\n"
|
||||
<< " -V, --version Show version and exit\n";
|
||||
<< "Options:\n"
|
||||
<< " -g, --gui Use GUI frontend (if built)\n"
|
||||
<< " -t, --term Use terminal (ncurses) frontend [default]\n"
|
||||
<< " -h, --help Show this help and exit\n"
|
||||
<< " -V, --version Show version and exit\n";
|
||||
}
|
||||
|
||||
|
||||
#if defined(KTE_BUILD_GUI)
|
||||
// Detach the process from the controlling terminal when running the GUI so the
|
||||
// launching terminal can be closed. This mirrors typical GUI app behavior on
|
||||
// POSIX systems.
|
||||
static void
|
||||
DetachFromTerminalIfGUI(bool use_gui)
|
||||
{
|
||||
#if defined(__APPLE__) || defined(__linux__) || defined(__unix__)
|
||||
if (!use_gui)
|
||||
return;
|
||||
|
||||
// Ignore SIGHUP so closing the terminal won't terminate us.
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
|
||||
// Helper: redirect stdio to /dev/null and optionally close extra FDs.
|
||||
auto redirect_stdio_and_close = []() {
|
||||
// Reset file mode creation mask and working directory to a safe default
|
||||
umask(0);
|
||||
chdir("/");
|
||||
|
||||
FILE *fnull_r = fopen("/dev/null", "r");
|
||||
if (fnull_r) {
|
||||
dup2(fileno(fnull_r), STDIN_FILENO);
|
||||
}
|
||||
FILE *fnull_w = fopen("/dev/null", "w");
|
||||
if (fnull_w) {
|
||||
dup2(fileno(fnull_w), STDOUT_FILENO);
|
||||
dup2(fileno(fnull_w), STDERR_FILENO);
|
||||
}
|
||||
|
||||
// Close any other inherited FDs to avoid keeping terminal/pty or pipes open
|
||||
long max_fd = sysconf(_SC_OPEN_MAX);
|
||||
if (max_fd < 0)
|
||||
max_fd = 256; // conservative fallback
|
||||
for (long fd = 3; fd < max_fd; ++fd) {
|
||||
close(static_cast<int>(fd));
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(__APPLE__)
|
||||
// macOS: daemon(3) is deprecated and treated as an error with -Werror.
|
||||
// Use double-fork + setsid and redirect stdio to /dev/null.
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pid > 0) {
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
if (setsid() < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
pid_t pid2 = fork();
|
||||
if (pid2 < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pid2 > 0) {
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
redirect_stdio_and_close();
|
||||
#else
|
||||
// Prefer daemon(3) on non-Apple POSIX; fall back to manual detach if it fails.
|
||||
if (daemon(0, 0) == 0) {
|
||||
redirect_stdio_and_close();
|
||||
return;
|
||||
}
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pid > 0) {
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
if (setsid() < 0) {
|
||||
// bogus check
|
||||
}
|
||||
|
||||
pid_t pid2 = fork();
|
||||
if (pid2 < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pid2 > 0) {
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
redirect_stdio_and_close();
|
||||
#endif
|
||||
#else
|
||||
(void) use_gui;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
main(int argc, const char *argv[])
|
||||
{
|
||||
Editor editor;
|
||||
|
||||
// CLI parsing using getopt_long
|
||||
bool req_gui = false;
|
||||
bool req_term = false;
|
||||
bool show_help = false;
|
||||
bool req_gui = false;
|
||||
bool req_term = false;
|
||||
bool show_help = false;
|
||||
bool show_version = false;
|
||||
|
||||
static struct option long_opts[] = {
|
||||
{"gui", no_argument, nullptr, 'g'},
|
||||
{"term", no_argument, nullptr, 't'},
|
||||
{"help", no_argument, nullptr, 'h'},
|
||||
{"version", no_argument, nullptr, 'V'},
|
||||
{nullptr, 0, nullptr, 0}
|
||||
{"gui", no_argument, nullptr, 'g'},
|
||||
{"term", no_argument, nullptr, 't'},
|
||||
{"help", no_argument, nullptr, 'h'},
|
||||
{"version", no_argument, nullptr, 'V'},
|
||||
{nullptr, 0, nullptr, 0}
|
||||
};
|
||||
|
||||
int opt;
|
||||
int long_index = 0;
|
||||
while ((opt = getopt_long(argc, const_cast<char * const*>(argv), "gthV", long_opts, &long_index)) != -1) {
|
||||
while ((opt = getopt_long(argc, const_cast<char *const *>(argv), "gthV", long_opts, &long_index)) != -1) {
|
||||
switch (opt) {
|
||||
case 'g':
|
||||
req_gui = true;
|
||||
break;
|
||||
case 't':
|
||||
req_term = true;
|
||||
break;
|
||||
case 'h':
|
||||
show_help = true;
|
||||
break;
|
||||
case 'V':
|
||||
show_version = true;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
PrintUsage(argv[0]);
|
||||
return 2;
|
||||
case 'g':
|
||||
req_gui = true;
|
||||
break;
|
||||
case 't':
|
||||
req_term = true;
|
||||
break;
|
||||
case 'h':
|
||||
show_help = true;
|
||||
break;
|
||||
case 'V':
|
||||
show_version = true;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
PrintUsage(argv[0]);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +92,7 @@ main(int argc, const char *argv[])
|
||||
#if !defined(KTE_BUILD_GUI)
|
||||
if (req_gui) {
|
||||
std::cerr << "kte: GUI not built. Reconfigure with -DBUILD_GUI=ON and required deps installed." <<
|
||||
std::endl;
|
||||
std::endl;
|
||||
return 2;
|
||||
}
|
||||
#else
|
||||
@@ -212,8 +109,6 @@ main(int argc, const char *argv[])
|
||||
use_gui = false;
|
||||
#endif
|
||||
}
|
||||
// If using GUI, detach from the controlling terminal so the terminal can be closed.
|
||||
DetachFromTerminalIfGUI(use_gui);
|
||||
#endif
|
||||
|
||||
// Open files passed on the CLI; support +N to jump to line N in the next file.
|
||||
@@ -237,7 +132,7 @@ main(int argc, const char *argv[])
|
||||
// Clamp to >=1 later; 0 disables.
|
||||
try {
|
||||
unsigned long v = std::stoul(p);
|
||||
pending_line = static_cast<std::size_t>(v);
|
||||
pending_line = static_cast<std::size_t>(v);
|
||||
} catch (...) {
|
||||
// Ignore malformed huge numbers
|
||||
pending_line = 0;
|
||||
@@ -257,7 +152,7 @@ main(int argc, const char *argv[])
|
||||
// Apply pending +N to the just-opened (current) buffer
|
||||
if (Buffer *b = editor.CurrentBuffer()) {
|
||||
std::size_t nrows = b->Nrows();
|
||||
std::size_t line = pending_line > 0 ? pending_line - 1 : 0;
|
||||
std::size_t line = pending_line > 0 ? pending_line - 1 : 0;
|
||||
// 1-based to 0-based
|
||||
if (nrows > 0) {
|
||||
if (line >= nrows)
|
||||
@@ -283,7 +178,7 @@ main(int argc, const char *argv[])
|
||||
InstallDefaultCommands();
|
||||
|
||||
// Select frontend
|
||||
std::unique_ptr<Frontend> fe;
|
||||
std::unique_ptr <Frontend> fe;
|
||||
#if defined(KTE_BUILD_GUI)
|
||||
if (use_gui) {
|
||||
fe = std::make_unique<GUIFrontend>();
|
||||
|
||||
Reference in New Issue
Block a user