win_erlexec.c

来自「OTP是开放电信平台的简称」· C语言 代码 · 共 260 行

C
260
字号
/* ``The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved via the world wide web at http://www.erlang.org/. *  * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. *  * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' *  *     $Id$ *//* * Extra support for running the emulator on Windows. * Most of this only used when beam is run as a separate process. */#include <windows.h>#include <winuser.h>#include <wincon.h>#include <process.h>#include "sys.h"#include "erl_driver.h"extern int nohup;extern int keep_window;void error(char* format, ...);/* * Local functions. */static int start(char* emu, char** argv);static void start_winsock(void);static char* last_error(void);static char* last_wsa_error(void);static char* win32_errorstr(int error);static int has_console(void);static char** fnuttify_argv(char **argv);static void free_fnuttified(char **v);intstart_win_emulator(char* emu, char** argv, int start_detached){    int result;    if (start_detached) {	close(0);	close(1);	close(2);		putenv("ERL_CONSOLE_MODE=detached");	argv = fnuttify_argv(argv);	result = spawnv(_P_DETACH, emu, argv);	free_fnuttified(argv);    } else {	int argc = 0;	putenv("ERL_CONSOLE_MODE=window");	while (argv[argc] != NULL) {	    ++argc;	}	erl_start(argc, argv);	result = 0;    }    if (result == -1) {	error("Failed to execute %s: %s", emu, win32_errorstr(_doserrno));    }    return 0;}void __cdecl do_keep_window(void){    printf("\nPress any key to close window.\n");    sys_get_key(0);}intstart_emulator(char* emu, char** argv, int start_detached){    int result;    static char console_mode[] = "ERL_CONSOLE_MODE=tty:ccc";    char* fd_type;    char* title;    int argc = 0;    fd_type = strchr(console_mode, ':');    fd_type++;    _flushall();        /*     * If no console, we will spawn the emulator detached.     */    if (start_detached) {	close(0);	close(1);	close(2);	putenv("ERL_CONSOLE_MODE=detached");	argv = fnuttify_argv(argv);	result = spawnv(_P_DETACH, emu, argv);	free_fnuttified(argv);	if (result == -1) {	    return 1;	}	SetPriorityClass((HANDLE) result, GetPriorityClass(GetCurrentProcess()));	return 0;    }    /*     * Start the emulator.     */    if ((title = getenv("ERL_WINDOW_TITLE")) != NULL) {	SetConsoleTitle(title);    }    putenv(console_mode);    while (argv[argc] != NULL) {	++argc;    }    if (keep_window) {	atexit(do_keep_window);    }    erl_start(argc, argv);    return 0;}voiderror(char* format, ...){    char sbuf[2048];    va_list ap;    va_start(ap, format);    vsprintf(sbuf, format, ap);    va_end(ap);    if (has_console()) {	fprintf(stderr, "%s\n", sbuf);    } else {	MessageBox(NULL, sbuf, "Werl", MB_OK|MB_ICONERROR);    }    exit(1);}static char*last_error(void){    return win32_errorstr(GetLastError());}/* * Returns a human-readable description of the last error. * The returned pointer will be valid only as long as last-error() * isn't called again. */static char*win32_errorstr(int error){    static LPTSTR lpBufPtr = NULL;    if (lpBufPtr)	LocalFree(lpBufPtr);    FormatMessage(		  FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,		  NULL,		  error,		  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),		  (LPTSTR) &lpBufPtr,		  0,		  NULL);    SetLastError(error);    return lpBufPtr;}static inthas_console(void){    HANDLE handle = CreateFile("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE,			       NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);    if (handle != INVALID_HANDLE_VALUE) {        CloseHandle(handle);	return 1;    } else {        return 0;    }}static char** fnuttify_argv(char **argv){    char **v;    char *p;    char *q;    int c;    int i;    int n;    int m;    for (c = 0; argv[c]; ++c)	;    v = malloc(sizeof(char *) * (c+1));    v[c] = NULL;    for (i = 0; i < c; ++i) {	p = argv[i];	n = m = 0;	while (*p) {	    if (*p == ' ') {		m = 2;	    } else if (*p == '"') {		m = 2;		++n;	    }	    ++p;	}	v[i] = malloc((p - argv[i]) + 1 + n + m);	p = argv[i];	q = v[i];	if (n || m) {	    if (m) {		*q++ = '"';	    }	    while (*p) {		if (*p == '"') {		    *q++ = '\\';		}		*q++ = *p++;	    }	    if (m) {		*q++ = '"';	    }	    *q = '\0';	} else {	    strcpy(q,p);	}    }    return v;}static void free_fnuttified(char **v){    char **t = v;    while(*t) {	free(*t);	++t;    }    free(v);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?