2023-02-01 15:56:25 +01:00
#include "terminalshell.h"
2023-01-28 12:40:12 +01:00
#include "common/io/io.h"
2022-07-25 13:59:19 +02:00
#include "common/parsing.h"
2022-07-25 14:45:41 +02:00
#include "common/processing.h"
2022-10-12 14:13:20 +08:00
#include "common/thread.h"
2023-02-01 15:56:25 +01:00
#include "util/stringUtils.h"
2021-06-14 23:22:14 +02:00
#include <string.h>
2022-06-18 14:25:31 +02:00
#include <stdlib.h>
2021-06-14 23:22:14 +02:00
#include <unistd.h>
static void setExeName ( FFstrbuf * exe , const char ** exeName )
{
2022-10-08 22:16:45 +08:00
assert ( exe -> length > 0 );
2021-06-14 23:22:14 +02:00
uint32_t lastSlashIndex = ffStrbufLastIndexC ( exe , '/' );
if ( lastSlashIndex < exe -> length )
* exeName = exe -> chars + lastSlashIndex + 1 ;
}
2024-01-12 20:42:33 +08:00
static pid_t getShellInfo ( FFShellResult * result , pid_t pid )
2022-10-11 14:59:09 +08:00
{
pid_t ppid = 0 ;
2024-01-23 16:38:43 +08:00
int32_t tty = - 1 ;
2021-06-14 23:22:14 +02:00
2024-04-18 09:22:08 +08:00
const char * userShellName = NULL ;
{
uint32_t index = ffStrbufLastIndexC ( & instance . state . platform . userShell , '/' );
if ( index == instance . state . platform . userShell . length )
userShellName = instance . state . platform . userShell . chars ;
else
userShellName = instance . state . platform . userShell . chars + index + 1 ;
}
2025-08-21 00:12:41 +08:00
while ( pid > 1 && ffProcessGetBasicInfoLinux ( pid , & result -> processName , & ppid , & tty ) == NULL )
2024-01-12 23:57:56 +09:00
{
2024-05-28 23:46:13 +08:00
if ( ! ffStrbufEqualS ( & result -> processName , userShellName ))
2024-01-12 23:57:56 +09:00
{
2024-04-18 09:22:08 +08:00
//Common programs that are between terminal and own process, but are not the shell
if (
// tty < 0 || //A shell should connect to a tty
2025-08-21 00:12:41 +08:00
pid == 1 || // init/systemd
2024-05-28 23:46:13 +08:00
ffStrbufEqualS ( & result -> processName , "sh" ) || //This prevents us from detecting things like pipes and redirects, i hope nobody uses plain `sh` as shell
ffStrbufEqualS ( & result -> processName , "sudo" ) ||
ffStrbufEqualS ( & result -> processName , "su" ) ||
ffStrbufEqualS ( & result -> processName , "strace" ) ||
ffStrbufEqualS ( & result -> processName , "gdb" ) ||
ffStrbufEqualS ( & result -> processName , "lldb" ) ||
ffStrbufEqualS ( & result -> processName , "lldb-mi" ) ||
ffStrbufEqualS ( & result -> processName , "login" ) ||
ffStrbufEqualS ( & result -> processName , "ltrace" ) ||
ffStrbufEqualS ( & result -> processName , "perf" ) ||
ffStrbufEqualS ( & result -> processName , "guake-wrapped" ) ||
ffStrbufEqualS ( & result -> processName , "time" ) ||
ffStrbufEqualS ( & result -> processName , "clifm" ) || //https://github.com/leo-arch/clifm/issues/289
ffStrbufEqualS ( & result -> processName , "valgrind" ) ||
2025-08-04 14:25:14 +08:00
ffStrbufEqualS ( & result -> processName , "fastfetch" ) || //#994
2024-06-05 16:07:03 +08:00
ffStrbufEqualS ( & result -> processName , "flashfetch" ) ||
2025-05-17 18:02:19 +08:00
ffStrbufEqualS ( & result -> processName , "proot" ) ||
ffStrbufEqualS ( & result -> processName , "script" ) ||
2024-05-28 23:46:13 +08:00
ffStrbufContainS ( & result -> processName , "debug" ) ||
2025-01-03 10:32:04 +08:00
ffStrbufContainS ( & result -> processName , "command-not-" ) ||
2024-05-28 23:46:13 +08:00
ffStrbufEndsWithS ( & result -> processName , ".sh" )
2024-04-18 09:22:08 +08:00
)
{
pid = ppid ;
2024-05-28 23:46:13 +08:00
ffStrbufClear ( & result -> processName );
2024-04-18 09:22:08 +08:00
continue ;
}
2024-01-12 23:57:56 +09:00
}
result -> pid = ( uint32_t ) pid ;
result -> ppid = ( uint32_t ) ppid ;
2024-01-23 16:38:43 +08:00
result -> tty = tty ;
2024-05-28 22:34:41 +08:00
ffProcessGetInfoLinux ( pid , & result -> processName , & result -> exe , & result -> exeName , & result -> exePath );
2024-01-12 23:57:56 +09:00
break ;
}
2025-08-21 00:12:41 +08:00
return pid > 1 ? ppid : 0 ;
2024-01-12 16:40:21 +08:00
}
2024-01-12 20:42:33 +08:00
static pid_t getTerminalInfo ( FFTerminalResult * result , pid_t pid )
2024-01-12 16:40:21 +08:00
{
pid_t ppid = 0 ;
2025-08-21 00:12:41 +08:00
while ( pid > 1 && ffProcessGetBasicInfoLinux ( pid , & result -> processName , & ppid , NULL ) == NULL )
2024-01-12 23:57:56 +09:00
{
//Known shells
if (
2025-08-21 00:12:41 +08:00
pid == 1 || // init/systemd
2024-09-22 10:31:59 +08:00
ffStrbufEqualS ( & result -> processName , "sudo" ) ||
ffStrbufEqualS ( & result -> processName , "su" ) ||
2024-05-28 23:46:13 +08:00
ffStrbufEqualS ( & result -> processName , "sh" ) ||
ffStrbufEqualS ( & result -> processName , "ash" ) ||
ffStrbufEqualS ( & result -> processName , "bash" ) ||
ffStrbufEqualS ( & result -> processName , "zsh" ) ||
ffStrbufEqualS ( & result -> processName , "ksh" ) ||
ffStrbufEqualS ( & result -> processName , "mksh" ) ||
ffStrbufEqualS ( & result -> processName , "oksh" ) ||
ffStrbufEqualS ( & result -> processName , "csh" ) ||
ffStrbufEqualS ( & result -> processName , "tcsh" ) ||
ffStrbufEqualS ( & result -> processName , "fish" ) ||
ffStrbufEqualS ( & result -> processName , "dash" ) ||
ffStrbufEqualS ( & result -> processName , "pwsh" ) ||
ffStrbufEqualS ( & result -> processName , "nu" ) ||
ffStrbufEqualS ( & result -> processName , "git-shell" ) ||
ffStrbufEqualS ( & result -> processName , "elvish" ) ||
ffStrbufEqualS ( & result -> processName , "oil.ovm" ) ||
ffStrbufEqualS ( & result -> processName , "xonsh" ) || // works in Linux but not in macOS because kernel returns `Python` in this case
ffStrbufEqualS ( & result -> processName , "login" ) ||
ffStrbufEqualS ( & result -> processName , "clifm" ) || // https://github.com/leo-arch/clifm/issues/289
ffStrbufEqualS ( & result -> processName , "chezmoi" ) || // #762
2024-12-20 14:44:54 +08:00
ffStrbufEqualS ( & result -> processName , "proot" ) ||
2025-05-17 18:02:19 +08:00
ffStrbufEqualS ( & result -> processName , "script" ) ||
2024-02-01 17:56:40 +08:00
#ifdef __linux__
2025-09-04 22:31:59 +08:00
ffStrbufStartsWithS ( & result -> processName , "Relay(" ) || // Unknown process in WSL2
2024-05-28 23:46:13 +08:00
ffStrbufStartsWithS ( & result -> processName , "flatpak-" ) || // #707
2024-02-01 17:56:40 +08:00
#endif
2024-05-28 23:46:13 +08:00
ffStrbufEndsWithS ( & result -> processName , ".sh" )
2024-01-12 23:57:56 +09:00
)
{
pid = ppid ;
2024-05-28 23:46:13 +08:00
ffStrbufClear ( & result -> processName );
2024-01-12 23:57:56 +09:00
continue ;
}
#ifdef __APPLE__
// https://github.com/fastfetch-cli/fastfetch/discussions/501
2024-05-28 23:46:13 +08:00
const char * pLeft = strstr ( result -> processName . chars , " (" );
2024-05-09 20:39:17 +09:00
if ( pLeft )
2024-01-12 23:57:56 +09:00
{
2024-05-09 20:39:17 +09:00
pLeft += 2 ;
const char * pRight = strstr ( pLeft , "term)" );
if ( pRight && pRight [ 5 ] == '\0' )
{
for (; pLeft < pRight ; ++ pLeft )
if ( * pLeft < 'a' || * pLeft > 'z' )
break ;
2024-05-28 23:46:13 +08:00
if ( pLeft == pRight && ffProcessGetBasicInfoLinux ( ppid , & result -> processName , & ppid , NULL ) != NULL )
2024-05-09 20:39:17 +09:00
return 0 ;
}
2024-01-12 23:57:56 +09:00
}
#endif
result -> pid = ( uint32_t ) pid ;
2024-01-19 10:46:19 +08:00
result -> ppid = ( uint32_t ) ppid ;
2024-05-28 22:34:41 +08:00
ffProcessGetInfoLinux ( pid , & result -> processName , & result -> exe , & result -> exeName , & result -> exePath );
2024-01-12 23:57:56 +09:00
break ;
}
2025-08-21 00:12:41 +08:00
return pid > 1 ? ppid : 0 ;
2021-06-14 23:22:14 +02:00
}
2024-01-22 10:20:50 +08:00
static bool getTerminalInfoByPidEnv ( FFTerminalResult * result , const char * pidEnv )
{
2024-01-30 15:22:26 +08:00
const char * envStr = getenv ( pidEnv );
if ( envStr == NULL )
return false ;
pid_t pid = ( pid_t ) strtol ( envStr , NULL , 10 );
2024-01-22 10:20:50 +08:00
result -> pid = ( uint32_t ) pid ;
2024-05-28 23:46:13 +08:00
if ( ffProcessGetBasicInfoLinux ( pid , & result -> processName , ( pid_t * ) & result -> ppid , NULL ) == NULL )
2024-01-22 10:20:50 +08:00
{
2024-05-28 22:34:41 +08:00
ffProcessGetInfoLinux ( pid , & result -> processName , & result -> exe , & result -> exeName , & result -> exePath );
2024-01-22 10:20:50 +08:00
return true ;
}
return false ;
}
2024-01-12 20:42:33 +08:00
static void getTerminalFromEnv ( FFTerminalResult * result )
2021-06-14 23:22:14 +02:00
{
2024-10-02 20:13:12 +08:00
if ( result -> processName . length > 0 )
{
if ( ! ffStrbufStartsWithS ( & result -> processName , "login" ) &&
! ffStrbufEqualS ( & result -> processName , "(login)" ) &&
#ifdef __APPLE__
! ffStrbufEqualS ( & result -> processName , "launchd" ) &&
#else
! ffStrbufEqualS ( & result -> processName , "systemd" ) &&
! ffStrbufEqualS ( & result -> processName , "init" ) &&
! ffStrbufEqualS ( & result -> processName , "(init)" ) &&
! ffStrbufEqualS ( & result -> processName , "SessionLeader" ) && // #750
#endif
2022-11-17 18:14:14 +08:00
2024-10-02 20:13:12 +08:00
! ffStrbufEqualS ( & result -> processName , "0" )
) return ;
2022-11-17 18:14:14 +08:00
2024-10-02 20:13:12 +08:00
ffStrbufClear ( & result -> processName );
ffStrbufClear ( & result -> exe );
result -> exeName = result -> exe . chars ;
ffStrbufClear ( & result -> exePath );
result -> pid = result -> ppid = 0 ;
}
2021-06-14 23:22:14 +02:00
2022-10-14 18:38:18 +08:00
const char * term = NULL ;
2021-10-17 01:05:45 +08:00
//SSH
2024-01-22 10:20:50 +08:00
if (
getenv ( "SSH_TTY" ) != NULL
)
2021-10-17 01:05:45 +08:00
term = getenv ( "SSH_TTY" );
2024-01-22 10:20:50 +08:00
else if (
getenv ( "KITTY_PID" ) != NULL ||
getenv ( "KITTY_INSTALLATION_DIR" ) != NULL
)
{
if ( getTerminalInfoByPidEnv ( result , "KITTY_PID" ))
return ;
term = "kitty" ;
}
2021-10-17 01:05:45 +08:00
2024-01-22 10:20:50 +08:00
#ifdef __linux__ // WSL
2021-10-17 01:05:45 +08:00
//Windows Terminal
2024-01-22 10:20:50 +08:00
else if (
2022-06-18 14:51:10 +02:00
getenv ( "WT_SESSION" ) != NULL ||
getenv ( "WT_PROFILE_ID" ) != NULL
2024-01-22 10:20:50 +08:00
) term = "Windows Terminal" ;
2023-07-16 13:12:50 +08:00
//ConEmu
2024-01-22 10:20:50 +08:00
else if (
2023-07-16 13:12:50 +08:00
getenv ( "ConEmuPID" ) != NULL
2024-01-22 10:20:50 +08:00
) term = "ConEmu" ;
2022-11-17 18:14:14 +08:00
#endif
2021-10-17 01:05:45 +08:00
2022-09-21 15:15:36 +08:00
//Alacritty
2024-01-22 10:20:50 +08:00
else if (
2022-09-21 15:15:36 +08:00
getenv ( "ALACRITTY_SOCKET" ) != NULL ||
getenv ( "ALACRITTY_LOG" ) != NULL ||
getenv ( "ALACRITTY_WINDOW_ID" ) != NULL
2024-01-22 10:20:50 +08:00
) term = "Alacritty" ;
2022-09-21 15:15:36 +08:00
2022-10-14 18:51:04 +08:00
#ifdef __ANDROID__
2022-06-18 00:45:28 +02:00
//Termux
2024-01-22 10:20:50 +08:00
else if (
2022-06-18 00:45:28 +02:00
getenv ( "TERMUX_VERSION" ) != NULL ||
2023-10-24 10:14:08 +08:00
getenv ( "TERMUX_MAIN_PACKAGE_FORMAT" ) != NULL
2024-01-22 10:20:50 +08:00
)
{
if ( getTerminalInfoByPidEnv ( result , "TERMUX_APP__PID" ))
return ;
term = "com.termux" ;
}
2022-10-14 18:51:04 +08:00
#endif
2022-06-18 00:45:28 +02:00
2025-08-24 21:40:22 +08:00
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__GNU__)
2022-09-20 11:16:08 +02:00
//Konsole
2024-01-22 10:20:50 +08:00
else if (
2022-09-20 11:16:08 +02:00
getenv ( "KONSOLE_VERSION" ) != NULL
2024-01-22 10:20:50 +08:00
) term = "konsole" ;
else if (
getenv ( "GNOME_TERMINAL_SCREEN" ) != NULL ||
getenv ( "GNOME_TERMINAL_SERVICE" ) != NULL
) term = "gnome-terminal" ;
2022-10-14 18:51:04 +08:00
#endif
2022-09-20 11:16:08 +02:00
2022-10-02 17:52:09 +08:00
//MacOS, mintty
2024-01-22 10:20:50 +08:00
else if ( getenv ( "TERM_PROGRAM" ) != NULL )
2022-09-04 09:02:11 -07:00
term = getenv ( "TERM_PROGRAM" );
2024-01-22 10:20:50 +08:00
else if ( getenv ( "LC_TERMINAL" ) != NULL )
2023-11-01 08:55:00 +08:00
term = getenv ( "LC_TERMINAL" );
2021-10-17 01:05:45 +08:00
//Normal Terminal
2024-01-22 10:20:50 +08:00
else
{
2021-10-17 01:05:45 +08:00
term = getenv ( "TERM" );
2024-01-22 10:20:50 +08:00
//TTY
if ( ! ffStrSet ( term ) || ffStrEquals ( term , "linux" ))
term = ttyname ( STDIN_FILENO );
}
2021-06-14 23:22:14 +02:00
2022-10-08 22:16:45 +08:00
if ( ffStrSet ( term ))
{
2024-01-12 20:42:33 +08:00
ffStrbufSetS ( & result -> processName , term );
ffStrbufSetS ( & result -> exe , term );
setExeName ( & result -> exe , & result -> exeName );
2022-10-08 22:16:45 +08:00
}
2021-06-14 23:22:14 +02:00
}
2024-01-12 20:42:33 +08:00
static void getUserShellFromEnv ( FFShellResult * result )
2021-06-14 23:22:14 +02:00
{
//If shell detection via processes failed
2024-01-12 20:42:33 +08:00
if ( result -> processName . length == 0 && instance . state . platform . userShell . length > 0 )
2021-06-14 23:22:14 +02:00
{
2024-01-12 20:42:33 +08:00
ffStrbufSet ( & result -> exe , & instance . state . platform . userShell );
setExeName ( & result -> exe , & result -> exeName );
ffStrbufAppendS ( & result -> processName , result -> exeName );
2021-06-14 23:22:14 +02:00
}
}
2024-08-27 14:06:45 +08:00
bool fftsGetShellVersion ( FFstrbuf * exe , const char * exeName , FFstrbuf * exePath , FFstrbuf * version );
2022-10-14 16:28:03 +08:00
2023-01-10 19:24:59 +08:00
bool fftsGetTerminalVersion ( FFstrbuf * processName , FFstrbuf * exe , FFstrbuf * version );
2024-01-12 20:42:33 +08:00
static void setShellInfoDetails ( FFShellResult * result )
2024-01-12 16:40:21 +08:00
{
2024-01-12 20:42:33 +08:00
ffStrbufClear ( & result -> version );
2024-08-27 14:06:45 +08:00
fftsGetShellVersion ( & result -> exe , result -> exeName , & result -> exePath , & result -> version );
2024-01-12 20:42:33 +08:00
if ( ffStrbufEqualS ( & result -> processName , "pwsh" ))
ffStrbufInitStatic ( & result -> prettyName , "PowerShell" );
else if ( ffStrbufEqualS ( & result -> processName , "nu" ))
ffStrbufInitStatic ( & result -> prettyName , "nushell" );
2024-01-12 21:13:59 +08:00
else if ( ffStrbufEqualS ( & result -> processName , "oil.ovm" ))
2024-01-12 20:42:33 +08:00
ffStrbufInitStatic ( & result -> prettyName , "Oils" );
2024-01-12 16:40:21 +08:00
else
{
// https://github.com/fastfetch-cli/fastfetch/discussions/280#discussioncomment-3831734
2024-01-12 20:42:33 +08:00
ffStrbufInitS ( & result -> prettyName , result -> exeName );
2024-01-12 16:40:21 +08:00
}
}
2024-01-12 20:42:33 +08:00
static void setTerminalInfoDetails ( FFTerminalResult * result )
2024-01-12 16:40:21 +08:00
{
2025-01-03 10:18:05 +08:00
if ( ffStrbufStartsWithC ( & result -> processName , '.' ) && ffStrbufContainS ( & result -> processName , "-wrap" ))
2024-01-12 16:40:21 +08:00
{
// For NixOS. Ref: #510 and https://github.com/NixOS/nixpkgs/pull/249428
2024-01-12 20:42:33 +08:00
// We use processName when detecting version and font, overriding it for simplification
2025-01-03 10:18:05 +08:00
ffStrbufSubstrBeforeLastC ( & result -> processName , '-' );
2024-04-27 23:12:45 +08:00
ffStrbufSubstrAfter ( & result -> processName , 0 );
2024-01-12 16:40:21 +08:00
}
2024-01-12 20:42:33 +08:00
if ( ffStrbufEqualS ( & result -> processName , "wezterm-gui" ))
ffStrbufInitStatic ( & result -> prettyName , "WezTerm" );
2024-01-14 17:26:54 +08:00
else if ( ffStrbufStartsWithS ( & result -> processName , "tmux:" ))
2024-01-12 20:42:33 +08:00
ffStrbufInitStatic ( & result -> prettyName , "tmux" );
2024-01-22 14:33:55 +08:00
else if ( ffStrbufStartsWithS ( & result -> processName , "screen-" ))
ffStrbufInitStatic ( & result -> prettyName , "screen" );
2024-07-26 23:52:39 +08:00
else if ( ffStrbufEqualS ( & result -> processName , "sshd" ) || ffStrbufStartsWithS ( & result -> processName , "sshd-" ))
ffStrbufInitCopy ( & result -> prettyName , & result -> tty );
2024-01-12 16:40:21 +08:00
#if defined(__ANDROID__)
2024-01-12 20:42:33 +08:00
else if ( ffStrbufEqualS ( & result -> processName , "com.termux" ))
ffStrbufInitStatic ( & result -> prettyName , "Termux" );
2024-01-12 16:40:21 +08:00
2025-08-24 21:40:22 +08:00
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__GNU__)
2024-01-12 16:40:21 +08:00
2024-01-22 10:20:50 +08:00
else if ( ffStrbufStartsWithS ( & result -> processName , "gnome-terminal" ))
2024-01-12 20:42:33 +08:00
ffStrbufInitStatic ( & result -> prettyName , "GNOME Terminal" );
else if ( ffStrbufStartsWithS ( & result -> processName , "kgx" ))
ffStrbufInitStatic ( & result -> prettyName , "GNOME Console" );
else if ( ffStrbufEqualS ( & result -> processName , "urxvt" ) ||
ffStrbufEqualS ( & result -> processName , "urxvtd" ) ||
ffStrbufEqualS ( & result -> processName , "rxvt" )
2024-01-12 16:40:21 +08:00
)
2024-01-12 20:42:33 +08:00
ffStrbufInitStatic ( & result -> prettyName , "rxvt-unicode" );
2024-07-01 23:56:19 +08:00
else if ( ffStrbufStartsWithS ( & result -> processName , "ptyxis-agent" ))
ffStrbufInitStatic ( & result -> prettyName , "Ptyxis" );
2024-01-12 16:40:21 +08:00
#elif defined(__APPLE__)
2024-01-12 20:42:33 +08:00
else if ( ffStrbufEqualS ( & result -> processName , "iTerm.app" ) || ffStrbufStartsWithS ( & result -> processName , "iTermServer-" ))
ffStrbufInitStatic ( & result -> prettyName , "iTerm" );
2024-05-05 13:35:39 +08:00
else if ( ffStrbufEndsWithS ( & result -> exePath , "Terminal.app/Contents/MacOS/Terminal" ))
{
2025-03-21 10:08:26 +08:00
ffStrbufSetStatic ( & result -> processName , "Apple_Terminal" ); // $TERM_PROGRAM, for terminal font detection
2024-05-05 13:35:39 +08:00
ffStrbufInitStatic ( & result -> prettyName , "Apple Terminal" );
}
2024-01-12 20:42:33 +08:00
else if ( ffStrbufEqualS ( & result -> processName , "Apple_Terminal" ))
ffStrbufInitStatic ( & result -> prettyName , "Apple Terminal" );
2025-03-21 10:08:26 +08:00
else if ( ffStrbufEndsWithS ( & result -> exePath , "Warp.app/Contents/MacOS/stable" ))
{
ffStrbufSetStatic ( & result -> processName , "WarpTerminal" ); // $TERM_PROGRAM, for terminal font detection
ffStrbufInitStatic ( & result -> prettyName , "Warp" );
}
2024-01-12 20:42:33 +08:00
else if ( ffStrbufEqualS ( & result -> processName , "WarpTerminal" ))
ffStrbufInitStatic ( & result -> prettyName , "Warp" );
2024-01-12 16:40:21 +08:00
2025-02-12 22:47:37 +00:00
#elif defined(__HAIKU__)
else if ( ffStrbufEqualS ( & result -> processName , "Terminal" ))
ffStrbufInitStatic ( & result -> prettyName , "Haiku Terminal" );
2024-01-12 16:40:21 +08:00
#endif
2024-01-12 20:42:33 +08:00
else if ( strncmp ( result -> exeName , result -> processName . chars , result -> processName . length ) == 0 ) // if exeName starts with processName, print it. Otherwise print processName
ffStrbufInitS ( & result -> prettyName , result -> exeName );
2024-01-12 16:40:21 +08:00
else
2024-01-12 20:42:33 +08:00
ffStrbufInitCopy ( & result -> prettyName , & result -> processName );
2024-01-12 16:40:21 +08:00
2024-01-12 20:42:33 +08:00
fftsGetTerminalVersion ( & result -> processName , & result -> exe , & result -> version );
2024-01-12 16:40:21 +08:00
}
2024-01-18 14:07:29 +08:00
#if defined(MAXPATH)
2024-01-12 20:42:33 +08:00
#define FF_EXE_PATH_LEN MAXPATH
#elif defined(PATH_MAX)
#define FF_EXE_PATH_LEN PATH_MAX
#else
#define FF_EXE_PATH_LEN 260
#endif
const FFShellResult * ffDetectShell ()
2021-06-14 23:22:14 +02:00
{
2024-01-12 20:42:33 +08:00
static FFShellResult result ;
2021-06-14 23:22:14 +02:00
static bool init = false ;
if ( init )
return & result ;
init = true ;
2024-01-12 20:42:33 +08:00
ffStrbufInit ( & result . processName );
ffStrbufInitA ( & result . exe , FF_EXE_PATH_LEN );
result . exeName = result . exe . chars ;
2024-01-19 10:50:02 +08:00
ffStrbufInit ( & result . exePath );
2024-01-12 20:42:33 +08:00
ffStrbufInit ( & result . version );
result . pid = 0 ;
result . ppid = 0 ;
2024-01-19 15:42:48 +08:00
result . tty = - 1 ;
2021-06-14 23:22:14 +02:00
2024-01-12 16:40:21 +08:00
pid_t ppid = getppid ();
2024-08-23 15:52:14 +08:00
const char * ignoreParent = getenv ( "FFTS_IGNORE_PARENT" );
if ( ignoreParent && ffStrEquals ( ignoreParent , "1" ))
{
FF_STRBUF_AUTO_DESTROY _ = ffStrbufCreate ();
ffProcessGetBasicInfoLinux ( ppid , & _ , & ppid , NULL );
}
2024-01-12 16:40:21 +08:00
ppid = getShellInfo ( & result , ppid );
2023-06-24 10:59:53 +08:00
getUserShellFromEnv ( & result );
2024-01-12 16:40:21 +08:00
setShellInfoDetails ( & result );
2021-06-14 23:22:14 +02:00
2024-01-12 20:42:33 +08:00
return & result ;
}
const FFTerminalResult * ffDetectTerminal ()
{
static FFTerminalResult result ;
static bool init = false ;
if ( init )
return & result ;
init = true ;
ffStrbufInit ( & result . processName );
ffStrbufInitA ( & result . exe , FF_EXE_PATH_LEN );
result . exeName = result . exe . chars ;
2024-01-19 10:50:02 +08:00
ffStrbufInit ( & result . exePath );
ffStrbufInit ( & result . version );
2024-02-27 16:19:36 +08:00
ffStrbufInitS ( & result . tty , ttyname ( STDOUT_FILENO ));
2024-01-12 20:42:33 +08:00
result . pid = 0 ;
result . ppid = 0 ;
pid_t ppid = ( pid_t ) ffDetectShell () -> ppid ;
2024-01-12 16:40:21 +08:00
if ( ppid )
ppid = getTerminalInfo ( & result , ppid );
getTerminalFromEnv ( & result );
setTerminalInfoDetails ( & result );
2023-01-10 19:24:59 +08:00
2021-06-14 23:22:14 +02:00
return & result ;
}