]> git.sesse.net Git - vlc/commitdiff
* src/extras/libc.c: Implemented vlc_execve() for the Win32 platform.
authorChristophe Massiot <massiot@videolan.org>
Mon, 29 Aug 2005 16:30:38 +0000 (16:30 +0000)
committerChristophe Massiot <massiot@videolan.org>
Mon, 29 Aug 2005 16:30:38 +0000 (16:30 +0000)
 * modules/control/http/http.c: Enabled --http-handlers under Win32.
   Beware to espace backslashes as in --http-handlers="php=C:\\php\\php.exe".

modules/control/http/http.c
src/extras/libc.c

index af6f0aa17ffd95b29bffa4e2a09986f8e7b69474..257b6d3ad35483ece5270eb2fafe2f88489ec879 100644 (file)
@@ -62,7 +62,7 @@ vlc_module_begin();
         add_string ( "http-host", NULL, NULL, HOST_TEXT, HOST_LONGTEXT, VLC_TRUE );
         add_string ( "http-src",  NULL, NULL, SRC_TEXT,  SRC_LONGTEXT,  VLC_TRUE );
         add_string ( "http-charset", "UTF-8", NULL, CHARSET_TEXT, CHARSET_LONGTEXT, VLC_TRUE );
-#if defined( HAVE_FORK )
+#if defined( HAVE_FORK ) || defined( WIN32 )
         add_string ( "http-handlers", NULL, NULL, HANDLERS_TEXT, HANDLERS_LONGTEXT, VLC_TRUE );
 #endif
         set_section( N_("HTTP SSL" ), 0 );
@@ -189,7 +189,7 @@ static int Open( vlc_object_t *p_this )
     /* determine file handler associations */
     p_sys->i_handlers = 0;
     p_sys->pp_handlers = NULL;
-#if defined( HAVE_FORK )
+#if defined( HAVE_FORK ) || defined( WIN32 )
     psz_src = config_GetPsz( p_intf, "http-handlers" );
     if( psz_src != NULL && *psz_src )
     {
@@ -529,9 +529,9 @@ static void ParseExecute( httpd_file_sys_t *p_args, char *p_buffer,
     E_(mvar_AppendNewVar)( p_args->vars, "copyright", COPYRIGHT_MESSAGE );
     E_(mvar_AppendNewVar)( p_args->vars, "vlc_compile_by", VLC_CompileBy() );
     E_(mvar_AppendNewVar)( p_args->vars, "vlc_compile_host",
-                       VLC_CompileHost() );
+                           VLC_CompileHost() );
     E_(mvar_AppendNewVar)( p_args->vars, "vlc_compile_domain",
-                       VLC_CompileDomain() );
+                           VLC_CompileDomain() );
     E_(mvar_AppendNewVar)( p_args->vars, "vlc_compiler", VLC_Compiler() );
     E_(mvar_AppendNewVar)( p_args->vars, "vlc_changeset", VLC_Changeset() );
     E_(mvar_AppendNewVar)( p_args->vars, "stream_position", position );
@@ -669,10 +669,6 @@ int  E_(HandlerCallback)( httpd_handler_sys_t *p_args,
     sprintf( psz_tmp, "SCRIPT_NAME=%s", p_url );
     TAB_APPEND( i_env, ppsz_env, psz_tmp );
 
-    psz_tmp = malloc( sizeof("SCRIPT_FILENAME=") + strlen(p_args->file.file) );
-    sprintf( psz_tmp, "SCRIPT_FILENAME=%s", p_args->file.file );
-    TAB_APPEND( i_env, ppsz_env, psz_tmp );
-
 #define p_sys p_args->file.p_intf->p_sys
     psz_tmp = malloc( sizeof("SERVER_NAME=") + strlen(p_sys->psz_address) );
     sprintf( psz_tmp, "SERVER_NAME=%s", p_sys->psz_address );
@@ -735,10 +731,20 @@ int  E_(HandlerCallback)( httpd_handler_sys_t *p_args,
         }
     }
 
+    p = strrchr( p_args->file.file, sep );
+    if( p != NULL )
+    {
+        p++;
+        psz_tmp = malloc( sizeof("SCRIPT_FILENAME=") + strlen(p) );
+        sprintf( psz_tmp, "SCRIPT_FILENAME=%s", p );
+        TAB_APPEND( i_env, ppsz_env, psz_tmp );
+
+        TAB_APPEND( p_args->p_association->i_argc,
+                    p_args->p_association->ppsz_argv, p );
+    }
+
     TAB_APPEND( i_env, ppsz_env, NULL );
 
-    TAB_APPEND( p_args->p_association->i_argc, p_args->p_association->ppsz_argv,
-                p_args->file.file );
     TAB_APPEND( p_args->p_association->i_argc, p_args->p_association->ppsz_argv,
                 NULL );
 
index 14b2932c36b533e5739df50dad603e9a55937da8..903ceefd02150ea24be09996aa8947e4326690da 100644 (file)
 #   include <sys/wait.h>
 #endif
 
+#if defined(WIN32) || defined(UNDER_CE)
+#   define WIN32_LEAN_AND_MEAN
+#   include <windows.h>
+#endif
+
 /*****************************************************************************
  * getenv: just in case, but it should never be called
  *****************************************************************************/
@@ -339,10 +344,6 @@ int64_t vlc_atoll( const char *nptr )
  * when called with an empty argument or just '\'
  *****************************************************************************/
 #if defined(WIN32) || defined(UNDER_CE)
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h> /* for GetLogicalDrives */
-
 typedef struct vlc_DIR
 {
     DIR *p_real_dir;
@@ -941,6 +942,160 @@ int __vlc_execve( vlc_object_t *p_object, int i_argc, char **ppsz_argv,
         }
     }
 
+#elif defined( WIN32 )
+    SECURITY_ATTRIBUTES saAttr; 
+    PROCESS_INFORMATION piProcInfo; 
+    STARTUPINFO siStartInfo;
+    BOOL bFuncRetn = FALSE; 
+    HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr;
+    DWORD i_status;
+    char *psz_cmd, *p_env, *p;
+    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.dwFlags |= STARTF_USESTDHANDLES;
+
+    /* Set up the command line. */
+    psz_cmd = malloc(32768);
+    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);
+    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;
+    *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;