mirror of
https://github.com/tmux/tmux.git
synced 2024-12-04 19:58:48 +00:00
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:
parent
1e303b6a9d
commit
37b27d2eef
15
Makefile.am
15
Makefile.am
@ -11,10 +11,15 @@ dist_EXTRA_tmux_SOURCES = compat/*.[ch]
|
||||
# Preprocessor flags.
|
||||
AM_CPPFLAGS += @XOPEN_DEFINES@ \
|
||||
-DTMUX_VERSION='"@VERSION@"' \
|
||||
-DTMUX_CONF='"$(sysconfdir)/tmux.conf:~/.tmux.conf:$$XDG_CONFIG_HOME/tmux/tmux.conf:~/.config/tmux/tmux.conf"' \
|
||||
-DTMUX_LOCK_CMD='"@DEFAULT_LOCK_CMD@"' \
|
||||
-DTMUX_TERM='"@DEFAULT_TERM@"'
|
||||
|
||||
AM_CPPFLAGS += -DTMUX_CONF='"$(sysconfdir)/tmux.conf:~/.tmux.conf:$$XDG_CONFIG_HOME/tmux/tmux.conf:~/.config/tmux/tmux.conf"'
|
||||
|
||||
if TARGET_WIN32
|
||||
AM_CPPFLAGS += -DTMUX_CONF_WIN32='"/c/ProgramData/tmux/tmux.conf:~/.tmux.conf:$$LOCALAPPDATA/tmux/tmux.conf"'
|
||||
endif
|
||||
|
||||
# Additional object files.
|
||||
LDADD = $(LIBOBJS)
|
||||
|
||||
@ -67,7 +72,7 @@ AM_CPPFLAGS += -D_BSD_SOURCE
|
||||
endif
|
||||
|
||||
# Set flags for Cygwin.
|
||||
if IS_CYGWIN
|
||||
if TARGET_WIN32
|
||||
AM_CPPFLAGS += -DTMUX_SOCK_PERM=0
|
||||
endif
|
||||
|
||||
@ -227,6 +232,12 @@ if ENABLE_SIXEL
|
||||
dist_tmux_SOURCES += image.c image-sixel.c
|
||||
endif
|
||||
|
||||
# Windows-specific support.
|
||||
if TARGET_WIN32
|
||||
dist_tmux_SOURCES += osdep-win32.c osdep-win32-cpp.cpp
|
||||
LDADD += -lole32 -loleaut32 -lwbemuuid
|
||||
endif
|
||||
|
||||
if NEED_FUZZING
|
||||
check_PROGRAMS = fuzz/input-fuzzer
|
||||
fuzz_input_fuzzer_LDFLAGS = $(FUZZING_LIBS)
|
||||
|
54
compat.h
54
compat.h
@ -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 */
|
||||
|
251
configure.ac
251
configure.ac
@ -3,12 +3,13 @@
|
||||
AC_INIT([tmux], next-3.6)
|
||||
AC_PREREQ([2.60])
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
AC_CANONICAL_TARGET
|
||||
|
||||
AC_CONFIG_AUX_DIR(etc)
|
||||
AC_CONFIG_LIBOBJ_DIR(compat)
|
||||
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
# When CFLAGS isn't set at this stage and gcc is detected by the macro below,
|
||||
# autoconf will automatically use CFLAGS="-O2 -g". Prevent that by using an
|
||||
# empty default.
|
||||
@ -41,10 +42,136 @@ if test "x$enable_fuzzing" = xyes; then
|
||||
AM_CFLAGS="-g -fsanitize=fuzzer-no-link,address"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
utf8proc,
|
||||
AS_HELP_STRING(--enable-utf8proc, use utf8proc if it is installed)
|
||||
)
|
||||
|
||||
# Figure out the platform.
|
||||
AC_MSG_CHECKING(platform)
|
||||
case "$target_os" in
|
||||
*aix*)
|
||||
AC_MSG_RESULT(aix)
|
||||
PLATFORM=aix
|
||||
;;
|
||||
*darwin*)
|
||||
AC_MSG_RESULT(darwin)
|
||||
PLATFORM=darwin
|
||||
#
|
||||
# macOS uses __dead2 instead of __dead, like FreeBSD. But it defines
|
||||
# __dead away so it needs to be removed before we can replace it.
|
||||
#
|
||||
AC_DEFINE(BROKEN___DEAD)
|
||||
#
|
||||
# macOS CMSG_FIRSTHDR is broken, so redefine it with a working one.
|
||||
# daemon works but has some stupid side effects, so use our internal
|
||||
# version which has a workaround.
|
||||
#
|
||||
AC_DEFINE(BROKEN_CMSG_FIRSTHDR)
|
||||
AC_LIBOBJ(daemon)
|
||||
AC_LIBOBJ(daemon-darwin)
|
||||
#
|
||||
# macOS wcwidth(3) is bad, so complain and suggest using utf8proc
|
||||
# instead.
|
||||
#
|
||||
if test "x$enable_utf8proc" = x; then
|
||||
AC_MSG_NOTICE([])
|
||||
AC_MSG_NOTICE([ macOS library support for Unicode is very poor,])
|
||||
AC_MSG_NOTICE([ particularly for complex codepoints like emojis;])
|
||||
AC_MSG_NOTICE([ to use these correctly, configuring with])
|
||||
AC_MSG_NOTICE([ --enable-utf8proc is recommended. To build])
|
||||
AC_MSG_NOTICE([ without anyway, use --disable-utf8proc])
|
||||
AC_MSG_NOTICE([])
|
||||
AC_MSG_ERROR([must give --enable-utf8proc or --disable-utf8proc])
|
||||
fi
|
||||
;;
|
||||
*dragonfly*)
|
||||
AC_MSG_RESULT(dragonfly)
|
||||
PLATFORM=dragonfly
|
||||
;;
|
||||
*linux*)
|
||||
AC_MSG_RESULT(linux)
|
||||
PLATFORM=linux
|
||||
;;
|
||||
*freebsd*)
|
||||
AC_MSG_RESULT(freebsd)
|
||||
PLATFORM=freebsd
|
||||
;;
|
||||
*netbsd*)
|
||||
AC_MSG_RESULT(netbsd)
|
||||
PLATFORM=netbsd
|
||||
;;
|
||||
*openbsd*)
|
||||
AC_MSG_RESULT(openbsd)
|
||||
PLATFORM=openbsd
|
||||
;;
|
||||
*sunos*)
|
||||
AC_MSG_RESULT(sunos)
|
||||
PLATFORM=sunos
|
||||
;;
|
||||
*solaris*)
|
||||
AC_MSG_RESULT(sunos)
|
||||
PLATFORM=sunos
|
||||
case `/usr/bin/nroff --version 2>&1` in
|
||||
*GNU*)
|
||||
# Solaris 11.4 and later use GNU groff.
|
||||
MANFORMAT=mdoc
|
||||
;;
|
||||
*)
|
||||
if test `uname -o 2>/dev/null` = illumos; then
|
||||
# Illumos uses mandoc.
|
||||
MANFORMAT=mdoc
|
||||
else
|
||||
# Solaris 2.0 to 11.3 use AT&T nroff.
|
||||
MANFORMAT=man
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*hpux*)
|
||||
AC_MSG_RESULT(hpux)
|
||||
PLATFORM=hpux
|
||||
;;
|
||||
*cygwin*|*msys*)
|
||||
AC_MSG_RESULT(cygwin)
|
||||
PLATFORM=cygwin
|
||||
TARGET_WIN32=yes
|
||||
AC_DEFINE(TARGET_WIN32)
|
||||
AM_CONDITIONAL(TARGET_WIN32, test "x$TARGET_WIN32" = xyes)
|
||||
;;
|
||||
*haiku*)
|
||||
AC_MSG_RESULT(haiku)
|
||||
PLATFORM=haiku
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(unknown)
|
||||
PLATFORM=unknown
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(PLATFORM)
|
||||
AM_CONDITIONAL(IS_AIX, test "x$PLATFORM" = xaix)
|
||||
AM_CONDITIONAL(IS_DARWIN, test "x$PLATFORM" = xdarwin)
|
||||
AM_CONDITIONAL(IS_DRAGONFLY, test "x$PLATFORM" = xdragonfly)
|
||||
AM_CONDITIONAL(IS_LINUX, test "x$PLATFORM" = xlinux)
|
||||
AM_CONDITIONAL(IS_FREEBSD, test "x$PLATFORM" = xfreebsd)
|
||||
AM_CONDITIONAL(IS_NETBSD, test "x$PLATFORM" = xnetbsd)
|
||||
AM_CONDITIONAL(IS_OPENBSD, test "x$PLATFORM" = xopenbsd)
|
||||
AM_CONDITIONAL(IS_SUNOS, test "x$PLATFORM" = xsunos)
|
||||
AM_CONDITIONAL(IS_HPUX, test "x$PLATFORM" = xhpux)
|
||||
AM_CONDITIONAL(IS_CYGWIN, test "x$PLATFORM" = xcygwin)
|
||||
AM_CONDITIONAL(IS_HAIKU, test "x$PLATFORM" = xhaiku)
|
||||
AM_CONDITIONAL(IS_UNKNOWN, test "x$PLATFORM" = xunknown)
|
||||
|
||||
|
||||
# Set up the compiler in two different ways and say yes we may want to install.
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
m4_version_prereq(2.70, [AC_PROG_CC], [AC_PROG_CC_C99])
|
||||
|
||||
if test "x$TARGET_WIN32" = xyes; then
|
||||
AC_PROG_CXX
|
||||
CFLAGS="$CFLAGS -isystem $(dirname $(readlink -f $0))/third_party/mingw_headers"
|
||||
CXXFLAGS="$CXXFLAGS -std=c++17 -isystem $(dirname $(readlink -f $0))/third_party/mingw_headers -O2 -fpermissive -Wno-write-strings -Wno-class-conversion"
|
||||
fi
|
||||
|
||||
AC_PROG_CPP
|
||||
AC_PROG_EGREP
|
||||
AC_PROG_INSTALL
|
||||
@ -381,10 +508,6 @@ if test "x$enable_utempter" = xyes; then
|
||||
fi
|
||||
|
||||
# Look for utf8proc.
|
||||
AC_ARG_ENABLE(
|
||||
utf8proc,
|
||||
AS_HELP_STRING(--enable-utf8proc, use utf8proc if it is installed)
|
||||
)
|
||||
if test "x$enable_utf8proc" = xyes; then
|
||||
PKG_CHECK_MODULES(
|
||||
LIBUTF8PROC,
|
||||
@ -874,118 +997,6 @@ AC_SUBST(DEFAULT_TERM)
|
||||
MANFORMAT=mdoc
|
||||
AC_SUBST(MANFORMAT)
|
||||
|
||||
# Figure out the platform.
|
||||
AC_MSG_CHECKING(platform)
|
||||
case "$host_os" in
|
||||
*aix*)
|
||||
AC_MSG_RESULT(aix)
|
||||
PLATFORM=aix
|
||||
;;
|
||||
*darwin*)
|
||||
AC_MSG_RESULT(darwin)
|
||||
PLATFORM=darwin
|
||||
#
|
||||
# macOS uses __dead2 instead of __dead, like FreeBSD. But it defines
|
||||
# __dead away so it needs to be removed before we can replace it.
|
||||
#
|
||||
AC_DEFINE(BROKEN___DEAD)
|
||||
#
|
||||
# macOS CMSG_FIRSTHDR is broken, so redefine it with a working one.
|
||||
# daemon works but has some stupid side effects, so use our internal
|
||||
# version which has a workaround.
|
||||
#
|
||||
AC_DEFINE(BROKEN_CMSG_FIRSTHDR)
|
||||
AC_LIBOBJ(daemon)
|
||||
AC_LIBOBJ(daemon-darwin)
|
||||
#
|
||||
# macOS wcwidth(3) is bad, so complain and suggest using utf8proc
|
||||
# instead.
|
||||
#
|
||||
if test "x$enable_utf8proc" = x; then
|
||||
AC_MSG_NOTICE([])
|
||||
AC_MSG_NOTICE([ macOS library support for Unicode is very poor,])
|
||||
AC_MSG_NOTICE([ particularly for complex codepoints like emojis;])
|
||||
AC_MSG_NOTICE([ to use these correctly, configuring with])
|
||||
AC_MSG_NOTICE([ --enable-utf8proc is recommended. To build])
|
||||
AC_MSG_NOTICE([ without anyway, use --disable-utf8proc])
|
||||
AC_MSG_NOTICE([])
|
||||
AC_MSG_ERROR([must give --enable-utf8proc or --disable-utf8proc])
|
||||
fi
|
||||
;;
|
||||
*dragonfly*)
|
||||
AC_MSG_RESULT(dragonfly)
|
||||
PLATFORM=dragonfly
|
||||
;;
|
||||
*linux*)
|
||||
AC_MSG_RESULT(linux)
|
||||
PLATFORM=linux
|
||||
;;
|
||||
*freebsd*)
|
||||
AC_MSG_RESULT(freebsd)
|
||||
PLATFORM=freebsd
|
||||
;;
|
||||
*netbsd*)
|
||||
AC_MSG_RESULT(netbsd)
|
||||
PLATFORM=netbsd
|
||||
;;
|
||||
*openbsd*)
|
||||
AC_MSG_RESULT(openbsd)
|
||||
PLATFORM=openbsd
|
||||
;;
|
||||
*sunos*)
|
||||
AC_MSG_RESULT(sunos)
|
||||
PLATFORM=sunos
|
||||
;;
|
||||
*solaris*)
|
||||
AC_MSG_RESULT(sunos)
|
||||
PLATFORM=sunos
|
||||
case `/usr/bin/nroff --version 2>&1` in
|
||||
*GNU*)
|
||||
# Solaris 11.4 and later use GNU groff.
|
||||
MANFORMAT=mdoc
|
||||
;;
|
||||
*)
|
||||
if test `uname -o 2>/dev/null` = illumos; then
|
||||
# Illumos uses mandoc.
|
||||
MANFORMAT=mdoc
|
||||
else
|
||||
# Solaris 2.0 to 11.3 use AT&T nroff.
|
||||
MANFORMAT=man
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*hpux*)
|
||||
AC_MSG_RESULT(hpux)
|
||||
PLATFORM=hpux
|
||||
;;
|
||||
*cygwin*|*msys*)
|
||||
AC_MSG_RESULT(cygwin)
|
||||
PLATFORM=cygwin
|
||||
;;
|
||||
*haiku*)
|
||||
AC_MSG_RESULT(haiku)
|
||||
PLATFORM=haiku
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(unknown)
|
||||
PLATFORM=unknown
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(PLATFORM)
|
||||
AM_CONDITIONAL(IS_AIX, test "x$PLATFORM" = xaix)
|
||||
AM_CONDITIONAL(IS_DARWIN, test "x$PLATFORM" = xdarwin)
|
||||
AM_CONDITIONAL(IS_DRAGONFLY, test "x$PLATFORM" = xdragonfly)
|
||||
AM_CONDITIONAL(IS_LINUX, test "x$PLATFORM" = xlinux)
|
||||
AM_CONDITIONAL(IS_FREEBSD, test "x$PLATFORM" = xfreebsd)
|
||||
AM_CONDITIONAL(IS_NETBSD, test "x$PLATFORM" = xnetbsd)
|
||||
AM_CONDITIONAL(IS_OPENBSD, test "x$PLATFORM" = xopenbsd)
|
||||
AM_CONDITIONAL(IS_SUNOS, test "x$PLATFORM" = xsunos)
|
||||
AM_CONDITIONAL(IS_HPUX, test "x$PLATFORM" = xhpux)
|
||||
AM_CONDITIONAL(IS_CYGWIN, test "x$PLATFORM" = xcygwin)
|
||||
AM_CONDITIONAL(IS_HAIKU, test "x$PLATFORM" = xhaiku)
|
||||
AM_CONDITIONAL(IS_UNKNOWN, test "x$PLATFORM" = xunknown)
|
||||
|
||||
# Set the default lock command
|
||||
DEFAULT_LOCK_CMD="lock -np"
|
||||
AC_MSG_CHECKING(lock-command)
|
||||
|
87
osdep-win32-cpp.cpp
Normal file
87
osdep-win32-cpp.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
#include <cwchar>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define _WIN32_DCOM
|
||||
|
||||
#define sprintf_s sprintf
|
||||
|
||||
#include <windows.h>
|
||||
#include <comutil.h>
|
||||
#include <stringapiset.h>
|
||||
#include <tlhelp32.h>
|
||||
#include <wbemidl.h>
|
||||
|
||||
void
|
||||
win32_setenv_shell_impl(void);
|
||||
|
||||
void
|
||||
win32_setenv_shell_impl(void)
|
||||
{
|
||||
unsigned pid = GetCurrentProcessId();
|
||||
int ppid = -1;
|
||||
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
PROCESSENTRY32 pe = { 0 };
|
||||
IWbemLocator* wbem_locator = nullptr;
|
||||
IWbemServices* wbem_services = nullptr;
|
||||
IEnumWbemClassObject* enum_wbem = nullptr;
|
||||
|
||||
pe.dwSize = sizeof(PROCESSENTRY32);
|
||||
|
||||
if (Process32First(h, &pe)) {
|
||||
do {
|
||||
if (pe.th32ProcessID == pid)
|
||||
ppid = pe.th32ParentProcessID;
|
||||
} while (Process32Next(h, &pe));
|
||||
}
|
||||
|
||||
CloseHandle(h);
|
||||
|
||||
CoInitializeEx(0, COINIT_MULTITHREADED);
|
||||
CoInitializeSecurity(nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE, nullptr);
|
||||
CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&wbem_locator);
|
||||
|
||||
wbem_locator->ConnectServer(L"ROOT\\CIMV2", nullptr, nullptr, nullptr, 0, nullptr, nullptr, &wbem_services);
|
||||
wchar_t* query = new wchar_t[4096];
|
||||
swprintf(query, 4096, L"select commandline from win32_process where processid = %d", ppid);
|
||||
wbem_services->ExecQuery(L"WQL", query, WBEM_FLAG_FORWARD_ONLY, nullptr, &enum_wbem);
|
||||
delete[] query;
|
||||
|
||||
if (enum_wbem) {
|
||||
IWbemClassObject *result = nullptr;
|
||||
ULONG returned_count = 0;
|
||||
|
||||
if(enum_wbem->Next(WBEM_INFINITE, 1, &result, &returned_count) == S_OK) {
|
||||
VARIANT process_id;
|
||||
VARIANT command_line;
|
||||
|
||||
result->Get(L"CommandLine", 0, &command_line, 0, 0);
|
||||
|
||||
wchar_t* command_line_utf16 = command_line.bstrVal;
|
||||
size_t size = WideCharToMultiByte(CP_UTF8, 0, command_line_utf16, -1, nullptr, 0, nullptr, nullptr) + 1;
|
||||
char* command_line_utf8 = new char[size];
|
||||
|
||||
WideCharToMultiByte(CP_UTF8, 0, command_line_utf16, -1, command_line_utf8, size, nullptr, nullptr);
|
||||
|
||||
SysFreeString(command_line_utf16);
|
||||
|
||||
setenv("SHELL", command_line_utf8, 1);
|
||||
|
||||
delete[] command_line_utf8;
|
||||
|
||||
result->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
void
|
||||
win32_setenv_shell(void);
|
||||
|
||||
void
|
||||
win32_setenv_shell(void)
|
||||
{
|
||||
win32_setenv_shell_impl();
|
||||
}
|
||||
|
||||
}
|
101
osdep-win32.c
Normal file
101
osdep-win32.c
Normal file
@ -0,0 +1,101 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tmux.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
static int in_cygwin_virtual_filesystem(void);
|
||||
|
||||
#define PROFILE_TMPDIR "/AppData/Local/Temp/"
|
||||
|
||||
static char tmpdir[4096] = {0};
|
||||
static char socket_dir[4096] = {0};
|
||||
static char tmpfile_template[4096] = {0};
|
||||
static int in_cygwin_fs = -1;
|
||||
|
||||
static int
|
||||
in_cygwin_virtual_filesystem(void)
|
||||
{
|
||||
if (in_cygwin_fs != -1)
|
||||
return in_cygwin_fs;
|
||||
|
||||
in_cygwin_fs = 0;
|
||||
|
||||
if (
|
||||
(access("/bin/sh", F_OK) == 0) &&
|
||||
(access("/usr", F_OK) == 0) &&
|
||||
(access("/home", F_OK) == 0) &&
|
||||
(access("/proc", F_OK) == 0) &&
|
||||
(access("/var", F_OK) == 0) &&
|
||||
(access("/tmp", F_OK) == 0) &&
|
||||
(access("/dev/null", F_OK) == 0) &&
|
||||
(access("/dev/random", F_OK) == 0) &&
|
||||
(access("/dev/stdout", F_OK) == 0) &&
|
||||
(access("/proc/stat", F_OK) == 0)
|
||||
) {
|
||||
in_cygwin_fs = 1;
|
||||
}
|
||||
|
||||
return in_cygwin_fs;
|
||||
}
|
||||
|
||||
const char *
|
||||
win32_get_tmpdir(void)
|
||||
{
|
||||
char *profile_dir = NULL;
|
||||
|
||||
if (*tmpdir)
|
||||
return tmpdir;
|
||||
|
||||
if (in_cygwin_virtual_filesystem()) {
|
||||
strncpy(tmpdir, "/tmp/", 4096);
|
||||
return tmpdir;
|
||||
}
|
||||
|
||||
if ((profile_dir = getenv("USERPROFILE")))
|
||||
snprintf(tmpdir, 4096, "%s%s", profile_dir, PROFILE_TMPDIR);
|
||||
|
||||
return tmpdir;
|
||||
}
|
||||
|
||||
const char *
|
||||
win32_get_socket_dir_search_path(void)
|
||||
{
|
||||
if (*socket_dir)
|
||||
return socket_dir;
|
||||
|
||||
snprintf(socket_dir, 4096, "$TMUX_TMPDIR:%s", win32_get_tmpdir());
|
||||
|
||||
return socket_dir;
|
||||
}
|
||||
|
||||
const char *
|
||||
win32_get_conf_search_path(void)
|
||||
{
|
||||
if (in_cygwin_virtual_filesystem())
|
||||
return TMUX_CONF;
|
||||
|
||||
return TMUX_CONF_WIN32;
|
||||
}
|
||||
|
||||
const char *
|
||||
win32_get_tmpfile_template(void)
|
||||
{
|
||||
if (*tmpfile_template)
|
||||
return tmpfile_template;
|
||||
|
||||
snprintf(tmpfile_template, 4096, "%s/tmux.XXXXXXXX", win32_get_tmpdir());
|
||||
|
||||
return tmpfile_template;
|
||||
}
|
||||
|
||||
const char *
|
||||
win32_get_shell_cmd_switch(const char *shell)
|
||||
{
|
||||
if (strstr(shell, "cmd.exe") != NULL)
|
||||
return "/c";
|
||||
else
|
||||
return "-c";
|
||||
}
|
4
popup.c
4
popup.c
@ -775,7 +775,7 @@ popup_editor(struct client *c, const char *buf, size_t len,
|
||||
int fd;
|
||||
FILE *f;
|
||||
char *cmd;
|
||||
char path[] = _PATH_TMP "tmux.XXXXXXXX";
|
||||
char *path = (char *)TMPFILE_TEMPLATE();
|
||||
const char *editor;
|
||||
u_int px, py, sx, sy;
|
||||
|
||||
@ -807,7 +807,7 @@ popup_editor(struct client *c, const char *buf, size_t len,
|
||||
|
||||
xasprintf(&cmd, "%s %s", editor, path);
|
||||
if (popup_display(POPUP_INTERNAL|POPUP_CLOSEEXIT, BOX_LINES_DEFAULT,
|
||||
NULL, px, py, sx, sy, NULL, cmd, 0, NULL, _PATH_TMP, NULL, c, NULL,
|
||||
NULL, px, py, sx, sy, NULL, cmd, 0, NULL, TMPDIR(), NULL, c, NULL,
|
||||
NULL, NULL, popup_editor_close_cb, pe) != 0) {
|
||||
popup_editor_free(pe);
|
||||
free(cmd);
|
||||
|
2
spawn.c
2
spawn.c
@ -456,7 +456,7 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
||||
xasprintf(&argv0, "%s", cp + 1);
|
||||
else
|
||||
xasprintf(&argv0, "%s", new_wp->shell);
|
||||
execl(new_wp->shell, argv0, "-c", tmp, (char *)NULL);
|
||||
execl(new_wp->shell, argv0, SHELL_CMD_SWITCH(new_wp->shell), tmp, (char *)NULL);
|
||||
_exit(1);
|
||||
}
|
||||
if (cp != NULL && cp[1] != '\0')
|
||||
|
1233
third_party/mingw_headers/comutil.h
vendored
Normal file
1233
third_party/mingw_headers/comutil.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
45
third_party/mingw_headers/new.h
vendored
Normal file
45
third_party/mingw_headers/new.h
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* This file has no copyright assigned and is placed in the Public Domain.
|
||||
* This file is part of the mingw-w64 runtime package.
|
||||
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
|
||||
*/
|
||||
#ifndef _INC_NEW
|
||||
#define _INC_NEW
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <crtdefs.h>
|
||||
|
||||
#pragma push_macro("new")
|
||||
#undef new
|
||||
|
||||
#ifndef __NOTHROW_T_DEFINED
|
||||
#define __NOTHROW_T_DEFINED
|
||||
#endif
|
||||
|
||||
#ifndef __PLACEMENT_NEW_INLINE
|
||||
#define __PLACEMENT_NEW_INLINE
|
||||
#endif
|
||||
|
||||
_CRTIMP int __cdecl _query_new_mode(void);
|
||||
_CRTIMP int __cdecl _set_new_mode(int _NewMode);
|
||||
|
||||
#ifndef _PNH_DEFINED
|
||||
typedef int (__cdecl *_PNH)(size_t);
|
||||
#define _PNH_DEFINED
|
||||
#endif
|
||||
|
||||
_CRTIMP _PNH __cdecl _query_new_handler(void);
|
||||
_CRTIMP _PNH __cdecl _set_new_handler(_PNH _NewHandler);
|
||||
|
||||
#ifndef _NO_ANSI_NH_DEFINED
|
||||
#define _NO_ANSI_NEW_HANDLER ((new_handler)-1)
|
||||
#define _NO_ANSI_NEW_HANDLER_M ((_new_handler_m)-1)
|
||||
#define _NO_ANSI_NH_DEFINED
|
||||
#endif
|
||||
|
||||
#pragma pop_macro("new")
|
||||
#endif
|
||||
#endif
|
6
tmux.c
6
tmux.c
@ -65,7 +65,7 @@ getshell(void)
|
||||
struct passwd *pw;
|
||||
const char *shell;
|
||||
|
||||
shell = getenv("SHELL");
|
||||
shell = GETENV_SHELL();
|
||||
if (checkshell(shell))
|
||||
return (shell);
|
||||
|
||||
@ -328,7 +328,7 @@ find_home(void)
|
||||
if (home != NULL)
|
||||
return (home);
|
||||
|
||||
home = getenv("HOME");
|
||||
home = GETENV_HOME();
|
||||
if (home == NULL || *home == '\0') {
|
||||
pw = getpwuid(getuid());
|
||||
if (pw != NULL)
|
||||
@ -377,7 +377,7 @@ main(int argc, char **argv)
|
||||
environ_put(global_environ, *var, 0);
|
||||
if ((cwd = find_cwd()) != NULL)
|
||||
environ_set(global_environ, "PWD", 0, "%s", cwd);
|
||||
expand_paths(TMUX_CONF, &cfg_files, &cfg_nfiles, 1);
|
||||
expand_paths(TMUX_CONF_SEARCH_PATH(), &cfg_files, &cfg_nfiles, 1);
|
||||
|
||||
while ((opt = getopt(argc, argv, "2c:CDdf:lL:NqS:T:uUvV")) != -1) {
|
||||
switch (opt) {
|
||||
|
3
tmux.h
3
tmux.h
@ -81,9 +81,6 @@ struct winlink;
|
||||
#ifndef TMUX_CONF
|
||||
#define TMUX_CONF "/etc/tmux.conf:~/.tmux.conf"
|
||||
#endif
|
||||
#ifndef TMUX_SOCK
|
||||
#define TMUX_SOCK "$TMUX_TMPDIR:" _PATH_TMP
|
||||
#endif
|
||||
#ifndef TMUX_SOCK_PERM
|
||||
#define TMUX_SOCK_PERM (7 /* o+rwx */)
|
||||
#endif
|
||||
|
21
tty-term.c
21
tty-term.c
@ -683,8 +683,9 @@ tty_term_read_list(const char *name, int fd, char ***caps, u_int *ncaps,
|
||||
u_int i;
|
||||
const char *s;
|
||||
char tmp[11];
|
||||
int retval = ERR;
|
||||
|
||||
if (setupterm((char *)name, fd, &error) != OK) {
|
||||
if ((retval = setupterm((char *)name, fd, &error)) != OK) {
|
||||
switch (error) {
|
||||
case 1:
|
||||
xasprintf(cause, "can't use hardcopy terminal: %s",
|
||||
@ -695,13 +696,25 @@ tty_term_read_list(const char *name, int fd, char ***caps, u_int *ncaps,
|
||||
name);
|
||||
break;
|
||||
case -1:
|
||||
xasprintf(cause, "can't find terminfo database");
|
||||
break;
|
||||
#ifdef WIN32_PLATFORM
|
||||
if ((retval = setupterm("#win32con", fd, &error)) != OK)
|
||||
{
|
||||
xasprintf(cause, "can't set up Win32 console");
|
||||
break;
|
||||
}
|
||||
#else
|
||||
{
|
||||
xasprintf(cause, "can't find terminfo database");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
xasprintf(cause, "unknown error");
|
||||
break;
|
||||
}
|
||||
return (-1);
|
||||
|
||||
if (retval != OK)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
*ncaps = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user