Support use as a Windows program outside of Cygwin

If `getenv("SHELL")` is `NULL`, use the function `win32_setenv_shell()`
added to `osdep-win32-cpp.cpp` to set it using the command line of the
parent process, which is retrieved using WMI WIN32 API.

This is a C++ file because the OLE/WMI API is only available for C++.
Adjust the autotools code to add this file and link the necessary
Windows DLLs.

Include some fixed/missing MINGW headers necessary to compile this file.
This will be fixed in the relevant places and they will be removed.

Add a new macro WIN32_PLATFORM for Windows specific functionality, currently
Cygwin and MSYS2, in the future for the native port as well.

When spawning commands using the shell, check for cmd.exe on Windows and
use the `/c` switch, otherwise use `-c` which works for PowerShell,
MSYS2, Cygwin and Git Bash etc..

Adjust code that uses `/tmp/` to use
`$env:USERPROFILE/AppData/Local/Temp/` outside of a Cygwin virtual
filesystem when `/tmp/` is not available, add the function
`win32_get_tmpdir()` and related functions to `osdep-win32.c` for this.

Use `getenv("USERPROFILE")` when `getenv("HOME")` is `NULL`.

When outside of a Cygwin virtual filesystem, use
`C:\ProgramData\tmux\tmux.conf:$USERPROFILE\.tmux.conf:$LOCALAPPDATA\tmux\tmux.conf`
as the config search order.

Use the ncurses term-driver with `TERM="#win32con"` when a terminfo
database is not available. This will require patches to ncurses as well
as MSYS2 and Cygwin to work.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
This commit is contained in:
Rafael Kitover
2024-08-24 05:44:45 +00:00
parent 1e303b6a9d
commit 37b27d2eef
12 changed files with 1683 additions and 139 deletions

View File

@@ -69,6 +69,11 @@
#define __weak __attribute__ ((__weak__))
#endif
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MSYS__)
#define WIN32_PLATFORM
#define TTY_OVER_SOCKET
#endif
#ifndef ECHOPRT
#define ECHOPRT 0
#endif
@@ -98,10 +103,6 @@ void warnx(const char *, ...);
#define _PATH_BSHELL "/bin/sh"
#endif
#ifndef _PATH_TMP
#define _PATH_TMP "/tmp/"
#endif
#ifndef _PATH_DEVNULL
#define _PATH_DEVNULL "/dev/null"
#endif
@@ -471,4 +472,49 @@ int BSDgetopt(int, char *const *, const char *);
#define optreset BSDoptreset
#define optarg BSDoptarg
#ifndef WIN32_PLATFORM
#ifndef TMUX_CONF_WIN32
#define TMUX_CONF_WIN32 "/c/ProgramData/tmux/tmux.conf:~/.tmux.conf"
#endif
#define SHELL_CMD_SWITCH(shell) "-c"
#define TMPDIR() "/tmp/"
#ifndef TMUX_SOCK
#define TMUX_SOCK "$TMUX_TMPDIR:" TMPDIR
#endif
#define TMPFILE_TEMPLATE() TMPDIR() "tmux.XXXXXXXX"
#define GETENV_HOME() getenv("HOME")
#define GETENV_SHELL() getenv("SHELL")
#define TMUX_CONF_SEARCH_PATH() TMUX_CONF
#else
void win32_setenv_shell(void);
const char *win32_get_tmpdir(void);
const char *win32_get_tmpfile_template(void);
const char *win32_get_socket_dir_search_path(void);
const char *win32_get_conf_search_path(void);
const char *win32_get_shell_cmd_switch(const char *);
#define SHELL_CMD_SWITCH(shell) win32_get_shell_cmd_switch(shell)
#define TMPDIR() win32_get_tmpdir()
#ifndef TMUX_SOCK
#define TMUX_SOCK win32_get_socket_dir_search_path()
#endif
#define TMPFILE_TEMPLATE() win32_get_tmpfile_template()
#define GETENV_HOME() (getenv("HOME") ? getenv("HOME") : getenv("USERPROFILE"))
#define GETENV_SHELL() (getenv("SHELL") ? getenv("SHELL") : (win32_setenv_shell(), getenv("SHELL")))
#define TMUX_CONF_SEARCH_PATH() win32_get_conf_search_path()
#endif
#endif /* COMPAT_H */