• R/O
  • SSH
  • HTTPS

ttssh2: Commit


Commit MetaInfo

Revision9518 (tree)
Time2021-11-10 22:01:44
Authorzmatsuo

Log Message

cygwin/cyglib に複数個所に重複したコードを移動

- cyglaunch,ttermpro から利用
- パス、ファイル名をUnicode化
- cyglaunch の main() を wmain() へ変更

Change Summary

Incremental Difference

--- trunk/cygwin/CMakeLists.txt (revision 9517)
+++ trunk/cygwin/CMakeLists.txt (revision 9518)
@@ -3,7 +3,20 @@
33 cyglaunch
44 PROPERTIES FOLDER cygwin)
55
6+add_subdirectory(cyglib)
7+set_target_properties(
8+ cyglib
9+ PROPERTIES FOLDER cygwin)
10+
611 add_subdirectory(cygtool)
712 set_target_properties(
813 cygtool_dll
914 PROPERTIES FOLDER cygwin)
15+
16+if(false)
17+ add_subdirectory(cygterm)
18+ set_target_properties(
19+ cygterm
20+ PROPERTIES FOLDER cygwin)
21+endif()
22+
--- trunk/cygwin/cyglaunch/CMakeLists.txt (revision 9517)
+++ trunk/cygwin/cyglaunch/CMakeLists.txt (revision 9518)
@@ -6,6 +6,7 @@
66 ${PACKAGE_NAME} WIN32
77 cyglaunch.c
88 cyglaunch.rc
9+ ../cyglib/cyglib.h
910 )
1011
1112 target_include_directories(
@@ -14,6 +15,13 @@
1415 .
1516 )
1617
18+target_link_libraries(
19+ ${PACKAGE_NAME}
20+ PRIVATE
21+ common_static
22+ cyglib
23+ )
24+
1725 install(
1826 TARGETS ${PACKAGE_NAME}
1927 DESTINATION .
@@ -20,9 +28,9 @@
2028 )
2129
2230 if(MSVC)
23- # subsystem:windows, but start form main()
31+ # subsystem:windows, but start form wmain()
2432 if(${CMAKE_VERSION} VERSION_LESS "3.12.0")
25- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:mainCRTStartup")
33+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:wmainCRTStartup")
2634 else()
2735 target_link_options(
2836 ${PACKAGE_NAME}
@@ -31,3 +39,11 @@
3139 )
3240 endif()
3341 endif(MSVC)
42+
43+if(MINGW)
44+ target_link_options(
45+ ${PACKAGE_NAME}
46+ PRIVATE
47+ -municode
48+ )
49+endif(MINGW)
--- trunk/cygwin/cyglaunch/cyglaunch.c (revision 9517)
+++ trunk/cygwin/cyglaunch/cyglaunch.c (revision 9518)
@@ -1,145 +1,119 @@
1-//
2-// Cygterm launcher
3-//
4-// (C) 2007- TeraTerm Project
5-// https://ttssh2.osdn.jp/
6-//
7-// [How to compile]
8-// Cygwin:
9-// # cc -mno-cygwin -mwindows -o cyglaunch cyglaunch.c
10-//
11-
12-#include <windows.h>
13-#include <stdio.h>
14-#include <stdlib.h>
15-#include <direct.h>
16-
17-#define Section "Tera Term"
18-char *FName = "TERATERM.INI";
19-
20-
21-//
22-// Connect to local cygwin
23-//
24-void OnCygwinConnection(char *CygwinDirectory, char *cmdline)
25-{
26- char file[MAX_PATH], *filename;
27- char c, *envptr, *envbuff;
28- int envbufflen;
29- char *exename = "cygterm.exe";
30- char cmd[1024];
31- STARTUPINFO si;
32- PROCESS_INFORMATION pi;
33-
34- if (strlen(CygwinDirectory) > 0) {
35- if (SearchPath(CygwinDirectory, "bin\\cygwin1", ".dll", sizeof(file), file, &filename) > 0) {
36- goto found_dll;
37- }
38- }
39-
40- if (SearchPath(NULL, "cygwin1", ".dll", sizeof(file), file, &filename) > 0) {
41- goto found_path;
42- }
43-
44- for (c = 'C' ; c <= 'Z' ; c++) {
45- char tmp[MAX_PATH];
46- sprintf(tmp, "%c:\\cygwin\\bin;%c:\\cygwin64\\bin", c, c);
47- if (SearchPath(tmp, "cygwin1", ".dll", sizeof(file), file, &filename) > 0) {
48- goto found_dll;
49- }
50- }
51-
52- MessageBox(NULL, "Can't find Cygwin directory.", "ERROR", MB_OK | MB_ICONWARNING);
53- return;
54-
55-found_dll:;
56- envptr = getenv("PATH");
57- file[strlen(file)-12] = '\0'; // delete "\\cygwin1.dll"
58- if (envptr != NULL) {
59- envbufflen = strlen(file) + strlen(envptr) + 7; // "PATH="(5) + ";"(1) + NUL(1)
60- if ((envbuff=malloc(envbufflen)) == NULL) {
61- MessageBox(NULL, "Can't allocate memory.", "ERROR", MB_OK | MB_ICONWARNING);
62- return;
63- }
64- _snprintf(envbuff, envbufflen, "PATH=%s;%s", file, envptr);
65- } else {
66- envbufflen = strlen(file) + strlen(envptr) + 6; // "PATH="(5) + NUL(1)
67- if ((envbuff=malloc(envbufflen)) == NULL) {
68- MessageBox(NULL, "Can't allocate memory.", "ERROR", MB_OK | MB_ICONWARNING);
69- return;
70- }
71- _snprintf(envbuff, envbufflen, "PATH=%s", file);
72- }
73- _putenv(envbuff);
74- if (envbuff) {
75- free(envbuff);
76- envbuff = NULL;
77- }
78-
79-found_path:;
80- memset(&si, 0, sizeof(si));
81- GetStartupInfo(&si);
82- memset(&pi, 0, sizeof(pi));
83-
84- strcpy(cmd, exename);
85- strcat(cmd, " ");
86- strncat(cmd, cmdline, sizeof(cmd)-strlen(cmd)-1);
87-//printf("%s", cmd);
88-//MessageBox(NULL, cmd, "", MB_OK);
89- if (CreateProcess(
90- NULL,
91- cmd,
92- NULL, NULL, FALSE, 0,
93- NULL, NULL,
94- &si, &pi) == 0) {
95- MessageBox(NULL, "Can't execute Cygterm.", "ERROR", MB_OK | MB_ICONWARNING);
96- }
97-}
98-
99-
100-int main(int argc, char** argv)
101-{
102- char Temp[256], CygwinDir[256], Cmdline[256];
103- char *bs;
104- int i;
105- BOOL d_opt=FALSE;
106-
107- if (GetModuleFileName(NULL, Temp, sizeof(Temp)) > 0 &&
108- (bs = strrchr(Temp, '\\')) != NULL) {
109- *bs = 0;
110- _chdir(Temp);
111- _snprintf(bs, sizeof(Temp) + Temp - bs, "\\%s", FName);
112- }
113- else {
114- _snprintf(Temp, sizeof(Temp), ".\\", FName);
115- }
116-
117- // Cygwin install path
118- GetPrivateProfileString(Section, "CygwinDirectory", "c:\\cygwin",
119- CygwinDir, sizeof(CygwinDir), Temp);
120-
121- //printf("%s %d\n", CygwinDir, GetLastError());
122-
123- Cmdline[0] = 0;
124- for (i=1; i<argc; i++) {
125- if (i != 1) {
126- strncat(Cmdline, " ", sizeof(Cmdline)-strlen(Cmdline)-1);
127- }
128- if (d_opt && strncmp("\"\\\\", argv[i], 3) == 0) {
129- argv[i][1] = '/';
130- argv[i][2] = '/';
131- }
132- strncat(Cmdline, argv[i], sizeof(Cmdline)-strlen(Cmdline)-1);
133- if (strcmp(argv[i], "-d") == 0) {
134- d_opt = TRUE;
135- }
136- else {
137- d_opt = FALSE;
138- }
139- }
140- //printf("%s\n", Cmdline);
141-
142- OnCygwinConnection(CygwinDir, Cmdline);
143-
144- return 0;
145-}
1+/*
2+ * Copyright (C) 2007- TeraTerm Project
3+ * All rights reserved.
4+ *
5+ * Redistribution and use in source and binary forms, with or without
6+ * modification, are permitted provided that the following conditions
7+ * are met:
8+ *
9+ * 1. Redistributions of source code must retain the above copyright
10+ * notice, this list of conditions and the following disclaimer.
11+ * 2. Redistributions in binary form must reproduce the above copyright
12+ * notice, this list of conditions and the following disclaimer in the
13+ * documentation and/or other materials provided with the distribution.
14+ * 3. The name of the author may not be used to endorse or promote products
15+ * derived from this software without specific prior written permission.
16+ *
17+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27+ */
28+
29+//
30+// Cygterm launcher
31+//
32+
33+#include <windows.h>
34+#include <stdio.h>
35+#include <stdlib.h>
36+#include <locale.h>
37+
38+#include "ttlib.h"
39+#include "asprintf.h"
40+#include "cyglib.h"
41+
42+#define Section L"Tera Term"
43+
44+/**
45+ * TERATERM.INI から CygwinDirectory を読み込む
46+ */
47+static wchar_t *GetCygwinDir(void)
48+{
49+ wchar_t *HomeDir;
50+ wchar_t *teraterm_ini;
51+ wchar_t CygwinDir[256];
52+
53+ HomeDir = GetHomeDirW(NULL);
54+ teraterm_ini = NULL;
55+ awcscats(&teraterm_ini, HomeDir, L"\\TERATERM.INI", NULL);
56+ free(HomeDir);
57+
58+ // Cygwin install path
59+ GetPrivateProfileStringW(Section, L"CygwinDirectory", L"",
60+ CygwinDir, _countof(CygwinDir), teraterm_ini);
61+ free(teraterm_ini);
62+
63+ if (CygwinDir[0] == 0) {
64+ return NULL;
65+ }
66+ return _wcsdup(CygwinDir);
67+}
68+
69+int wmain(int argc, wchar_t *argv[])
70+{
71+ wchar_t *CygwinDir;
72+ wchar_t *Cmdline;
73+ int i;
74+ BOOL d_opt=FALSE;
75+ DWORD e;
76+
77+ setlocale(LC_ALL, "");
78+
79+ // 引数を結合してコマンドラインを作成
80+ Cmdline = NULL;
81+ for (i=1; i<argc; i++) {
82+ if (i != 1) {
83+ awcscat(&Cmdline, L" ");
84+ }
85+ if (d_opt && wcsncmp(L"\"\\\\", argv[i], 3) == 0) {
86+ argv[i][1] = '/';
87+ argv[i][2] = '/';
88+ }
89+ awcscat(&Cmdline, argv[i]);
90+ if (wcscmp(argv[i], L"-d") == 0) {
91+ d_opt = TRUE;
92+ }
93+ else {
94+ d_opt = FALSE;
95+ }
96+ }
97+
98+ // cygwinがインストールされているフォルダ
99+ CygwinDir = GetCygwinDir();
100+
101+ // cygtermを実行する
102+ e = CygwinConnect(CygwinDir, Cmdline);
103+ switch(e) {
104+ case NO_ERROR:
105+ break;
106+ case ERROR_FILE_NOT_FOUND:
107+ MessageBox(NULL, "Can't find Cygwin directory.", "ERROR", MB_OK | MB_ICONWARNING);
108+ break;
109+ case ERROR_NOT_ENOUGH_MEMORY:
110+ MessageBox(NULL, "Can't allocate memory.", "ERROR", MB_OK | MB_ICONWARNING);
111+ break;
112+ case ERROR_OPEN_FAILED:
113+ default:
114+ MessageBox(NULL, "Can't execute Cygterm.", "ERROR", MB_OK | MB_ICONWARNING);
115+ break;
116+ }
117+
118+ return 0;
119+}
--- trunk/cygwin/cyglib/CMakeLists.txt (nonexistent)
+++ trunk/cygwin/cyglib/CMakeLists.txt (revision 9518)
@@ -0,0 +1,21 @@
1+set(PACKAGE_NAME "cyglib")
2+
3+project(${PACKAGE_NAME})
4+
5+add_library(
6+ ${PACKAGE_NAME}
7+ cyglib.c
8+ cyglib.h
9+ )
10+
11+target_include_directories(
12+ ${PACKAGE_NAME}
13+ PUBLIC
14+ .
15+ )
16+
17+target_link_libraries(
18+ ${PACKAGE_NAME}
19+ PUBLIC
20+ common_static
21+ )
--- trunk/cygwin/cyglib/cyglib.c (nonexistent)
+++ trunk/cygwin/cyglib/cyglib.c (revision 9518)
@@ -0,0 +1,249 @@
1+/*
2+ * Copyright (C) 2021- TeraTerm Project
3+ * All rights reserved.
4+ *
5+ * Redistribution and use in source and binary forms, with or without
6+ * modification, are permitted provided that the following conditions
7+ * are met:
8+ *
9+ * 1. Redistributions of source code must retain the above copyright
10+ * notice, this list of conditions and the following disclaimer.
11+ * 2. Redistributions in binary form must reproduce the above copyright
12+ * notice, this list of conditions and the following disclaimer in the
13+ * documentation and/or other materials provided with the distribution.
14+ * 3. The name of the author may not be used to endorse or promote products
15+ * derived from this software without specific prior written permission.
16+ *
17+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27+ */
28+
29+#include <windows.h>
30+#include <stdio.h>
31+#include <stdlib.h>
32+#include <direct.h>
33+#include <locale.h>
34+#include <string.h>
35+#include <errno.h>
36+
37+#include "ttlib.h"
38+#include "asprintf.h"
39+
40+#include "cyglib.h"
41+
42+/**
43+ * cygwin1.dllを探す
44+ *
45+ * @param[in] cygwin_dir (存在するであろう)フォルダ
46+ * @param[out] find_dir 見つかったフォルダ free() すること
47+ * @param[out] find_in_path 環境変数 PATH 内に見つかった
48+ *
49+ * @retval TRUE 見つかった
50+ * @retval FALSE 見つからない
51+ */
52+static BOOL CygwinSearchDLL(const wchar_t *cygwin_dir, wchar_t **find_dir, BOOL *find_in_path)
53+{
54+ wchar_t file[MAX_PATH];
55+ wchar_t *filename;
56+ wchar_t c;
57+#if 1
58+ const wchar_t *dll_base = L"cygwin1";
59+ const wchar_t *search_paths[] = {
60+ L"%c:\\cygwin\\bin",
61+ L"%c:\\cygwin64\\bin",
62+ NULL,
63+ };
64+#endif
65+#if 0
66+ const wchar_t *dll_base = L"msys-2.0";
67+ const wchar_t *search_paths[] = {
68+ L"%c:\\msys\\usr\\bin",
69+ L"%c:\\msys64\\usr\\bin",
70+ NULL,
71+ };
72+#endif
73+ wchar_t *dll;
74+ int i;
75+ DWORD r;
76+
77+ *find_in_path = FALSE;
78+ *find_dir = NULL;
79+
80+ // 指定されたフォルダに存在するか?
81+ if (cygwin_dir != NULL && cygwin_dir[0] != 0) {
82+ // SearchPathW() で探す
83+ dll = NULL;
84+ awcscats(&dll, L"bin\\", dll_base, L".dll", NULL);
85+ r = SearchPathW(cygwin_dir, dll, L".dll", _countof(file), file, &filename);
86+ free(dll);
87+ if (r > 0) {
88+ goto found_dll;
89+ }
90+
91+ // SearchPathW() だと "msys-2.0.dll" が見つけることができない (Windows 10)
92+ dll = NULL;
93+ awcscats(&dll, cygwin_dir, L"\\", dll_base, L".dll", NULL);
94+ r = GetFileAttributesW(dll);
95+ if (r != INVALID_FILE_ATTRIBUTES) {
96+ // 見つかった
97+ wcscpy_s(file, _countof(file), dll);
98+ free(dll);
99+ goto found_dll;
100+ }
101+ free(dll);
102+ }
103+
104+ // PATH から探す
105+ if (SearchPathW(NULL, dll_base, L".dll", _countof(file), file, &filename) > 0) {
106+ *find_in_path = TRUE;
107+ goto found_dll;
108+ }
109+
110+ // ありそうな場所を探す
111+ for (c = 'C' ; c <= 'Z' ; c++) {
112+ for (i = 0; search_paths[i] != NULL; i++) {
113+ // SearchPathW() で探す
114+ const wchar_t *search_path_base = search_paths[i];
115+ wchar_t *search_path;
116+ aswprintf(&search_path, search_path_base, c);
117+ r = SearchPathW(search_path, dll_base, L".dll", _countof(file), file, &filename);
118+ if (r > 0) {
119+ free(search_path);
120+ goto found_dll;
121+ }
122+
123+ // ファイルが存在するか調べる
124+ dll = NULL;
125+ awcscats(&dll, search_path, L"\\", dll_base, L".dll", NULL);
126+ r = GetFileAttributesW(dll);
127+ free(search_path);
128+ if (r != INVALID_FILE_ATTRIBUTES) {
129+ wcscpy_s(file, _countof(file), dll);
130+ free(dll);
131+ goto found_dll;
132+ }
133+ free(dll);
134+ }
135+ }
136+
137+ // 見つからなかった
138+ return FALSE;
139+
140+found_dll:
141+ {
142+ // cut "cygwin1.dll", フォルダのみを返す
143+ wchar_t *p = wcsrchr(file, L'\\');
144+ *p = 0;
145+ }
146+
147+ *find_dir = _wcsdup(file);
148+ return TRUE;
149+}
150+
151+static errno_t __wdupenv_s(wchar_t** envptr, size_t* buf_size, const wchar_t* name)
152+{
153+#if defined(_MSC_VER)
154+ return _wdupenv_s(envptr, buf_size, name);
155+#else
156+ const wchar_t* s = _wgetenv(name);
157+ if (s == NULL) {
158+ // 存在しない
159+ *envptr = NULL;
160+ return EINVAL;
161+ }
162+ *envptr = _wcsdup(s);
163+ if (buf_size != NULL) {
164+ *buf_size = wcslen(*envptr);
165+ }
166+ return 0;
167+#endif
168+}
169+
170+/**
171+ * 環境変数 PATH に add_path を追加
172+ */
173+static BOOL AddPath(const wchar_t *add_path)
174+{
175+ wchar_t *envptr;
176+ wchar_t *new_env;
177+ int r;
178+ errno_t e;
179+
180+ e = __wdupenv_s(&envptr, NULL, L"PATH");
181+ if (e == 0) {
182+ aswprintf(&new_env, L"PATH=%s;%s", add_path, envptr);
183+ free(envptr);
184+ }
185+ else {
186+ // 環境変数 PATH が存在しない
187+ aswprintf(&new_env, L"PATH=%s", add_path);
188+ }
189+ r = _wputenv(new_env);
190+ free(new_env);
191+ return r == 0 ? TRUE : FALSE;
192+}
193+
194+/**
195+ * Connect to local cygwin
196+ * cygtermを実行
197+ *
198+ * @param[in] CygwinDirectory Cygwinがインストールしてあるフォルダ
199+ * 見つからなければデフォルトフォルダなどを探す
200+ * @param[in] cmdline cygtermに渡すコマンドライン引数
201+ * NULLのとき引数なし
202+ * @retval NO_ERROR 実行できた
203+ * @retval ERROR_FILE_NOT_FOUND cygwinが見つからない(cygwin1.dllが見つからない)
204+ * @retval ERROR_NOT_ENOUGH_MEMORY メモリ不足
205+ * @retval ERROR_OPEN_FAILED 実行できない
206+ */
207+DWORD CygwinConnect(const wchar_t *CygwinDirectory, const wchar_t *cmdline)
208+{
209+ BOOL find_cygwin;
210+ wchar_t *find_dir;
211+ BOOL find_in_path;
212+ wchar_t *ExeDirW;
213+ wchar_t *cygterm_cmd;
214+ DWORD e;
215+ const wchar_t *cygterm_exe = L"cygterm.exe";
216+// const wchar_t *cygterm_exe = L"msys2term.exe";
217+
218+// CygwinDirectory = NULL;
219+ find_cygwin = CygwinSearchDLL(CygwinDirectory, &find_dir, &find_in_path);
220+ if (find_cygwin == FALSE) {
221+ return ERROR_FILE_NOT_FOUND;
222+ }
223+
224+ if (!find_in_path) {
225+ // 環境変数 PATH に追加
226+ // cygterm.exe を実行するときに cygwin1.dll をロードできるようにする
227+ BOOL r = AddPath(find_dir);
228+ if (r == FALSE) {
229+ free(find_dir);
230+ return ERROR_NOT_ENOUGH_MEMORY;
231+ }
232+ }
233+ free(find_dir);
234+
235+ ExeDirW = GetExeDirW(NULL);
236+ cygterm_cmd = NULL;
237+ awcscats(&cygterm_cmd, ExeDirW, L"\\", cygterm_exe, NULL);
238+ if (cmdline != NULL && cmdline[0] != 0) {
239+ awcscats(&cygterm_cmd, L" ", cmdline, NULL);
240+ }
241+
242+ e = TTWinExec(cygterm_cmd);
243+ free(cygterm_cmd);
244+ if (e != NO_ERROR) {
245+ return ERROR_OPEN_FAILED;
246+ }
247+
248+ return NO_ERROR;
249+}
--- trunk/cygwin/cyglib/cyglib.h (nonexistent)
+++ trunk/cygwin/cyglib/cyglib.h (revision 9518)
@@ -0,0 +1,41 @@
1+/*
2+ * Copyright (C) 2021- TeraTerm Project
3+ * All rights reserved.
4+ *
5+ * Redistribution and use in source and binary forms, with or without
6+ * modification, are permitted provided that the following conditions
7+ * are met:
8+ *
9+ * 1. Redistributions of source code must retain the above copyright
10+ * notice, this list of conditions and the following disclaimer.
11+ * 2. Redistributions in binary form must reproduce the above copyright
12+ * notice, this list of conditions and the following disclaimer in the
13+ * documentation and/or other materials provided with the distribution.
14+ * 3. The name of the author may not be used to endorse or promote products
15+ * derived from this software without specific prior written permission.
16+ *
17+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27+ */
28+
29+#pragma once
30+
31+#include <windows.h>
32+
33+#ifdef __cplusplus
34+extern "C" {
35+#endif
36+
37+DWORD CygwinConnect(const wchar_t *CygwinDirectory, const wchar_t *cmdline);
38+
39+#ifdef __cplusplus
40+}
41+#endif
--- trunk/teraterm/teraterm/CMakeLists.txt (revision 9517)
+++ trunk/teraterm/teraterm/CMakeLists.txt (revision 9518)
@@ -303,6 +303,7 @@
303303 ttpcmn
304304 ttpset
305305 ttptek
306+ cyglib
306307 ${ONIGURUMA_LIB}
307308 ${SFMT_LIB}
308309 )
--- trunk/teraterm/teraterm/vtwin.cpp (revision 9517)
+++ trunk/teraterm/teraterm/vtwin.cpp (revision 9518)
@@ -65,6 +65,7 @@
6565 #include "ttplug.h" /* TTPLUG */
6666 #include "teraterml.h"
6767 #include "buffer.h"
68+#include "cyglib.h"
6869
6970 #include <stdio.h>
7071 #define _CRTDBG_MAP_ALLOC
@@ -3690,50 +3691,18 @@
36903691 }
36913692 }
36923693
3693-static void __dupenv_s(char **envptr, size_t, const char* name)
3694-{
3695-#if defined(_MSC_VER)
3696- _dupenv_s(envptr, NULL, name);
3697-#else
3698- const char* s = getenv(name);
3699- if (s == NULL) {
3700- *envptr = NULL;
3701- return;
3702- }
3703- *envptr = strdup(s);
3704-#endif
3705-}
3706-
37073694 //
37083695 // Connect to local cygwin
37093696 //
37103697 void CVTWindow::OnCygwinConnection()
37113698 {
3712- char file[MAX_PATH], *filename;
3713- char c, *envptr, *envbuff=NULL;
3714- size_t envbufflen;
3715- const char *exename = "cygterm.exe";
3716- char cygterm[MAX_PATH];
3717-
3718- if (strlen(ts.CygwinDirectory) > 0) {
3719- if (SearchPath(ts.CygwinDirectory, "bin\\cygwin1", ".dll", sizeof(file), file, &filename) > 0) {
3720- goto found_dll;
3721- }
3722- }
3723-
3724- if (SearchPath(NULL, "cygwin1", ".dll", sizeof(file), file, &filename) > 0) {
3725- goto found_path;
3726- }
3727-
3728- for (c = 'C' ; c <= 'Z' ; c++) {
3729- char tmp[MAX_PATH];
3730- sprintf_s(tmp, "%c:\\cygwin\\bin;%c:\\cygwin64\\bin", c, c);
3731- if (SearchPath(tmp, "cygwin1", ".dll", sizeof(file), file, &filename) > 0) {
3732- goto found_dll;
3733- }
3734- }
3735-
3736- {
3699+ wchar_t *CygwinDirectory = ToWcharA(ts.CygwinDirectory);
3700+ DWORD e = CygwinConnect(CygwinDirectory, NULL);
3701+ free(CygwinDirectory);
3702+ switch(e) {
3703+ case NO_ERROR:
3704+ break;
3705+ case ERROR_FILE_NOT_FOUND: {
37373706 static const TTMessageBoxInfoW info = {
37383707 "Tera Term",
37393708 "MSG_ERROR", L"ERROR",
@@ -3741,54 +3710,20 @@
37413710 MB_OK | MB_ICONWARNING
37423711 };
37433712 TTMessageBoxW(HVTWin, &info, ts.UILanguageFileW);
3713+ break;
37443714 }
3745- return;
3746-
3747-found_dll:;
3748- __dupenv_s(&envptr, NULL, "PATH");
3749- file[strlen(file)-12] = '\0'; // delete "\\cygwin1.dll"
3750- if (envptr != NULL) {
3751- envbufflen = strlen(file) + strlen(envptr) + 7; // "PATH="(5) + ";"(1) + NUL(1)
3752- if ((envbuff = (char *)malloc(envbufflen)) == NULL) {
3753- static const TTMessageBoxInfoW info = {
3754- "Tera Term",
3755- "MSG_ERROR", L"ERROR",
3756- "MSG_CYGTERM_ENV_ALLOC_ERROR", L"Can't allocate memory for environment variable.",
3757- MB_OK | MB_ICONWARNING
3758- };
3759- TTMessageBoxW(HVTWin, &info, ts.UILanguageFileW);
3760- free(envptr);
3761- return;
3762- }
3763- _snprintf_s(envbuff, envbufflen, _TRUNCATE, "PATH=%s;%s", file, envptr);
3764- free(envptr);
3765- } else {
3766- envbufflen = strlen(file) + 6; // "PATH="(5) + NUL(1)
3767- if ((envbuff = (char *)malloc(envbufflen)) == NULL) {
3768- static const TTMessageBoxInfoW info = {
3769- "Tera Term",
3770- "MSG_ERROR", L"ERROR",
3771- "MSG_CYGTERM_ENV_ALLOC_ERROR", L"Can't allocate memory for environment variable.",
3772- MB_OK | MB_ICONWARNING
3773- };
3774- TTMessageBoxW(HVTWin, &info, ts.UILanguageFileW);
3775- return;
3776- }
3777- _snprintf_s(envbuff, envbufflen, _TRUNCATE, "PATH=%s", file);
3715+ case ERROR_NOT_ENOUGH_MEMORY: {
3716+ static const TTMessageBoxInfoW info = {
3717+ "Tera Term",
3718+ "MSG_ERROR", L"ERROR",
3719+ "MSG_CYGTERM_ENV_ALLOC_ERROR", L"Can't allocate memory for environment variable.",
3720+ MB_OK | MB_ICONWARNING
3721+ };
3722+ TTMessageBoxW(HVTWin, &info, ts.UILanguageFileW);
3723+ break;
37783724 }
3779- _putenv(envbuff);
3780- if (envbuff) {
3781- free(envbuff);
3782- envbuff = NULL;
3783- }
3784-
3785-found_path:;
3786- strncpy_s(cygterm, sizeof(cygterm), ts.HomeDir, _TRUNCATE);
3787- AppendSlash(cygterm, sizeof(cygterm));
3788- strncat_s(cygterm, sizeof(cygterm), exename, _TRUNCATE);
3789-
3790- DWORD e = TTWinExecA(cygterm);
3791- if (e != NO_ERROR) {
3725+ case ERROR_OPEN_FAILED:
3726+ default: {
37923727 static const TTMessageBoxInfoW info = {
37933728 "Tera Term",
37943729 "MSG_ERROR", L"ERROR",
@@ -3796,10 +3731,11 @@
37963731 MB_OK | MB_ICONWARNING
37973732 };
37983733 TTMessageBoxW(HVTWin, &info, ts.UILanguageFileW);
3734+ break;
37993735 }
3736+ }
38003737 }
38013738
3802-
38033739 //
38043740 // TeraTerm Menuの起動
38053741 //
Show on old repository browser