blob: 9dded854859d7f173dc69ea4666c222458b2b079 [file] [log] [blame]
Bram Moolenaar97ff9b92016-06-26 20:37:46 +02001/*
2 * iscygpty.c -- part of ptycheck
3 * https://github.com/k-takata/ptycheck
4 *
Bram Moolenaar9e8dcf92017-08-31 21:35:45 +02005 * Copyright (c) 2015-2017 K.Takata
Bram Moolenaar97ff9b92016-06-26 20:37:46 +02006 *
7 * You can redistribute it and/or modify it under the terms of either
8 * the MIT license (as described below) or the Vim license.
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining
11 * a copy of this software and associated documentation files (the
12 * "Software"), to deal in the Software without restriction, including
13 * without limitation the rights to use, copy, modify, merge, publish,
14 * distribute, sublicense, and/or sell copies of the Software, and to
15 * permit persons to whom the Software is furnished to do so, subject to
16 * the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
25 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 */
29
Bram Moolenaar9e8dcf92017-08-31 21:35:45 +020030#ifdef _WIN32
31
Bram Moolenaar97ff9b92016-06-26 20:37:46 +020032#include <ctype.h>
33#include <io.h>
34#include <wchar.h>
35#include <windows.h>
36
37#ifdef USE_FILEEXTD
Bram Moolenaaraa2f0ee2019-12-21 18:47:26 +010038// VC 7.1 or earlier doesn't support SAL.
Bram Moolenaar97ff9b92016-06-26 20:37:46 +020039# if !defined(_MSC_VER) || (_MSC_VER < 1400)
40# define __out
41# define __in
42# define __in_opt
43# endif
Bram Moolenaaraa2f0ee2019-12-21 18:47:26 +010044// Win32 FileID API Library:
45// http://www.microsoft.com/en-us/download/details.aspx?id=22599
46// Needed for WinXP.
Bram Moolenaar97ff9b92016-06-26 20:37:46 +020047# include <fileextd.h>
Bram Moolenaaraa2f0ee2019-12-21 18:47:26 +010048#else // USE_FILEEXTD
49// VC 8 or earlier.
Bram Moolenaar97ff9b92016-06-26 20:37:46 +020050# if defined(_MSC_VER) && (_MSC_VER < 1500)
51# ifdef ENABLE_STUB_IMPL
52# define STUB_IMPL
53# else
54# error "Win32 FileID API Library is required for VC2005 or earlier."
55# endif
56# endif
Bram Moolenaaraa2f0ee2019-12-21 18:47:26 +010057#endif // USE_FILEEXTD
Bram Moolenaar97ff9b92016-06-26 20:37:46 +020058
Bram Moolenaar35d7a2f2022-06-09 20:53:54 +010059#ifdef __MINGW32__
60# define UNUSED __attribute__((unused))
61#else
62# define UNUSED
63#endif
Bram Moolenaar97ff9b92016-06-26 20:37:46 +020064
65#include "iscygpty.h"
66
67//#define USE_DYNFILEID
68#ifdef USE_DYNFILEID
69typedef BOOL (WINAPI *pfnGetFileInformationByHandleEx)(
Bram Moolenaar792f0e32018-02-27 17:27:13 +010070 HANDLE hFile,
71 FILE_INFO_BY_HANDLE_CLASS FileInformationClass,
72 LPVOID lpFileInformation,
73 DWORD dwBufferSize);
Bram Moolenaar97ff9b92016-06-26 20:37:46 +020074static pfnGetFileInformationByHandleEx pGetFileInformationByHandleEx = NULL;
75
76# ifndef USE_FILEEXTD
77static BOOL WINAPI stub_GetFileInformationByHandleEx(
Bram Moolenaar35d7a2f2022-06-09 20:53:54 +010078 HANDLE hFile UNUSED,
79 FILE_INFO_BY_HANDLE_CLASS FileInformationClass UNUSED,
80 LPVOID lpFileInformation UNUSED,
81 DWORD dwBufferSize UNUSED)
Bram Moolenaar97ff9b92016-06-26 20:37:46 +020082{
83 return FALSE;
84}
85# endif
86
87static void setup_fileid_api(void)
88{
89 if (pGetFileInformationByHandleEx != NULL) {
90 return;
91 }
92 pGetFileInformationByHandleEx = (pfnGetFileInformationByHandleEx)
93 GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
94 "GetFileInformationByHandleEx");
95 if (pGetFileInformationByHandleEx == NULL) {
96# ifdef USE_FILEEXTD
97 pGetFileInformationByHandleEx = GetFileInformationByHandleEx;
98# else
99 pGetFileInformationByHandleEx = stub_GetFileInformationByHandleEx;
100# endif
101 }
102}
103#else
104# define pGetFileInformationByHandleEx GetFileInformationByHandleEx
105# define setup_fileid_api()
106#endif
107
108
109#define is_wprefix(s, prefix) \
110 (wcsncmp((s), (prefix), sizeof(prefix) / sizeof(WCHAR) - 1) == 0)
111
Bram Moolenaaraa2f0ee2019-12-21 18:47:26 +0100112// Check if the fd is a cygwin/msys's pty.
Bram Moolenaar97ff9b92016-06-26 20:37:46 +0200113int is_cygpty(int fd)
114{
115#ifdef STUB_IMPL
116 return 0;
117#else
118 HANDLE h;
Bram Moolenaar9e8dcf92017-08-31 21:35:45 +0200119 int size = sizeof(FILE_NAME_INFO) + sizeof(WCHAR) * (MAX_PATH - 1);
Bram Moolenaar97ff9b92016-06-26 20:37:46 +0200120 FILE_NAME_INFO *nameinfo;
121 WCHAR *p = NULL;
122
123 setup_fileid_api();
124
125 h = (HANDLE) _get_osfhandle(fd);
126 if (h == INVALID_HANDLE_VALUE) {
127 return 0;
128 }
Bram Moolenaaraa2f0ee2019-12-21 18:47:26 +0100129 // Cygwin/msys's pty is a pipe.
Bram Moolenaar97ff9b92016-06-26 20:37:46 +0200130 if (GetFileType(h) != FILE_TYPE_PIPE) {
131 return 0;
132 }
Bram Moolenaar9e8dcf92017-08-31 21:35:45 +0200133 nameinfo = malloc(size + sizeof(WCHAR));
Bram Moolenaar97ff9b92016-06-26 20:37:46 +0200134 if (nameinfo == NULL) {
135 return 0;
136 }
Bram Moolenaaraa2f0ee2019-12-21 18:47:26 +0100137 // Check the name of the pipe:
138 // '\{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master'
Bram Moolenaar97ff9b92016-06-26 20:37:46 +0200139 if (pGetFileInformationByHandleEx(h, FileNameInfo, nameinfo, size)) {
140 nameinfo->FileName[nameinfo->FileNameLength / sizeof(WCHAR)] = L'\0';
141 p = nameinfo->FileName;
Bram Moolenaaraa2f0ee2019-12-21 18:47:26 +0100142 if (is_wprefix(p, L"\\cygwin-")) { // Cygwin
Bram Moolenaar97ff9b92016-06-26 20:37:46 +0200143 p += 8;
Bram Moolenaaraa2f0ee2019-12-21 18:47:26 +0100144 } else if (is_wprefix(p, L"\\msys-")) { // MSYS and MSYS2
Bram Moolenaar97ff9b92016-06-26 20:37:46 +0200145 p += 6;
146 } else {
147 p = NULL;
148 }
149 if (p != NULL) {
Bram Moolenaaraa2f0ee2019-12-21 18:47:26 +0100150 while (*p && isxdigit(*p)) // Skip 16-digit hexadecimal.
Bram Moolenaar97ff9b92016-06-26 20:37:46 +0200151 ++p;
152 if (is_wprefix(p, L"-pty")) {
153 p += 4;
154 } else {
155 p = NULL;
156 }
157 }
158 if (p != NULL) {
Bram Moolenaaraa2f0ee2019-12-21 18:47:26 +0100159 while (*p && isdigit(*p)) // Skip pty number.
Bram Moolenaar97ff9b92016-06-26 20:37:46 +0200160 ++p;
161 if (is_wprefix(p, L"-from-master")) {
162 //p += 12;
163 } else if (is_wprefix(p, L"-to-master")) {
164 //p += 10;
165 } else {
166 p = NULL;
167 }
168 }
169 }
170 free(nameinfo);
171 return (p != NULL);
Bram Moolenaaraa2f0ee2019-12-21 18:47:26 +0100172#endif // STUB_IMPL
Bram Moolenaar97ff9b92016-06-26 20:37:46 +0200173}
174
Bram Moolenaaraa2f0ee2019-12-21 18:47:26 +0100175// Check if at least one cygwin/msys pty is used.
Bram Moolenaar97ff9b92016-06-26 20:37:46 +0200176int is_cygpty_used(void)
177{
178 int fd, ret = 0;
179
180 for (fd = 0; fd < 3; fd++) {
181 ret |= is_cygpty(fd);
182 }
183 return ret;
184}
185
Bram Moolenaaraa2f0ee2019-12-21 18:47:26 +0100186#endif // _WIN32
Bram Moolenaar9e8dcf92017-08-31 21:35:45 +0200187
Bram Moolenaaraa2f0ee2019-12-21 18:47:26 +0100188// vim: set ts=4 sw=4: