1 /* -*- c-basic-offset:2; tab-width:2; indent-tabs-mode:nil -*- */
2
3 #include <sys/types.h>
4
5 #include <pobl/bl_def.h> /* USE_WIN32API/HAVE_WINDOWS_H */
6 #include <pobl/bl_unistd.h> /* bl_getuid/bl_getgid */
7 #include <pobl/bl_conf_io.h>
8 #include <pobl/bl_privilege.h>
9 #include <pobl/bl_debug.h>
10 #include <pobl/bl_dlfcn.h>
11 #include <pobl/bl_mem.h> /* malloc */
12
13 #ifdef HAVE_WINDOWS_H
14 #include <windows.h>
15 #endif
16
17 #include "main_loop.h"
18
19 #if defined(USE_WIN32API)
20 #define CONFIG_PATH "."
21 #elif defined(SYSCONFDIR)
22 #define CONFIG_PATH SYSCONFDIR
23 #else
24 #define CONFIG_PATH "/etc"
25 #endif
26
27 #ifdef USE_WIN32API
28 #include <stdlib.h> /* _fmode */
29 #include <fcntl.h> /* _O_BINARY */
30 static char *dummy_argv[] = {"mlterm", NULL};
31 #define argv (__argv ? __argv : dummy_argv)
32 #define argc __argc
33 #endif
34
35 /* --- static functions --- */
36
37 #if defined(__CYGWIN__) || defined(__MSYS__)
38 #ifdef __CYGWIN__
39 #define ENV_PCON "CYGWIN"
40 #else
41 #define ENV_PCON "MSYS"
42 #endif
43
44 #include <stdlib.h> /* setenv */
45
init_cygwin_env(void)46 static void init_cygwin_env(void) {
47 char *cur_val;
48 char *new_val;
49 size_t len;
50
51 /*
52 * 'disable_pcon' variable in winsup/cygwin/global.cc disables win32 pseudo console.
53 * (See fhandler_pty_master::setup_pseudoconsole() in fhandler_tty.cc)
54 *
55 * If cur_len >= new_len, _addenv() in winsup/cygwin/environ.cc doesn't call parse_optons()
56 * which changes 'disable_pcon' variable according to the value of "CYGWIN" environmental
57 * variable.
58 *
59 * So call setenv() with not only "disable_pcon" but also the current value of "CYGWIN"
60 * environmental variable.
61 */
62
63 if ((cur_val = getenv(ENV_PCON))) {
64 len = strlen(cur_val) + 1;
65 } else {
66 len = 0;
67 }
68
69 /* Don't use alloca() here before bl_alloca_begin_stack_frame() is called in main_loop_start(). */
70 if ((new_val = malloc(len + 12 + 1))) {
71 if (cur_val) {
72 memcpy(new_val, cur_val, len - 1);
73 new_val[len - 1] = ' ';
74 }
75 strcpy(new_val + len, "disable_pcon");
76 setenv(ENV_PCON, new_val, 1);
77 free(new_val);
78 }
79 }
80 #endif
81
82 #if defined(HAVE_WINDOWS_H) && !defined(USE_WIN32API)
83
84 #include <stdio.h> /* sprintf */
85 #include <sys/utsname.h>
86
87 #include <pobl/bl_util.h>
88
check_console(void)89 static void check_console(void) {
90 int count;
91 HWND conwin;
92 char app_name[6 + DIGIT_STR_LEN(u_int) + 1];
93 HANDLE handle;
94
95 if (!(handle = GetStdHandle(STD_OUTPUT_HANDLE)) || handle == INVALID_HANDLE_VALUE) {
96 #if 0
97 struct utsname name;
98 char *rel;
99
100 if (uname(&name) == 0 && (rel = alloca(strlen(name.release) + 1))) {
101 char *p;
102
103 if ((p = strchr(strcpy(rel, name.release), '.'))) {
104 int major;
105 int minor;
106
107 *p = '\0';
108 major = atoi(rel);
109 rel = p + 1;
110
111 if ((p = strchr(rel, '.'))) {
112 *p = '\0';
113 minor = atoi(rel);
114
115 if (major >= 2 || (major == 1 && minor >= 7)) {
116 /*
117 * Mlterm works without console
118 * in cygwin 1.7 or later.
119 */
120 return;
121 }
122 }
123 }
124 }
125
126 /* AllocConsole() after starting mlterm doesn't work on MSYS. */
127 if (!AllocConsole())
128 #endif
129 {
130 return;
131 }
132 }
133
134 /* Hide allocated console window */
135
136 sprintf(app_name, "mlterm%08x", (unsigned int)GetCurrentThreadId());
137 LockWindowUpdate(GetDesktopWindow());
138 SetConsoleTitle(app_name);
139
140 for (count = 0; count < 20; count++) {
141 if ((conwin = FindWindow(NULL, app_name))) {
142 ShowWindowAsync(conwin, SW_HIDE);
143 break;
144 }
145
146 Sleep(40);
147 }
148
149 LockWindowUpdate(NULL);
150 }
151
152 #else
153
154 #define check_console() (1)
155
156 #endif
157
158 /* --- global functions --- */
159
160 #ifdef USE_WIN32API
WinMain(HINSTANCE hinst,HINSTANCE hprev,char * cmdline,int cmdshow)161 int PASCAL WinMain(HINSTANCE hinst, HINSTANCE hprev, char *cmdline, int cmdshow)
162 #else
163 int main(int argc, char **argv)
164 #endif
165 {
166 #ifdef __CYGWIN__
167 init_cygwin_env();
168 #endif
169
170 #if defined(USE_WIN32API) && defined(USE_LIBSSH2)
171 WSADATA wsadata;
172
173 WSAStartup(MAKEWORD(2, 0), &wsadata);
174 #endif
175
176 #ifdef USE_WIN32API
177 _fmode = _O_BINARY;
178 #endif
179
180 check_console();
181
182 /* Don't call before NSApplicationMain() */
183 #if !defined(USE_SDL2) || !defined(__APPLE__)
184 /* normal user */
185 bl_priv_change_euid(bl_getuid());
186 bl_priv_change_egid(bl_getgid());
187 #endif
188
189 bl_set_sys_conf_dir(CONFIG_PATH);
190
191 #if (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(USE_FRAMEBUFFER)
192 /*
193 * XXX
194 * It performs well to read as large amount of data as possible
195 * on framebuffer on old machines.
196 */
197 vt_set_timeout_read_pty(0xffff); /* 65535 sec */
198 #endif
199
200 if (!main_loop_init(argc, argv)) {
201 #ifdef DEBUG
202 bl_warn_printf(BL_DEBUG_TAG " ui_term_manager_init() failed.\n");
203 #endif
204
205 return 1;
206 }
207
208 main_loop_start();
209
210 /*
211 * Stale utmp is left without this if the last window is closed and final()
212 * in vt_pty_unix.c is not called.
213 */
214 main_loop_final();
215
216 #if defined(USE_WIN32API) && defined(USE_LIBSSH2)
217 WSACleanup();
218 #endif
219
220 bl_dl_close_all();
221
222 return 0;
223 }
224