⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 daemon_win32.cpp

📁 硬盘各项性能的测试,如温度容量版本健康度型号
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * os_win32/daemon_win32.cpp * * Home page of code is: http://smartmontools.sourceforge.net * * Copyright (C) 2004-8 Christian Franke <smartmontools-support@lists.sourceforge.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * You should have received a copy of the GNU General Public License * (for example COPYING); if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <io.h>#define WIN32_LEAN_AND_MEAN// Need MB_SERVICE_NOTIFICATION (NT4/2000/XP), IsDebuggerPresent() (Win98/ME/NT4/2000/XP)#define _WIN32_WINNT 0x0400 #include <windows.h>#ifdef _DEBUG#include <crtdbg.h>#endif#include "daemon_win32.h"const char *daemon_win32_c_cvsid = "$Id: daemon_win32.cpp,v 1.12 2008/03/04 22:09:48 ballen4705 Exp $"DAEMON_WIN32_H_CVSID;/////////////////////////////////////////////////////////////////////////////#define ARGUSED(x) ((void)(x))// Prevent spawning of child process if debugging#ifdef _DEBUG#define debugging() IsDebuggerPresent()#else#define debugging() FALSE#endif#define EVT_NAME_LEN 260// Internal events (must be > SIGUSRn)#define EVT_RUNNING   100 // Exists when running, signaled on creation#define EVT_DETACHED  101 // Signaled when child detaches from console#define EVT_RESTART   102 // Signaled when child should restartstatic void make_name(char * name, int sig){	int i;	if (!GetModuleFileNameA(NULL, name, EVT_NAME_LEN-10))		strcpy(name, "DaemonEvent");	for (i = 0; name[i]; i++) {		char c = name[i];		if (!(   ('0' <= c && c <= '9')		      || ('A' <= c && c <= 'Z')		      || ('a' <= c && c <= 'z')))			  name[i] = '_';	}	sprintf(name+strlen(name), "-%d", sig);}static HANDLE create_event(int sig, BOOL initial, BOOL errmsg, BOOL * exists){	char name[EVT_NAME_LEN];	HANDLE h;	if (sig >= 0)		make_name(name, sig);	else		name[0] = 0;	if (exists)		*exists = FALSE;	if (!(h = CreateEventA(NULL, FALSE, initial, (name[0] ? name : NULL)))) {		if (errmsg)			fprintf(stderr, "CreateEvent(.,\"%s\"): Error=%ld\n", name, GetLastError());		return 0;	}	if (GetLastError() == ERROR_ALREADY_EXISTS) {		if (!exists) {			if (errmsg)				fprintf(stderr, "CreateEvent(.,\"%s\"): Exists\n", name);			CloseHandle(h);			return 0;		}		*exists = TRUE;	}	return h;}static HANDLE open_event(int sig){	char name[EVT_NAME_LEN];	make_name(name, sig);	return OpenEventA(EVENT_MODIFY_STATE, FALSE, name);}static int event_exists(int sig){	char name[EVT_NAME_LEN];	HANDLE h;	make_name(name, sig);	if (!(h = OpenEventA(EVENT_MODIFY_STATE, FALSE, name)))		return 0;	CloseHandle(h);	return 1;}static int sig_event(int sig){	char name[EVT_NAME_LEN];	HANDLE h;	make_name(name, sig);	if (!(h = OpenEventA(EVENT_MODIFY_STATE, FALSE, name))) {		make_name(name, EVT_RUNNING);		if (!(h = OpenEvent(EVENT_MODIFY_STATE, FALSE, name)))			return -1;		CloseHandle(h);		return 0;	}	SetEvent(h);	CloseHandle(h);	return 1;}static void daemon_help(FILE * f, const char * ident, const char * message){	fprintf(f,		"%s: %s.\n"		"Use \"%s status|stop|reload|restart|sigusr1|sigusr2\" to control daemon.\n",		ident, message, ident);	fflush(f);}/////////////////////////////////////////////////////////////////////////////// Parent Processstatic BOOL WINAPI parent_console_handler(DWORD event){	switch (event) {		case CTRL_C_EVENT:		case CTRL_BREAK_EVENT:			return TRUE; // Ignore	}	return FALSE; // continue with next handler ...}static int parent_main(HANDLE rev){	HANDLE dev;	HANDLE ht[2];	char * cmdline;	STARTUPINFO si;	PROCESS_INFORMATION pi;	DWORD rc, exitcode;	// Ignore ^C, ^BREAK in parent	SetConsoleCtrlHandler(parent_console_handler, TRUE/*add*/);	// Create event used by child to signal daemon_detach()	if (!(dev = create_event(EVT_DETACHED, FALSE/*not signaled*/, TRUE, NULL/*must not exist*/))) {		CloseHandle(rev);		return 101;	}	// Restart process with same args	cmdline = GetCommandLineA();	memset(&si, 0, sizeof(si)); si.cb = sizeof(si);		if (!CreateProcessA(		NULL, cmdline,		NULL, NULL, TRUE/*inherit*/,		0, NULL, NULL, &si, &pi)) {		fprintf(stderr, "CreateProcess(.,\"%s\",.) failed, Error=%ld\n", cmdline, GetLastError());		CloseHandle(rev); CloseHandle(dev);		return 101;	}	CloseHandle(pi.hThread);	// Wait for daemon_detach() or exit()	ht[0] = dev; ht[1] = pi.hProcess;	rc = WaitForMultipleObjects(2, ht, FALSE/*or*/, INFINITE);	if (!(/*WAIT_OBJECT_0(0) <= rc && */ rc < WAIT_OBJECT_0+2)) {		fprintf(stderr, "WaitForMultipleObjects returns %lX\n", rc);		TerminateProcess(pi.hProcess, 200);	}	CloseHandle(rev); CloseHandle(dev);	// Get exit code	if (!GetExitCodeProcess(pi.hProcess, &exitcode))		exitcode = 201;	else if (exitcode == STILL_ACTIVE) // detach()ed, assume OK		exitcode = 0;	CloseHandle(pi.hProcess);	return exitcode;}/////////////////////////////////////////////////////////////////////////////// Child Processstatic int svc_mode;   // Running as service?static int svc_paused; // Service paused?static void service_report_status(int state, int waithint);// Tables of signal handler and corresponding eventstypedef void (*sigfunc_t)(int);#define MAX_SIG_HANDLERS 8static int num_sig_handlers = 0;static sigfunc_t sig_handlers[MAX_SIG_HANDLERS];static int sig_numbers[MAX_SIG_HANDLERS];static HANDLE sig_events[MAX_SIG_HANDLERS];static HANDLE sighup_handle, sigint_handle, sigbreak_handle;static HANDLE sigterm_handle, sigusr1_handle;static HANDLE running_event;static int reopen_stdin, reopen_stdout, reopen_stderr;// Handler for windows console eventsstatic BOOL WINAPI child_console_handler(DWORD event){	// Caution: runs in a new thread	// TODO: Guard with a mutex	HANDLE h = 0;	switch (event) {		case CTRL_C_EVENT: // <CONTROL-C> (SIGINT)			h = sigint_handle; break;		case CTRL_BREAK_EVENT: // <CONTROL-Break> (SIGBREAK/SIGQUIT)		case CTRL_CLOSE_EVENT: // User closed console or abort via task manager			h = sigbreak_handle; break;		case CTRL_LOGOFF_EVENT: // Logout/Shutdown (SIGTERM)		case CTRL_SHUTDOWN_EVENT:			h = sigterm_handle; break;	}	if (!h)		return FALSE; // continue with next handler	// Signal event	if (!SetEvent(h))		return FALSE;	return TRUE;}static void child_exit(void){	int i;	char * cmdline;	HANDLE rst;	STARTUPINFO si;	PROCESS_INFORMATION pi;	for (i = 0; i < num_sig_handlers; i++)		CloseHandle(sig_events[i]);	num_sig_handlers = 0;	CloseHandle(running_event); running_event = 0;	// Restart?	if (!(rst = open_event(EVT_RESTART)))		return; // No => normal exit	// Yes => Signal exit and restart process	Sleep(500);	SetEvent(rst);	CloseHandle(rst);	Sleep(500);	cmdline = GetCommandLineA();	memset(&si, 0, sizeof(si)); si.cb = sizeof(si);	si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE;	if (!CreateProcessA(		NULL, cmdline,		NULL, NULL, TRUE/*inherit*/,		0, NULL, NULL, &si, &pi)) {		fprintf(stderr, "CreateProcess(.,\"%s\",.) failed, Error=%ld\n", cmdline, GetLastError());	}	CloseHandle(pi.hThread); CloseHandle(pi.hProcess);}static int child_main(HANDLE hev,int (*main_func)(int, char **), int argc, char **argv){	// Keep EVT_RUNNING open until exit	running_event = hev;	// Install console handler	SetConsoleCtrlHandler(child_console_handler, TRUE/*add*/);	// Install restart handler	atexit(child_exit);	// Continue in main_func() to do the real work	return main_func(argc, argv);}// Simulate signal()sigfunc_t daemon_signal(int sig, sigfunc_t func){	int i;	HANDLE h;	if (func == SIG_DFL || func == SIG_IGN)		return func; // TODO	for (i = 0; i < num_sig_handlers; i++) {		if (sig_numbers[i] == sig) {			sigfunc_t old = sig_handlers[i];			sig_handlers[i] = func;			return old;		}	}	if (num_sig_handlers >= MAX_SIG_HANDLERS)		return SIG_ERR;	if (!(h = create_event((!svc_mode ? sig : -1), FALSE, TRUE, NULL)))		return SIG_ERR;	sig_events[num_sig_handlers]   = h;	sig_numbers[num_sig_handlers]  = sig;	sig_handlers[num_sig_handlers] = func;	switch (sig) {		case SIGHUP:   sighup_handle   = h; break;		case SIGINT:   sigint_handle   = h; break;		case SIGTERM:  sigterm_handle  = h; break;		case SIGBREAK: sigbreak_handle = h; break;		case SIGUSR1:  sigusr1_handle  = h; break;	}	num_sig_handlers++;	return SIG_DFL;}// strsignal()const char * daemon_strsignal(int sig){	switch (sig) {		case SIGHUP:  return "SIGHUP";		case SIGINT:  return "SIGINT";		case SIGTERM: return "SIGTERM";		case SIGBREAK:return "SIGBREAK";		case SIGUSR1: return "SIGUSR1";		case SIGUSR2: return "SIGUSR2";		default:      return "*UNKNOWN*";	}}// Simulate sleep()void daemon_sleep(int seconds){	do {		if (num_sig_handlers <= 0) {			Sleep(seconds*1000L);		}		else {			// Wait for any signal or timeout			DWORD rc = WaitForMultipleObjects(num_sig_handlers, sig_events,				FALSE/*OR*/, seconds*1000L);			if (rc != WAIT_TIMEOUT) {				if (!(/*WAIT_OBJECT_0(0) <= rc && */ rc < WAIT_OBJECT_0+(unsigned)num_sig_handlers)) {					fprintf(stderr,"WaitForMultipleObjects returns %lu\n", rc);					Sleep(seconds*1000L);					return;				}				// Call Handler				sig_handlers[rc-WAIT_OBJECT_0](sig_numbers[rc-WAIT_OBJECT_0]);				break;			}		}	} while (svc_paused);}// Disable/Enable consolevoid daemon_disable_console(){	SetConsoleCtrlHandler(child_console_handler, FALSE/*remove*/);	reopen_stdin = reopen_stdout = reopen_stderr = 0;	if (isatty(fileno(stdin))) {		fclose(stdin); reopen_stdin = 1;	}	if (isatty(fileno(stdout))) {		fclose(stdout); reopen_stdout = 1;	}	if (isatty(fileno(stderr))) {		fclose(stderr); reopen_stderr = 1;	}	FreeConsole();	SetConsoleCtrlHandler(child_console_handler, TRUE/*add*/);}int daemon_enable_console(const char * title){	BOOL ok;	SetConsoleCtrlHandler(child_console_handler, FALSE/*remove*/);	ok = AllocConsole();

⌨️ 快捷键说明

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