symbian-qemu-0.9.1-12/python-2.6.1/PC/w9xpopen.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  * w9xpopen.c
       
     3  *
       
     4  * Serves as an intermediate stub Win32 console application to
       
     5  * avoid a hanging pipe when redirecting 16-bit console based
       
     6  * programs (including MS-DOS console based programs and batch
       
     7  * files) on Window 95 and Windows 98.
       
     8  *
       
     9  * This program is to be launched with redirected standard
       
    10  * handles. It will launch the command line specified 16-bit
       
    11  * console based application in the same console, forwarding
       
    12  * its own redirected standard handles to the 16-bit child.
       
    13 
       
    14  * AKA solution to the problem described in KB: Q150956.
       
    15  */    
       
    16 
       
    17 #define WIN32_LEAN_AND_MEAN
       
    18 #include <windows.h>
       
    19 #include <stdio.h>
       
    20 #include <stdlib.h>  /* for malloc and its friends */
       
    21 
       
    22 const char *usage =
       
    23 "This program is used by Python's os.popen function\n"
       
    24 "to work around a limitation in Windows 95/98.  It is\n"
       
    25 "not designed to be used as a stand-alone program.";
       
    26 
       
    27 int main(int argc, char *argv[])
       
    28 {
       
    29     BOOL bRet;
       
    30     STARTUPINFO si;
       
    31     PROCESS_INFORMATION pi;
       
    32     DWORD exit_code=0;
       
    33     size_t cmdlen = 0;
       
    34     int i;
       
    35     char *cmdline, *cmdlinefill;
       
    36 
       
    37     if (argc < 2) {
       
    38         if (GetFileType(GetStdHandle(STD_INPUT_HANDLE))==FILE_TYPE_CHAR)
       
    39             /* Attached to a console, and therefore not executed by Python
       
    40                Display a message box for the inquisitive user
       
    41             */
       
    42             MessageBox(NULL, usage, argv[0], MB_OK);
       
    43         else {
       
    44             /* Eeek - executed by Python, but args are screwed!
       
    45                Write an error message to stdout so there is at
       
    46                least some clue for the end user when it appears
       
    47                in their output.
       
    48                A message box would be hidden and blocks the app.
       
    49              */
       
    50             fprintf(stdout, "Internal popen error - no args specified\n%s\n", usage);
       
    51         }
       
    52         return 1;
       
    53     }
       
    54     /* Build up the command-line from the args.
       
    55        Args with a space are quoted, existing quotes are escaped.
       
    56        To keep things simple calculating the buffer size, we assume
       
    57        every character is a quote - ie, we allocate double what we need
       
    58        in the worst case.  As this is only double the command line passed
       
    59        to us, there is a good chance this is reasonably small, so the total 
       
    60        allocation will almost always be < 512 bytes.
       
    61     */
       
    62     for (i=1;i<argc;i++)
       
    63         cmdlen += strlen(argv[i])*2 + 3; /* one space, maybe 2 quotes */
       
    64     cmdline = cmdlinefill = (char *)malloc(cmdlen+1);
       
    65     if (cmdline == NULL)
       
    66         return -1;
       
    67     for (i=1;i<argc;i++) {
       
    68         const char *arglook;
       
    69         int bQuote = strchr(argv[i], ' ') != NULL;
       
    70         if (bQuote)
       
    71             *cmdlinefill++ = '"';
       
    72         /* escape quotes */
       
    73         for (arglook=argv[i];*arglook;arglook++) {
       
    74             if (*arglook=='"')
       
    75                 *cmdlinefill++ = '\\';
       
    76             *cmdlinefill++ = *arglook;
       
    77         }
       
    78         if (bQuote)
       
    79             *cmdlinefill++ = '"';
       
    80         *cmdlinefill++ = ' ';
       
    81     }
       
    82     *cmdlinefill = '\0';
       
    83 
       
    84     /* Make child process use this app's standard files. */
       
    85     ZeroMemory(&si, sizeof si);
       
    86     si.cb = sizeof si;
       
    87     si.dwFlags = STARTF_USESTDHANDLES;
       
    88     si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
       
    89     si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
       
    90     si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
       
    91 
       
    92     bRet = CreateProcess(
       
    93         NULL, cmdline,
       
    94         NULL, NULL,
       
    95         TRUE, 0,
       
    96         NULL, NULL,
       
    97         &si, &pi
       
    98         );
       
    99 
       
   100     free(cmdline);
       
   101 
       
   102     if (bRet) {
       
   103         if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_FAILED) {
       
   104 	    GetExitCodeProcess(pi.hProcess, &exit_code);
       
   105 	}
       
   106         CloseHandle(pi.hProcess);
       
   107         CloseHandle(pi.hThread);
       
   108         return exit_code;
       
   109     }
       
   110 
       
   111     return 1;
       
   112 }