libc.c
来自「uclinux 下的vlc播放器源代码」· C语言 代码 · 共 1,191 行 · 第 1/3 页
C
1,191 行
int i_quote = **s; **ppsz_parser = **s; (*ppsz_parser)++; (*s)++; find_end_quote( s, ppsz_parser, i_quote ); **ppsz_parser = **s; (*ppsz_parser)++; (*s)++; } i_bcount = 0; } else { /* A regular character */ **ppsz_parser = **s; (*ppsz_parser)++; (*s)++; i_bcount = 0; } }}char **vlc_parse_cmdline( const char *psz_cmdline, int *i_args ){ int argc = 0; char **argv = 0; char *s, *psz_parser, *psz_arg, *psz_orig; int i_bcount = 0; if( !psz_cmdline ) return 0; psz_orig = strdup( psz_cmdline ); psz_arg = psz_parser = s = psz_orig; while( *s ) { if( *s == '\t' || *s == ' ' ) { /* We have a complete argument */ *psz_parser = 0; TAB_APPEND( argc, argv, strdup(psz_arg) ); /* Skip trailing spaces/tabs */ do{ s++; } while( *s == '\t' || *s == ' ' ); /* New argument */ psz_arg = psz_parser = s; i_bcount = 0; } else if( *s == '\\' ) { *psz_parser++ = *s++; i_bcount++; } else if( *s == '"' || *s == '\'' ) { if( ( i_bcount & 1 ) == 0 ) { /* Preceeded by an even number of '\', this is half that * number of '\', plus a quote which we erase. */ int i_quote = *s; psz_parser -= i_bcount / 2; s++; find_end_quote( &s, &psz_parser, i_quote ); s++; } else { /* Preceeded by an odd number of '\', this is half that * number of '\' followed by a '"' */ psz_parser = psz_parser - i_bcount/2 - 1; *psz_parser++ = '"'; s++; } i_bcount = 0; } else { /* A regular character */ *psz_parser++ = *s++; i_bcount = 0; } } /* Take care of the last arg */ if( *psz_arg ) { *psz_parser = '\0'; TAB_APPEND( argc, argv, strdup(psz_arg) ); } if( i_args ) *i_args = argc; free( psz_orig ); return argv;}/************************************************************************* * vlc_execve: Execute an external program with a given environment, * wait until it finishes and return its standard output *************************************************************************/int __vlc_execve( vlc_object_t *p_object, int i_argc, char **ppsz_argv, char **ppsz_env, char *psz_cwd, char *p_in, int i_in, char **pp_data, int *pi_data ){#ifdef HAVE_FORK int pi_stdin[2]; int pi_stdout[2]; pid_t i_child_pid; pipe( pi_stdin ); pipe( pi_stdout ); if ( (i_child_pid = fork()) == -1 ) { msg_Err( p_object, "unable to fork (%s)", strerror(errno) ); return -1; } if ( i_child_pid == 0 ) { close(0); dup(pi_stdin[1]); close(pi_stdin[0]); close(1); dup(pi_stdout[1]); close(pi_stdout[0]); close(2); if ( psz_cwd != NULL ) chdir( psz_cwd ); execve( ppsz_argv[0], ppsz_argv, ppsz_env ); exit(1); } close(pi_stdin[1]); close(pi_stdout[1]); if ( !i_in ) close( pi_stdin[0] ); *pi_data = 0; if( *pp_data ) free( *pp_data ); *pp_data = NULL; *pp_data = malloc( 1025 ); /* +1 for \0 */ if( !*pp_data ) return -1; while ( !p_object->b_die ) { int i_ret, i_status; fd_set readfds, writefds; struct timeval tv; FD_ZERO( &readfds ); FD_ZERO( &writefds ); FD_SET( pi_stdout[0], &readfds ); if ( i_in ) FD_SET( pi_stdin[0], &writefds ); tv.tv_sec = 0; tv.tv_usec = 10000; i_ret = select( pi_stdin[0] > pi_stdout[0] ? pi_stdin[0] + 1 : pi_stdout[0] + 1, &readfds, &writefds, NULL, &tv ); if ( i_ret > 0 ) { if ( FD_ISSET( pi_stdout[0], &readfds ) ) { ssize_t i_read = read( pi_stdout[0], &(*pp_data)[*pi_data], 1024 ); if ( i_read > 0 ) { *pi_data += i_read; *pp_data = realloc( *pp_data, *pi_data + 1025 ); } } if ( FD_ISSET( pi_stdin[0], &writefds ) ) { ssize_t i_write = write( pi_stdin[0], p_in, __MIN(i_in, 1024) ); if ( i_write > 0 ) { p_in += i_write; i_in -= i_write; } if ( !i_in ) close( pi_stdin[0] ); } } if ( waitpid( i_child_pid, &i_status, WNOHANG ) == i_child_pid ) { if ( WIFEXITED( i_status ) ) { if ( WEXITSTATUS( i_status ) ) { msg_Warn( p_object, "child %s returned with error code %d", ppsz_argv[0], WEXITSTATUS( i_status ) ); } } else { if ( WIFSIGNALED( i_status ) ) { msg_Warn( p_object, "child %s quit on signal %d", ppsz_argv[0], WTERMSIG( i_status ) ); } } if ( i_in ) close( pi_stdin[0] ); close( pi_stdout[0] ); break; } if ( i_ret < 0 && errno != EINTR ) { msg_Warn( p_object, "select failed (%s)", strerror(errno) ); } }#elif defined( WIN32 ) && !defined( UNDER_CE ) SECURITY_ATTRIBUTES saAttr; PROCESS_INFORMATION piProcInfo; STARTUPINFO siStartInfo; BOOL bFuncRetn = FALSE; HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr; DWORD i_status; char *psz_cmd = NULL, *p_env = NULL, *p = NULL; char **ppsz_parser; int i_size; /* Set the bInheritHandle flag so pipe handles are inherited. */ saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; /* Create a pipe for the child process's STDOUT. */ if ( !CreatePipe( &hChildStdoutRd, &hChildStdoutWr, &saAttr, 0 ) ) { msg_Err( p_object, "stdout pipe creation failed" ); return -1; } /* Ensure the read handle to the pipe for STDOUT is not inherited. */ SetHandleInformation( hChildStdoutRd, HANDLE_FLAG_INHERIT, 0 ); /* Create a pipe for the child process's STDIN. */ if ( !CreatePipe( &hChildStdinRd, &hChildStdinWr, &saAttr, 0 ) ) { msg_Err( p_object, "stdin pipe creation failed" ); return -1; } /* Ensure the write handle to the pipe for STDIN is not inherited. */ SetHandleInformation( hChildStdinWr, HANDLE_FLAG_INHERIT, 0 ); /* Set up members of the PROCESS_INFORMATION structure. */ ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) ); /* Set up members of the STARTUPINFO structure. */ ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.hStdError = hChildStdoutWr; siStartInfo.hStdOutput = hChildStdoutWr; siStartInfo.hStdInput = hChildStdinRd; siStartInfo.wShowWindow = SW_HIDE; siStartInfo.dwFlags |= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; /* Set up the command line. */ psz_cmd = malloc(32768); if( !psz_cmd ) return -1; psz_cmd[0] = '\0'; i_size = 32768; ppsz_parser = &ppsz_argv[0]; while ( ppsz_parser[0] != NULL && i_size > 0 ) { /* Protect the last argument with quotes ; the other arguments * are supposed to be already protected because they have been * passed as a command-line option. */ if ( ppsz_parser[1] == NULL ) { strncat( psz_cmd, "\"", i_size ); i_size--; } strncat( psz_cmd, *ppsz_parser, i_size ); i_size -= strlen( *ppsz_parser ); if ( ppsz_parser[1] == NULL ) { strncat( psz_cmd, "\"", i_size ); i_size--; } strncat( psz_cmd, " ", i_size ); i_size--; ppsz_parser++; } /* Set up the environment. */ p = p_env = malloc(32768); if( !p ) { free( psz_cmd ); return -1; } i_size = 32768; ppsz_parser = &ppsz_env[0]; while ( *ppsz_parser != NULL && i_size > 0 ) { memcpy( p, *ppsz_parser, __MIN((int)(strlen(*ppsz_parser) + 1), i_size) ); p += strlen(*ppsz_parser) + 1; i_size -= strlen(*ppsz_parser) + 1; ppsz_parser++; } *p = '\0'; /* Create the child process. */ bFuncRetn = CreateProcess( NULL, psz_cmd, // command line NULL, // process security attributes NULL, // primary thread security attributes TRUE, // handles are inherited 0, // creation flags p_env, psz_cwd, &siStartInfo, // STARTUPINFO pointer &piProcInfo ); // receives PROCESS_INFORMATION free( psz_cmd ); free( p_env ); if ( bFuncRetn == 0 ) { msg_Err( p_object, "child creation failed" ); return -1; } /* Read from a file and write its contents to a pipe. */ while ( i_in > 0 && !p_object->b_die ) { DWORD i_written; if ( !WriteFile( hChildStdinWr, p_in, i_in, &i_written, NULL ) ) break; i_in -= i_written; p_in += i_written; } /* Close the pipe handle so the child process stops reading. */ CloseHandle(hChildStdinWr); /* Close the write end of the pipe before reading from the * read end of the pipe. */ CloseHandle(hChildStdoutWr); /* Read output from the child process. */ *pi_data = 0; if( *pp_data ) free( pp_data ); *pp_data = NULL; *pp_data = malloc( 1025 ); /* +1 for \0 */ while ( !p_object->b_die ) { DWORD i_read; if ( !ReadFile( hChildStdoutRd, &(*pp_data)[*pi_data], 1024, &i_read, NULL ) || i_read == 0 ) break; *pi_data += i_read; *pp_data = realloc( *pp_data, *pi_data + 1025 ); } while ( !p_object->b_die && !GetExitCodeProcess( piProcInfo.hProcess, &i_status ) && i_status != STILL_ACTIVE ) msleep( 10000 ); CloseHandle(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); if ( i_status ) msg_Warn( p_object, "child %s returned with error code %ld", ppsz_argv[0], i_status );#else msg_Err( p_object, "vlc_execve called but no implementation is available" ); return -1;#endif (*pp_data)[*pi_data] = '\0'; return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?