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 + -
显示快捷键?