Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

314 lines
5.3 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. posix.c
  5. Abstract:
  6. This module contains the main of the session console process (posix.exe).
  7. Author:
  8. Avi Nathan (avin) 17-Jul-1991
  9. Environment:
  10. User Mode Only
  11. Revision History:
  12. Ellen Aycock-Wright (ellena) 15-Sept-1991 - Modified for Posix
  13. --*/
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include "error.h"
  17. #include "errors.h"
  18. #include "posixres.h"
  19. #define WIN32_ONLY
  20. #include "psxses.h"
  21. int
  22. GetCWD(
  23. size_t size,
  24. char *CurrentDir
  25. );
  26. #define SKIP_ARG {argc--; argv++;}
  27. DWORD ServeKbdInput(LPVOID Parm);
  28. CRITICAL_SECTION KbdBufMutex;
  29. HANDLE hIoEvent;
  30. HANDLE hCanonEvent;
  31. BOOLEAN DoTrickyIO = FALSE;
  32. CRITICAL_SECTION StopMutex; // these for VSTOP/VSTART
  33. BOOLEAN bStop = FALSE;
  34. HANDLE hStopEvent;
  35. //
  36. // These are resources for "on" and "off", used throughout.
  37. //
  38. LPTSTR szOn, szOff;
  39. void
  40. __cdecl
  41. main(
  42. int argc,
  43. char *argv[],
  44. char *envp[]
  45. )
  46. {
  47. static char PgmFullPathBuf[MAX_PATH + 1];
  48. static char CurrentDir[MAX_PATH + 1];
  49. DWORD SessionPortHandle;
  50. char *lpPgmName = NULL;
  51. char *pch;
  52. LPSTR lpFilePart;
  53. int i;
  54. DWORD dwThreadId;
  55. HANDLE hThread;
  56. #if DBG
  57. fTrace = FALSE;
  58. #endif
  59. //
  60. // skip program name
  61. //
  62. SKIP_ARG;
  63. //
  64. // look for flags for posix up to /C
  65. //
  66. //
  67. while (argc) {
  68. if ((argv[0][0] == '/') && ((argv[0][1]|('a'-'A')) == 'c')) {
  69. if (argv[0][2]) {
  70. argv[0] += 2;
  71. } else {
  72. SKIP_ARG;
  73. }
  74. break;
  75. } else {
  76. if (argv[0][0] == '/') {
  77. switch (argv[0][1]|('a'-'A')) {
  78. case 'p':
  79. SKIP_ARG;
  80. lpPgmName = *argv;
  81. break;
  82. #if DBG
  83. case 'b':
  84. #if 0
  85. _asm int 3;
  86. #endif
  87. break;
  88. case 'v':
  89. fVerbose = TRUE;
  90. break;
  91. case 't':
  92. fTrace = TRUE;
  93. break;
  94. #endif
  95. default:
  96. // error("posix: unknown flag: %s\n", argv[0]);
  97. error(MSG_UNKNOWN_FLAG, argv[0]);
  98. exit(1);
  99. }
  100. } else {
  101. // error("usage: posix /c <path> [<args>]\n");
  102. error(MSG_USAGE);
  103. exit(1);
  104. }
  105. }
  106. SKIP_ARG;
  107. }
  108. if (!argc) {
  109. // error("posix: command missing\n");
  110. error(MSG_COMMAND_MISSING);
  111. exit(1);
  112. }
  113. //
  114. // Set event handlers to handle Ctrl-C etc.
  115. //
  116. SetEventHandlers(TRUE);
  117. //
  118. // Connect with PSXSS
  119. //
  120. if (!(SessionPortHandle = InitPsxSessionPort()) ) {
  121. // printf("posix: Cannot connect to Posix SubSystem\n");
  122. error(MSG_CANNOT_CONNECT);
  123. exit(1);
  124. }
  125. szOn = MyLoadString(IDS_ON);
  126. szOff = MyLoadString(IDS_OFF);
  127. pch = getenv("_POSIX_TERM");
  128. if (NULL != pch && 0 == lstrcmpi(pch, szOn)) {
  129. DoTrickyIO = TRUE;
  130. }
  131. if (DoTrickyIO) {
  132. //
  133. // Get handles to CONIN$ and CONOUT$ for terminal io.
  134. //
  135. //
  136. hConsoleInput = CreateFile(
  137. TEXT("CONIN$"),
  138. GENERIC_READ | GENERIC_WRITE,
  139. FILE_SHARE_READ | FILE_SHARE_WRITE,
  140. NULL,
  141. OPEN_EXISTING,
  142. FILE_ATTRIBUTE_NORMAL,
  143. NULL
  144. );
  145. if (INVALID_HANDLE_VALUE == hConsoleInput) {
  146. KdPrint(("POSIX: get con handle: 0x%x\n",
  147. GetLastError()));
  148. }
  149. hConsoleOutput = CreateFile(
  150. TEXT("CONOUT$"),
  151. GENERIC_READ | GENERIC_WRITE,
  152. FILE_SHARE_READ | FILE_SHARE_WRITE,
  153. NULL,
  154. OPEN_EXISTING,
  155. FILE_ATTRIBUTE_NORMAL,
  156. NULL
  157. );
  158. if (INVALID_HANDLE_VALUE == hConsoleOutput) {
  159. KdPrint(("POSIX: get con handle: 0x%x\n",
  160. GetLastError()));
  161. }
  162. //
  163. // Init terminal emulation globals.
  164. //
  165. TermioInit();
  166. }
  167. //
  168. // get the full path of the program to execute
  169. //
  170. if (!lpPgmName) {
  171. lpPgmName = argv[0];
  172. }
  173. GetFullPathName(lpPgmName, MAX_PATH, PgmFullPathBuf, &lpFilePart);
  174. //
  175. // Get our current working directory, so the Posix subsystem will know
  176. // where to put the new Posix process.
  177. //
  178. (void)GetCWD(sizeof(CurrentDir), CurrentDir);
  179. //
  180. // Submit the request to start the process
  181. //
  182. if (!StartProcess(SessionPortHandle, PgmFullPathBuf, CurrentDir, argc,
  183. argv, envp)) {
  184. // printf("posix: Cannot start process\n");
  185. error(MSG_CANNOT_START_PROC);
  186. exit(1);
  187. }
  188. if (!DoTrickyIO) {
  189. ExitThread(0);
  190. }
  191. SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
  192. InitializeCriticalSection(&KbdBufMutex);
  193. hIoEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  194. hCanonEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  195. InitializeCriticalSection(&StopMutex);
  196. hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  197. hThread = CreateThread(NULL, 0, ServeKbdInput, NULL, 0, &dwThreadId);
  198. if (/* !hThread || */ !hIoEvent) {
  199. KdPrint(("PSXSES: Cannot start keyboard server\n"));
  200. exit(1);
  201. }
  202. ExitThread(0);
  203. }
  204. VOID
  205. SetEventHandlers(
  206. IN BOOL fSet
  207. )
  208. {
  209. SetConsoleCtrlHandler((PVOID)EventHandlerRoutine, fSet);
  210. }
  211. int
  212. GetCWD(
  213. size_t size,
  214. char *CurrentDir
  215. )
  216. {
  217. char *pch, *pch2, *pch3, save, save2, save3;
  218. HANDLE d;
  219. WIN32_FIND_DATA FindData;
  220. (void)GetCurrentDirectory(size, CurrentDir);
  221. //
  222. // Make sure the drive letter is upper-case.
  223. //
  224. CurrentDir[0] = (char) toupper(CurrentDir[0]);
  225. //
  226. // Go through the path a component at a time, and make
  227. // sure that the directory names are in the correct
  228. // case.
  229. //
  230. pch = strchr(CurrentDir, '\\');
  231. if (NULL == pch) {
  232. // we are in the root
  233. return 0;
  234. }
  235. ++pch;
  236. for (;;) {
  237. pch2 = strchr(pch, '\\');
  238. if (NULL != pch2)
  239. *pch2 = '\0';
  240. d = FindFirstFile(CurrentDir, &FindData);
  241. if (INVALID_HANDLE_VALUE == d) {
  242. return -1;
  243. }
  244. FindClose(d);
  245. strcpy(pch, FindData.cFileName);
  246. if (NULL != pch2) {
  247. *pch2 = '\\';
  248. pch = pch2 + 1;
  249. } else {
  250. break;
  251. }
  252. }
  253. return 0;
  254. }