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

📄 exec.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* {{{ proto string escapeshellarg(string arg)   Quote and escape an argument for use in a shell command */PHP_FUNCTION(escapeshellarg){	pval **arg1;	char *cmd = NULL;	if (zend_get_parameters_ex(1, &arg1) == FAILURE) {		WRONG_PARAM_COUNT;	}		convert_to_string_ex(arg1);	if (Z_STRLEN_PP(arg1)) {		cmd = php_escape_shell_arg(Z_STRVAL_PP(arg1));		RETVAL_STRING(cmd, 1);		efree(cmd);	}}/* }}} *//* {{{ proto string shell_exec(string cmd)   Execute command via shell and return complete output as string */PHP_FUNCTION(shell_exec){	FILE *in;	int readbytes, total_readbytes=0, allocated_space;	pval **cmd;	char *ret;	if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &cmd)==FAILURE) {		WRONG_PARAM_COUNT;	}		if (PG(safe_mode)) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot execute using backquotes in Safe Mode");		RETURN_FALSE;	}	convert_to_string_ex(cmd);#ifdef PHP_WIN32	if ((in=VCWD_POPEN(Z_STRVAL_PP(cmd), "rt"))==NULL) {#else	if ((in=VCWD_POPEN(Z_STRVAL_PP(cmd), "r"))==NULL) {#endif		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to execute '%s'", Z_STRVAL_PP(cmd));		RETURN_FALSE;	}	allocated_space = EXEC_INPUT_BUF;	ret = (char *) emalloc(allocated_space);	while (1) {		readbytes = fread(ret+total_readbytes, 1, EXEC_INPUT_BUF, in);		if (readbytes<=0) {			break;		}		total_readbytes += readbytes;		allocated_space = total_readbytes+EXEC_INPUT_BUF;		ret = (char *) erealloc(ret, allocated_space);	}	pclose(in);		RETVAL_STRINGL(ret, total_readbytes, 0);	Z_STRVAL_P(return_value)[total_readbytes] = '\0';	}/* }}} *//* {{{ proc_open resource management */static int le_proc_open;static void proc_open_rsrc_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC){#ifdef PHP_WIN32	HANDLE child;	DWORD wstatus;		child = (HANDLE)rsrc->ptr;	WaitForSingleObject(child, INFINITE);	GetExitCodeProcess(child, &wstatus);	FG(pclose_ret) = wstatus;	CloseHandle(child);#else# if HAVE_SYS_WAIT_H	int wstatus;	pid_t child, wait_pid;		child = (pid_t)rsrc->ptr;	do {		wait_pid = waitpid(child, &wstatus, 0);	} while (wait_pid == -1 && errno == EINTR);		if (wait_pid == -1)		FG(pclose_ret) = -1;	else {		if (WIFEXITED(wstatus))			wstatus = WEXITSTATUS(wstatus);		FG(pclose_ret) = wstatus;	}	# else	FG(pclose_ret) = -1;# endif#endif}PHP_MINIT_FUNCTION(proc_open){	le_proc_open = zend_register_list_destructors_ex(proc_open_rsrc_dtor, NULL, "process", module_number);	return SUCCESS;}/* }}} *//* {{{ proto int proc_close(resource process)   close a process opened by proc_open */PHP_FUNCTION(proc_close){	zval *proc;	void *child;		if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &proc) == FAILURE) {		RETURN_FALSE;	}	ZEND_FETCH_RESOURCE(child, void *, &proc, -1, "process", le_proc_open);		zend_list_delete(Z_LVAL_P(proc));	RETURN_LONG(FG(pclose_ret));}/* }}} *//* {{{ handy definitions for portability/readability */#ifdef PHP_WIN32typedef HANDLE descriptor_t;# define pipe(pair)		(CreatePipe(&pair[0], &pair[1], &security, 2048L) ? 0 : -1)# define COMSPEC_NT	"cmd.exe"# define COMSPEC_9X	"command.com"static inline HANDLE dup_handle(HANDLE src, BOOL inherit, BOOL closeorig){	HANDLE copy, self = GetCurrentProcess();		if (!DuplicateHandle(self, src, self, &copy, 0, inherit, DUPLICATE_SAME_ACCESS |				(closeorig ? DUPLICATE_CLOSE_SOURCE : 0)))		return NULL;	return copy;}static inline HANDLE dup_fd_as_handle(int fd){	return dup_handle((HANDLE)_get_osfhandle(fd), TRUE, FALSE);}# define close_descriptor(fd)	CloseHandle(fd)#elsetypedef int descriptor_t;# define close_descriptor(fd)	close(fd)#endif#define DESC_PIPE		1#define DESC_FILE		2#define DESC_PARENT_MODE_WRITE	8struct php_proc_open_descriptor_item {	int index; 							/* desired fd number in child process */	descriptor_t parentend, childend;	/* fds for pipes in parent/child */	int mode;							/* mode for proc_open code */	int mode_flags;						/* mode flags for opening fds */};/* }}} *//* {{{ proto resource proc_open(string command, array descriptorspec, array &pipes)   Run a process with more control over it's file descriptors */PHP_FUNCTION(proc_open){#define MAX_DESCRIPTORS	16	char *command;	int command_len;	zval *descriptorspec;	zval *pipes;	int ndesc = 0;	int i;	zval **descitem = NULL;	HashPosition pos;	struct php_proc_open_descriptor_item descriptors[MAX_DESCRIPTORS];#ifdef PHP_WIN32	PROCESS_INFORMATION pi;	STARTUPINFO si;	BOOL newprocok;	HANDLE child;	SECURITY_ATTRIBUTES security;	char *command_with_cmd;#else	pid_t child;#endif	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "saz", &command,				&command_len, &descriptorspec, &pipes) == FAILURE) {		RETURN_FALSE;	}	if (FAILURE == php_make_safe_mode_command(command, &command TSRMLS_CC)) {		RETURN_FALSE;	}	command_len = strlen(command);		memset(descriptors, 0, sizeof(descriptors));#ifdef PHP_WIN32	/* we use this to allow the child to inherit handles */	memset(&security, 0, sizeof(security));	security.nLength = sizeof(security);	security.bInheritHandle = TRUE;	security.lpSecurityDescriptor = NULL;#endif		/* walk the descriptor spec and set up files/pipes */	zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(descriptorspec), &pos);	while (zend_hash_get_current_data_ex(Z_ARRVAL_P(descriptorspec), (void **)&descitem, &pos) == SUCCESS) {		char *str_index;		ulong nindex;		zval **ztype;		str_index = NULL;		zend_hash_get_current_key_ex(Z_ARRVAL_P(descriptorspec), &str_index, NULL, &nindex, 0, &pos);		if (str_index) {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "descriptor spec must be an integer indexed array");			goto exit_fail;		}		descriptors[ndesc].index = nindex;		if (Z_TYPE_PP(descitem) == IS_RESOURCE) {			/* should be a stream - try and dup the descriptor */			php_stream *stream;			int fd;			php_stream_from_zval(stream, descitem);			if (FAILURE == php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&fd, REPORT_ERRORS)) {				goto exit_fail;			}#ifdef PHP_WIN32			descriptors[ndesc].childend = dup_fd_as_handle(fd);			if (descriptors[ndesc].childend == NULL) {				php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to dup File-Handle for descriptor %lu", nindex);				goto exit_fail;			}#else			descriptors[ndesc].childend = dup(fd);			if (descriptors[ndesc].childend < 0) {				php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to dup File-Handle for descriptor %lu - %s", nindex, strerror(errno));				goto exit_fail;			}#endif			descriptors[ndesc].mode = DESC_FILE;		} else if (Z_TYPE_PP(descitem) != IS_ARRAY) {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Descriptor item must be either an array or a File-Handle");			goto exit_fail;		} else {			if (zend_hash_index_find(Z_ARRVAL_PP(descitem), 0, (void **)&ztype) == SUCCESS) {				convert_to_string_ex(ztype);			} else {				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing handle qualifier in array");				goto exit_fail;			}			if (strcmp(Z_STRVAL_PP(ztype), "pipe") == 0) {				descriptor_t newpipe[2];				zval **zmode;				if (zend_hash_index_find(Z_ARRVAL_PP(descitem), 1, (void **)&zmode) == SUCCESS) {					convert_to_string_ex(zmode);				} else {					php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing mode parameter for 'pipe'");					goto exit_fail;				}				descriptors[ndesc].mode = DESC_PIPE;				if (0 != pipe(newpipe)) {					php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to create pipe %s", strerror(errno));					goto exit_fail;				}				if (strcmp(Z_STRVAL_PP(zmode), "w") != 0) {					descriptors[ndesc].parentend = newpipe[1];					descriptors[ndesc].childend = newpipe[0];					descriptors[ndesc].mode |= DESC_PARENT_MODE_WRITE;				} else {					descriptors[ndesc].parentend = newpipe[0];					descriptors[ndesc].childend = newpipe[1];				}#ifdef PHP_WIN32				/* don't let the child inherit the parent side of the pipe */				descriptors[ndesc].parentend = dup_handle(descriptors[ndesc].parentend, FALSE, TRUE);#endif				descriptors[ndesc].mode_flags = descriptors[ndesc].mode & DESC_PARENT_MODE_WRITE ? O_WRONLY : O_RDONLY;#ifdef PHP_WIN32				if (Z_STRLEN_PP(zmode) >= 2 && Z_STRVAL_PP(zmode)[1] == 'b')					descriptors[ndesc].mode_flags |= O_BINARY;#endif							} else if (strcmp(Z_STRVAL_PP(ztype), "file") == 0) {				zval **zfile, **zmode;				int fd;				php_stream *stream;				size_t old_size = FG(def_chunk_size);				descriptors[ndesc].mode = DESC_FILE;				if (zend_hash_index_find(Z_ARRVAL_PP(descitem), 1, (void **)&zfile) == SUCCESS) {					convert_to_string_ex(zfile);				} else {					php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing file name parameter for 'file'");					goto exit_fail;				}				if (zend_hash_index_find(Z_ARRVAL_PP(descitem), 2, (void **)&zmode) == SUCCESS) {					convert_to_string_ex(zmode);				} else {					php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing mode parameter for 'file'");					goto exit_fail;				}				/* try a wrapper */				FG(def_chunk_size) = 1;				stream = php_stream_open_wrapper(Z_STRVAL_PP(zfile), Z_STRVAL_PP(zmode),						ENFORCE_SAFE_MODE|REPORT_ERRORS, NULL);				FG(def_chunk_size) = old_size;				/* force into an fd */				if (stream == NULL || FAILURE == php_stream_cast(stream,							PHP_STREAM_CAST_RELEASE|PHP_STREAM_AS_FD,							(void **)&fd, REPORT_ERRORS)) {					goto exit_fail;				}#ifdef PHP_WIN32				descriptors[ndesc].childend = (HANDLE)_get_osfhandle(fd);#else				descriptors[ndesc].childend = fd;#endif			} else {				php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not a valid descriptor spec/mode", Z_STRVAL_PP(ztype));				goto exit_fail;			}		}		zend_hash_move_forward_ex(Z_ARRVAL_P(descriptorspec), &pos);		if (++ndesc == MAX_DESCRIPTORS)			break;	}#ifdef PHP_WIN32	memset(&si, 0, sizeof(si));	si.cb = sizeof(si);	si.dwFlags = STARTF_USESTDHANDLES;		si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);	si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);	si.hStdError = GetStdHandle(STD_ERROR_HANDLE);		/* redirect stdin/stdout/stderr if requested */	for (i = 0; i < ndesc; i++) {		switch(descriptors[i].index) {			case 0:				si.hStdInput = descriptors[i].childend;				break;			case 1:				si.hStdOutput = descriptors[i].childend;				break;			case 2:				si.hStdError = descriptors[i].childend;				break;		}	}		memset(&pi, 0, sizeof(pi));		command_with_cmd = emalloc(command_len + sizeof(COMSPEC_9X) + 1 + sizeof(" /c "));	sprintf(command_with_cmd, "%s /c %s", GetVersion() < 0x80000000 ? COMSPEC_NT : COMSPEC_9X, command);	newprocok = CreateProcess(NULL, command_with_cmd, &security, &security, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);	efree(command_with_cmd);	if (FALSE == newprocok) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "CreateProcess failed");		goto exit_fail;	}	child = pi.hProcess;	CloseHandle(pi.hThread);#else	/* the unix way */	child = fork();	if (child == 0) {		/* this is the child process */		/* close those descriptors that we just opened for the parent stuff,		 * dup new descriptors into required descriptors and close the original		 * cruft */		for (i = 0; i < ndesc; i++) {			switch (descriptors[i].mode & ~DESC_PARENT_MODE_WRITE) {				case DESC_PIPE:					close(descriptors[i].parentend);					break;			}			if (dup2(descriptors[i].childend, descriptors[i].index) < 0)				perror("dup2");			if (descriptors[i].childend != descriptors[i].index)				close(descriptors[i].childend);		}		execl("/bin/sh", "sh", "-c", command, NULL);		_exit(127);	} else if (child < 0) {		/* failed to fork() */		/* clean up all the descriptors */		for (i = 0; i < ndesc; i++) {			close(descriptors[i].childend);			close(descriptors[i].parentend);		}		php_error_docref(NULL TSRMLS_CC, E_WARNING, "fork failed - %s", strerror(errno));		goto exit_fail;	}#endif	/* we forked/spawned and this is the parent */	efree(command);	if (pipes != NULL) {		zval_dtor(pipes);	}	array_init(pipes);	/* clean up all the child ends and then open streams on the parent	 * ends, where appropriate */	for (i = 0; i < ndesc; i++) {		FILE *fp;		char *mode_string=NULL;		php_stream *stream;		close_descriptor(descriptors[i].childend);		switch (descriptors[i].mode & ~DESC_PARENT_MODE_WRITE) {			case DESC_PIPE:				switch(descriptors[i].mode_flags) {#ifdef PHP_WIN32					case O_WRONLY|O_BINARY:						mode_string = "wb";						break;					case O_RDONLY|O_BINARY:						mode_string = "rb";						break;#endif					case O_WRONLY:						mode_string = "w";						break;					case O_RDONLY:						mode_string = "r";						break;				}#ifdef PHP_WIN32				fp = _fdopen(_open_osfhandle((long)descriptors[i].parentend,							descriptors[i].mode_flags), mode_string);#else				fp = fdopen(descriptors[i].parentend, mode_string);#endif				if (fp) {					stream = php_stream_fopen_from_file(fp, mode_string);					if (stream) {						zval *retfp;						MAKE_STD_ZVAL(retfp);						php_stream_to_zval(stream, retfp);						add_index_zval(pipes, descriptors[i].index, retfp);					}				}				break;		}	}	ZEND_REGISTER_RESOURCE(return_value, (void*)child, le_proc_open);	return;exit_fail:	efree(command);	RETURN_FALSE;	}/* }}} *//* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */

⌨️ 快捷键说明

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