315 lines
5.3 KiB
C
315 lines
5.3 KiB
C
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
posix.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the main of the session console process (posix.exe).
|
|
|
|
Author:
|
|
|
|
Avi Nathan (avin) 17-Jul-1991
|
|
|
|
Environment:
|
|
|
|
User Mode Only
|
|
|
|
Revision History:
|
|
|
|
Ellen Aycock-Wright (ellena) 15-Sept-1991 - Modified for Posix
|
|
|
|
--*/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "error.h"
|
|
#include "errors.h"
|
|
#include "posixres.h"
|
|
#define WIN32_ONLY
|
|
#include "psxses.h"
|
|
|
|
int
|
|
GetCWD(
|
|
size_t size,
|
|
char *CurrentDir
|
|
);
|
|
|
|
#define SKIP_ARG {argc--; argv++;}
|
|
|
|
DWORD ServeKbdInput(LPVOID Parm);
|
|
|
|
CRITICAL_SECTION KbdBufMutex;
|
|
HANDLE hIoEvent;
|
|
HANDLE hCanonEvent;
|
|
BOOLEAN DoTrickyIO = FALSE;
|
|
|
|
CRITICAL_SECTION StopMutex; // these for VSTOP/VSTART
|
|
BOOLEAN bStop = FALSE;
|
|
HANDLE hStopEvent;
|
|
|
|
//
|
|
// These are resources for "on" and "off", used throughout.
|
|
//
|
|
LPTSTR szOn, szOff;
|
|
|
|
void
|
|
__cdecl
|
|
main(
|
|
int argc,
|
|
char *argv[],
|
|
char *envp[]
|
|
)
|
|
{
|
|
static char PgmFullPathBuf[MAX_PATH + 1];
|
|
static char CurrentDir[MAX_PATH + 1];
|
|
DWORD SessionPortHandle;
|
|
char *lpPgmName = NULL;
|
|
char *pch;
|
|
LPSTR lpFilePart;
|
|
int i;
|
|
|
|
DWORD dwThreadId;
|
|
HANDLE hThread;
|
|
|
|
#if DBG
|
|
fTrace = FALSE;
|
|
#endif
|
|
|
|
//
|
|
// skip program name
|
|
//
|
|
SKIP_ARG;
|
|
|
|
//
|
|
// look for flags for posix up to /C
|
|
//
|
|
//
|
|
|
|
while (argc) {
|
|
if ((argv[0][0] == '/') && ((argv[0][1]|('a'-'A')) == 'c')) {
|
|
if (argv[0][2]) {
|
|
argv[0] += 2;
|
|
} else {
|
|
SKIP_ARG;
|
|
}
|
|
break;
|
|
} else {
|
|
if (argv[0][0] == '/') {
|
|
switch (argv[0][1]|('a'-'A')) {
|
|
case 'p':
|
|
SKIP_ARG;
|
|
lpPgmName = *argv;
|
|
break;
|
|
#if DBG
|
|
case 'b':
|
|
#if 0
|
|
_asm int 3;
|
|
#endif
|
|
break;
|
|
case 'v':
|
|
fVerbose = TRUE;
|
|
break;
|
|
case 't':
|
|
fTrace = TRUE;
|
|
break;
|
|
#endif
|
|
default:
|
|
// error("posix: unknown flag: %s\n", argv[0]);
|
|
error(MSG_UNKNOWN_FLAG, argv[0]);
|
|
exit(1);
|
|
}
|
|
} else {
|
|
// error("usage: posix /c <path> [<args>]\n");
|
|
error(MSG_USAGE);
|
|
exit(1);
|
|
}
|
|
}
|
|
SKIP_ARG;
|
|
}
|
|
|
|
if (!argc) {
|
|
// error("posix: command missing\n");
|
|
error(MSG_COMMAND_MISSING);
|
|
exit(1);
|
|
}
|
|
|
|
//
|
|
// Set event handlers to handle Ctrl-C etc.
|
|
//
|
|
|
|
SetEventHandlers(TRUE);
|
|
|
|
//
|
|
// Connect with PSXSS
|
|
//
|
|
|
|
if (!(SessionPortHandle = InitPsxSessionPort()) ) {
|
|
// printf("posix: Cannot connect to Posix SubSystem\n");
|
|
error(MSG_CANNOT_CONNECT);
|
|
exit(1);
|
|
}
|
|
|
|
szOn = MyLoadString(IDS_ON);
|
|
szOff = MyLoadString(IDS_OFF);
|
|
|
|
pch = getenv("_POSIX_TERM");
|
|
if (NULL != pch && 0 == lstrcmpi(pch, szOn)) {
|
|
DoTrickyIO = TRUE;
|
|
}
|
|
|
|
if (DoTrickyIO) {
|
|
//
|
|
// Get handles to CONIN$ and CONOUT$ for terminal io.
|
|
//
|
|
//
|
|
|
|
hConsoleInput = CreateFile(
|
|
TEXT("CONIN$"),
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL
|
|
);
|
|
if (INVALID_HANDLE_VALUE == hConsoleInput) {
|
|
KdPrint(("POSIX: get con handle: 0x%x\n",
|
|
GetLastError()));
|
|
}
|
|
|
|
hConsoleOutput = CreateFile(
|
|
TEXT("CONOUT$"),
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL
|
|
);
|
|
if (INVALID_HANDLE_VALUE == hConsoleOutput) {
|
|
KdPrint(("POSIX: get con handle: 0x%x\n",
|
|
GetLastError()));
|
|
}
|
|
|
|
//
|
|
// Init terminal emulation globals.
|
|
//
|
|
TermioInit();
|
|
}
|
|
|
|
//
|
|
// get the full path of the program to execute
|
|
//
|
|
|
|
if (!lpPgmName) {
|
|
lpPgmName = argv[0];
|
|
}
|
|
|
|
GetFullPathName(lpPgmName, MAX_PATH, PgmFullPathBuf, &lpFilePart);
|
|
|
|
//
|
|
// Get our current working directory, so the Posix subsystem will know
|
|
// where to put the new Posix process.
|
|
//
|
|
|
|
(void)GetCWD(sizeof(CurrentDir), CurrentDir);
|
|
|
|
//
|
|
// Submit the request to start the process
|
|
//
|
|
|
|
if (!StartProcess(SessionPortHandle, PgmFullPathBuf, CurrentDir, argc,
|
|
argv, envp)) {
|
|
// printf("posix: Cannot start process\n");
|
|
error(MSG_CANNOT_START_PROC);
|
|
exit(1);
|
|
}
|
|
|
|
if (!DoTrickyIO) {
|
|
ExitThread(0);
|
|
}
|
|
|
|
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
|
|
|
|
InitializeCriticalSection(&KbdBufMutex);
|
|
hIoEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
hCanonEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
|
InitializeCriticalSection(&StopMutex);
|
|
hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
hThread = CreateThread(NULL, 0, ServeKbdInput, NULL, 0, &dwThreadId);
|
|
|
|
if (/* !hThread || */ !hIoEvent) {
|
|
KdPrint(("PSXSES: Cannot start keyboard server\n"));
|
|
exit(1);
|
|
}
|
|
|
|
ExitThread(0);
|
|
}
|
|
|
|
VOID
|
|
SetEventHandlers(
|
|
IN BOOL fSet
|
|
)
|
|
{
|
|
SetConsoleCtrlHandler((PVOID)EventHandlerRoutine, fSet);
|
|
}
|
|
|
|
int
|
|
GetCWD(
|
|
size_t size,
|
|
char *CurrentDir
|
|
)
|
|
{
|
|
char *pch, *pch2, *pch3, save, save2, save3;
|
|
HANDLE d;
|
|
WIN32_FIND_DATA FindData;
|
|
|
|
(void)GetCurrentDirectory(size, CurrentDir);
|
|
|
|
//
|
|
// Make sure the drive letter is upper-case.
|
|
//
|
|
|
|
CurrentDir[0] = (char) toupper(CurrentDir[0]);
|
|
|
|
//
|
|
// Go through the path a component at a time, and make
|
|
// sure that the directory names are in the correct
|
|
// case.
|
|
//
|
|
|
|
pch = strchr(CurrentDir, '\\');
|
|
if (NULL == pch) {
|
|
// we are in the root
|
|
return 0;
|
|
}
|
|
++pch;
|
|
|
|
for (;;) {
|
|
pch2 = strchr(pch, '\\');
|
|
if (NULL != pch2)
|
|
*pch2 = '\0';
|
|
|
|
d = FindFirstFile(CurrentDir, &FindData);
|
|
if (INVALID_HANDLE_VALUE == d) {
|
|
return -1;
|
|
}
|
|
FindClose(d);
|
|
|
|
strcpy(pch, FindData.cFileName);
|
|
if (NULL != pch2) {
|
|
*pch2 = '\\';
|
|
pch = pch2 + 1;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|