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

📄 daemon_win32.cpp

📁 硬盘各项性能的测试,如温度容量版本健康度型号
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	SetConsoleCtrlHandler(child_console_handler, TRUE/*add*/);	if (!ok)		return -1;	if (title)		SetConsoleTitleA(title);	if (reopen_stdin)		freopen("conin$",  "r", stdin);	if (reopen_stdout)		freopen("conout$", "w", stdout);	if (reopen_stderr)		freopen("conout$", "w", stderr);	reopen_stdin = reopen_stdout = reopen_stderr = 0;	return 0;}// Detach daemon from console & parentint daemon_detach(const char * ident){	if (!svc_mode) {		if (ident) {			// Print help			FILE * f = ( isatty(fileno(stdout)) ? stdout					   : isatty(fileno(stderr)) ? stderr : NULL);			if (f)				daemon_help(f, ident, "now detaches from console into background mode");		}		// Signal detach to parent		if (sig_event(EVT_DETACHED) != 1) {			if (!debugging())				return -1;		}		daemon_disable_console();	}	else {		// Signal end of initialization to service control manager		service_report_status(SERVICE_RUNNING, 0);		reopen_stdin = reopen_stdout = reopen_stderr = 1;	}	return 0;}/////////////////////////////////////////////////////////////////////////////// MessageBox#ifndef _MT//MT runtime not necessary, because mbox_thread uses no unsafe lib functions//#error Program must be linked with multithreaded runtime library#endifstatic LONG mbox_count; // # mbox_thread()sstatic HANDLE mbox_mutex; // Show 1 box at a time (not necessary for service)typedef struct mbox_args_s {	HANDLE taken; const char * title, * text; int mode;} mbox_args;// Thread to display one message boxstatic ULONG WINAPI mbox_thread(LPVOID arg){	// Take args	mbox_args * mb = (mbox_args *)arg;	char title[100]; char text[1000]; int mode;	strncpy(title, mb->title, sizeof(title)-1); title[sizeof(title)-1] = 0;	strncpy(text , mb->text , sizeof(text )-1); text [sizeof(text )-1] = 0;	mode = mb->mode;	SetEvent(mb->taken);	// Show only one box at a time	WaitForSingleObject(mbox_mutex, INFINITE);	MessageBoxA(NULL, text, title, mode);	ReleaseMutex(mbox_mutex);	InterlockedDecrement(&mbox_count);	return 0;}// Display a message boxint daemon_messagebox(int system, const char * title, const char * text){	mbox_args mb;	HANDLE ht; DWORD tid;	// Create mutex during first call	if (!mbox_mutex)		mbox_mutex = CreateMutex(NULL/*!inherit*/, FALSE/*!owned*/, NULL/*unnamed*/);	// Allow at most 10 threads	if (InterlockedIncrement(&mbox_count) > 10) {		InterlockedDecrement(&mbox_count);		return -1;	}	// Create thread	mb.taken = CreateEvent(NULL/*!inherit*/, FALSE, FALSE/*!signaled*/, NULL/*unnamed*/);	mb.mode = MB_OK|MB_ICONWARNING	         |(svc_mode?MB_SERVICE_NOTIFICATION:0)	         |(system?MB_SYSTEMMODAL:MB_APPLMODAL);	mb.title = title; mb.text = text;	mb.text = text;	if (!(ht = CreateThread(NULL, 0, mbox_thread, &mb, 0, &tid)))		return -1;	// Wait for args taken	if (WaitForSingleObject(mb.taken, 10000) != WAIT_OBJECT_0)		TerminateThread(ht, 0);	CloseHandle(mb.taken);	CloseHandle(ht);	return 0;}/////////////////////////////////////////////////////////////////////////////// Spawn a command and redirect <inpbuf >outbuf// return command's exitcode or -1 on errorint daemon_spawn(const char * cmd,                 const char * inpbuf, int inpsize,                 char *       outbuf, int outsize ){	HANDLE pipe_inp_r, pipe_inp_w, pipe_out_r, pipe_out_w, pipe_err_w, h;	char temp_path[MAX_PATH];	DWORD flags, num_io, exitcode;	int use_file, state, i;	SECURITY_ATTRIBUTES sa;	STARTUPINFO si; PROCESS_INFORMATION pi;	HANDLE self = GetCurrentProcess();	if (GetVersion() & 0x80000000L) {		// Win9x/ME: A calling process never receives EOF if output of COMMAND.COM or		// any other DOS program is redirected via a pipe. Using a temp file instead.		use_file = 1; flags = DETACHED_PROCESS;	}	else {		// NT4/2000/XP: If DETACHED_PROCESS is used, CMD.EXE opens a new console window		// for each external command in a redirected .BAT file.		// Even (DETACHED_PROCESS|CREATE_NO_WINDOW) does not work.		use_file = 0; flags = CREATE_NO_WINDOW;	}	// Create stdin pipe with inheritable read side	memset(&sa, 0, sizeof(sa)); sa.nLength = sizeof(sa);	sa.bInheritHandle = TRUE;	if (!CreatePipe(&pipe_inp_r, &h, &sa/*inherit*/, inpsize*2+13))		return -1;	if (!DuplicateHandle(self, h, self, &pipe_inp_w,		0, FALSE/*!inherit*/, DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE)) {		CloseHandle(pipe_inp_r);		return -1;	}	memset(&sa, 0, sizeof(sa)); sa.nLength = sizeof(sa);	sa.bInheritHandle = TRUE;	if (!use_file) {		// Create stdout pipe with inheritable write side		if (!CreatePipe(&h, &pipe_out_w, &sa/*inherit*/, outsize)) {			CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w);			return -1;		}	}	else {		// Create temp file with inheritable write handle		char temp_dir[MAX_PATH];		if (!GetTempPathA(sizeof(temp_dir), temp_dir))			strcpy(temp_dir, ".");		if (!GetTempFileNameA(temp_dir, "out"/*prefix*/, 0/*create unique*/, temp_path)) {			CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w);			return -1;		}		if ((h = CreateFileA(temp_path, GENERIC_READ|GENERIC_WRITE,			0/*no sharing*/, &sa/*inherit*/, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) {			CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w);			return -1;		}		if (!DuplicateHandle(self, h, self, &pipe_out_w,			GENERIC_WRITE, TRUE/*inherit*/, 0)) {			CloseHandle(h); CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w);			return -1;		}	}	if (!DuplicateHandle(self, h, self, &pipe_out_r,		GENERIC_READ, FALSE/*!inherit*/, DUPLICATE_CLOSE_SOURCE)) {		CloseHandle(pipe_out_w); CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w);		return -1;	}	// Create stderr handle as dup of stdout write side	if (!DuplicateHandle(self, pipe_out_w, self, &pipe_err_w,		0, TRUE/*inherit*/, DUPLICATE_SAME_ACCESS)) {		CloseHandle(pipe_out_r); CloseHandle(pipe_out_w);		CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w);		return -1;	}	// Create process with pipes/file as stdio	memset(&si, 0, sizeof(si)); si.cb = sizeof(si);	si.hStdInput  = pipe_inp_r;	si.hStdOutput = pipe_out_w;	si.hStdError  = pipe_err_w;	si.dwFlags = STARTF_USESTDHANDLES;	if (!CreateProcessA(		NULL, (char*)cmd,		NULL, NULL, TRUE/*inherit*/,		flags/*DETACHED_PROCESS or CREATE_NO_WINDOW*/,		NULL, NULL, &si, &pi)) {		CloseHandle(pipe_err_w);		CloseHandle(pipe_out_r); CloseHandle(pipe_out_w);		CloseHandle(pipe_inp_r); CloseHandle(pipe_inp_w);		return -1;	}	CloseHandle(pi.hThread);	// Close inherited handles	CloseHandle(pipe_inp_r);	CloseHandle(pipe_out_w);	CloseHandle(pipe_err_w);	// Copy inpbuf to stdin	// convert \n => \r\n 	for (i = 0; i < inpsize; ) {		int len = 0;		while (i+len < inpsize && inpbuf[i+len] != '\n')			len++;		if (len > 0)			WriteFile(pipe_inp_w, inpbuf+i, len, &num_io, NULL);		i += len;		if (i < inpsize) {			WriteFile(pipe_inp_w, "\r\n", 2, &num_io, NULL);			i++;		}	}	CloseHandle(pipe_inp_w);	exitcode = 42;	for (state = 0; state < 2; state++) {		// stdout pipe: read pipe first		// stdout file: wait for process first		if (state == use_file) {			// Copy stdout to output buffer until full, rest to /dev/null			// convert \r\n => \n			if (use_file)				SetFilePointer(pipe_out_r, 0, NULL, FILE_BEGIN);			for (i = 0; ; ) {				char buf[256];				int j;				if (!ReadFile(pipe_out_r, buf, sizeof(buf), &num_io, NULL) || num_io == 0)					break;				for (j = 0; i < outsize-1 && j < (int)num_io; j++) {					if (buf[j] != '\r')						outbuf[i++] = buf[j];				}			}			outbuf[i] = 0;			CloseHandle(pipe_out_r);			if (use_file)				DeleteFileA(temp_path);		}		else {			// Wait for process exitcode			WaitForSingleObject(pi.hProcess, INFINITE);			GetExitCodeProcess(pi.hProcess, &exitcode);			CloseHandle(pi.hProcess);		}	}	return exitcode;}/////////////////////////////////////////////////////////////////////////////// Initd Functionsstatic int wait_signaled(HANDLE h, int seconds){	int i;	for (i = 0; ; ) {		if (WaitForSingleObject(h, 1000L) == WAIT_OBJECT_0)			return 0;		if (++i >= seconds)			return -1;		fputchar('.'); fflush(stdout);	}}static int wait_evt_running(int seconds, int exists){	int i;	if (event_exists(EVT_RUNNING) == exists)		return 0;	for (i = 0; ; ) {		Sleep(1000);		if (event_exists(EVT_RUNNING) == exists)			return 0;		if (++i >= seconds)			return -1;		fputchar('.'); fflush(stdout);	}}static int is_initd_command(char * s){	if (!strcmp(s, "status"))		return EVT_RUNNING;	if (!strcmp(s, "stop"))		return SIGTERM;	if (!strcmp(s, "reload"))		return SIGHUP;	if (!strcmp(s, "sigusr1"))		return SIGUSR1;	if (!strcmp(s, "sigusr2"))		return SIGUSR2;	if (!strcmp(s, "restart"))		return EVT_RESTART;	return -1;}static int initd_main(const char * ident, int argc, char **argv){	int rc;	if (argc < 2)		return -1;	if ((rc = is_initd_command(argv[1])) < 0)		return -1;	if (argc != 2) {		printf("%s: no arguments allowed for command %s\n", ident, argv[1]);		return 1;	}	switch (rc) {		default:		case EVT_RUNNING:			printf("Checking for %s:", ident); fflush(stdout);			rc = event_exists(EVT_RUNNING);			puts(rc ? " running" : " not running");			return (rc ? 0 : 1);		case SIGTERM:			printf("Stopping %s:", ident); fflush(stdout);			rc = sig_event(SIGTERM);			if (rc <= 0) {				puts(rc < 0 ? " not running" : " error");				return (rc < 0 ? 0 : 1);			}			rc = wait_evt_running(10, 0);			puts(!rc ? " done" : " timeout");			return (!rc ? 0 : 1);		case SIGHUP:			printf("Reloading %s:", ident); fflush(stdout);			rc = sig_event(SIGHUP);			puts(rc > 0 ? " done" : rc == 0 ? " error" : " not running");			return (rc > 0 ? 0 : 1);		case SIGUSR1:		case SIGUSR2:			printf("Sending SIGUSR%d to %s:", (rc-SIGUSR1+1), ident); fflush(stdout);			rc = sig_event(rc);			puts(rc > 0 ? " done" : rc == 0 ? " error" : " not running");			return (rc > 0 ? 0 : 1);		case EVT_RESTART:			{				HANDLE rst;				printf("Stopping %s:", ident); fflush(stdout);				if (event_exists(EVT_DETACHED)) {					puts(" not detached, cannot restart");					return 1;				}				if (!(rst = create_event(EVT_RESTART, FALSE, FALSE, NULL))) {					puts(" error");					return 1;				}				rc = sig_event(SIGTERM);				if (rc <= 0) {					puts(rc < 0 ? " not running" : " error");					CloseHandle(rst);					return 1;				}				rc = wait_signaled(rst, 10);				CloseHandle(rst);				if (rc) {					puts(" timeout");					return 1;				}				puts(" done");				Sleep(100);				printf("Starting %s:", ident); fflush(stdout);				rc = wait_evt_running(10, 1);				puts(!rc ? " done" : " error");				return (!rc ? 0 : 1);			}	}}/////////////////////////////////////////////////////////////////////////////// Windows Service Functionsint daemon_winsvc_exitcode; // Set by app to exit(code)static SERVICE_STATUS_HANDLE svc_handle;static SERVICE_STATUS svc_status;// Report status to SCMstatic void service_report_status(int state, int seconds){	// TODO: Avoid race	static DWORD checkpoint = 1;	static DWORD accept_more = SERVICE_ACCEPT_PARAMCHANGE; // Win2000/XP	svc_status.dwCurrentState = state;	svc_status.dwWaitHint = seconds*1000;

⌨️ 快捷键说明

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