~ubuntu-branches/ubuntu/trusty/enigmail/trusty-updates

« back to all changes in this revision

Viewing changes to extensions/enigmail/ipc/src/IPCProcess.cpp

  • Committer: Package Import Robot
  • Author(s): Chris Coulson
  • Date: 2011-06-07 14:35:53 UTC
  • mfrom: (0.12.1 upstream)
  • Revision ID: package-import@ubuntu.com-20110607143553-fbgqhhvh8g8h6j1y
Tags: 2:1.2~a2~cvs20110606t2200-0ubuntu1
* Update to latest trunk snapshot for Thunderbird beta compat

* Remove build/pgo/profileserver.py from debian/clean. The new build
  system has a target depending on this
  - update debian/clean
* Drop debian/patches/autoconf.diff, just generate this at build time
* Refresh debian/patches/build_system_dont_link_libxul.diff
* libipc seems to be renamed to libipc-pipe. Fix genxpi and chrome.manifest
  to fix this 
  - add debian/patches/ipc-pipe_rename.diff
  - update debian/patches/series
* The makefiles in extensions/enigmail/ipc have an incorrect DEPTH
  attribute. Fix this so that they can find the rest of the build system
  - add debian/patches/makefile_depth.diff
  - update debian/patches/series
* Drop debian/patches/makefile-in-empty-xpcom-fix.diff - fixed in the
  current version
* Don't register a class ID multiple times, as this breaks enigmail entirely
  - add debian/patches/dont_register_cids_multiple_times.diff
  - update debian/patches/series
* Look for the Thunderbird 5 SDK
  - update debian/rules
  - update debian/control
* Run autoconf2.13 at build time
  - update debian/rules
  - update debian/control
* Add useless mesa-common-dev build-dep, just to satisfy the build system.
  We should just patch this out entirely really, but that's for another upload
  - update debian/control

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
 
1
/* ***** BEGIN LICENSE BLOCK *****
 
2
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 
3
 *
2
4
 * The contents of this file are subject to the Mozilla Public
3
 
 * License Version 1.1 (the "License"); you may not use this file
4
 
 * except in compliance with the License. You may obtain a copy of
5
 
 * the License at http://www.mozilla.org/MPL/
 
5
 * License Version 1.1 (the "MPL"); you may not use this file
 
6
 * except in compliance with the MPL. You may obtain a copy of
 
7
 * the MPL at http://www.mozilla.org/MPL/
6
8
 *
7
 
 * Software distributed under the License is distributed on an "AS
 
9
 * Software distributed under the MPL is distributed on an "AS
8
10
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9
 
 * implied. See the License for the specific language governing
10
 
 * rights and limitations under the License.
 
11
 * implied. See the MPL for the specific language governing
 
12
 * rights and limitations under the MPL.
11
13
 *
12
14
 * The Original Code is the Netscape Portable Runtime (NSPR).
13
15
 *
20
22
 *   Ramalingam Saravanan <svn@xmlterm.org>
21
23
 *   Patrick Brunschwig <patrick@mozilla-enigmail.org>
22
24
 *
23
 
 * Alternatively, the contents of this file may be used under the
24
 
 * terms of the GNU General Public License Version 2 or later (the
25
 
 * "GPL"), in which case the provisions of the GPL are applicable
26
 
 * instead of those above.  If you wish to allow use of your
27
 
 * version of this file only under the terms of the GPL and not to
28
 
 * allow others to use your version of this file under the MPL,
29
 
 * indicate your decision by deleting the provisions above and
30
 
 * replace them with the notice and other provisions required by
31
 
 * the GPL.  If you do not delete the provisions above, a recipient
32
 
 * may use your version of this file under either the MPL or the
33
 
 * GPL.
34
 
 */
 
25
 * Alternatively, the contents of this file may be used under the terms of
 
26
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
27
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
28
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
29
 * of those above. If you wish to allow use of your version of this file only
 
30
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
31
 * use your version of this file under the terms of the MPL, indicate your
 
32
 * decision by deleting the provisions above and replace them with the notice
 
33
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
34
 * the provisions above, a recipient may use your version of this file under
 
35
 * the terms of any one of the MPL, the GPL or the LGPL.
 
36
 * ***** END LICENSE BLOCK ***** */
35
37
 
36
 
// Logging of debug output
37
 
// The following define statement should occur before any include statements
38
 
#define FORCE_PR_LOG       /* Allow logging even in release build */
39
38
 
40
39
#include "ipc.h"
41
40
#include "IPCProcess.h"
42
 
 
43
 
#ifdef PR_LOGGING
44
 
extern PRLogModuleInfo* gIPCServiceLog;
45
 
#endif
46
 
 
47
 
#define ERROR_LOG(args)    PR_LOG(gIPCServiceLog,PR_LOG_ERROR,args)
48
 
#define WARNING_LOG(args)  PR_LOG(gIPCServiceLog,PR_LOG_WARNING,args)
49
 
#define DEBUG_LOG(args)    PR_LOG(gIPCServiceLog,PR_LOG_DEBUG,args)
50
 
 
51
 
///////////////////////////////////////////////////////////////////////////////
 
41
#include "nsMemory.h"
52
42
 
53
43
#ifdef XP_WIN
54
44
#include <windows.h>
 
45
#include <shellapi.h>
55
46
#include <stdio.h>
 
47
#include <stdlib.h>
56
48
#include <io.h>
57
49
#include <fcntl.h>
58
50
 
105
97
 
106
98
}
107
99
 
108
 
 
109
100
PRStatus IPC_CreateInheritablePipeNSPR(PRFileDesc* *readPipe,
110
101
                                       PRFileDesc* *writePipe,
111
102
                                       PRBool readInherit,
144
135
static PRBool gIPCWinConsoleAllocated = PR_FALSE;
145
136
#endif
146
137
 
147
 
void IPC_Shutdown()
 
138
// Note: it's not necessary to free/close the console, there is (at most) 1
 
139
// console in a parent process
 
140
 
 
141
PRStatus IPC_GetProcessIdNSPR(IPCProcess* process, PRInt32 *pid)
148
142
{
149
 
 
150
 
#ifdef XP_WIN
151
 
  if (gIPCWinConsoleAllocated) {
152
 
    ::FreeConsole();
153
 
    gIPCWinConsoleAllocated = PR_FALSE;
154
 
  }
155
 
#endif
156
 
 
 
143
  *pid = 0;
 
144
 
 
145
  if (! process)
 
146
    return PR_FAILURE;
 
147
 
 
148
  struct MYProcess {
 
149
      PRUint32 pid;
 
150
  };
 
151
  MYProcess* ptrProc = (MYProcess *) process;
 
152
  *pid = ptrProc->pid;
 
153
 
 
154
  return PR_SUCCESS;
157
155
}
158
156
 
 
157
 
159
158
#ifdef XP_WIN
160
159
// Workaround for Win32
161
160
// Try to create a console, if one hasn't already been created
167
166
void IPC_HideConsoleWin32()
168
167
{
169
168
 
 
169
  // AllocConsole and SetConsoleTitle et al. are Windows API functions.
 
170
  // See Windows SDK/.../include/WinCon.h, WinBase.h, WinUser.h
 
171
 
170
172
  if (!gIPCWinConsoleAllocated && ::AllocConsole()) {
171
173
    // Set console title
172
174
    const char consoleTitle[] = "IPC error console";
211
213
 
212
214
#ifdef XP_WIN_IPC
213
215
 
214
 
/* Windows specific code adapted from mozilla/xpcom/threads/nsProcessCommon.cpp
215
 
   Out param `wideCmdLine` must be PR_Freed by the caller.
 
216
/*
 
217
 *
 
218
 * Windows specific code adapted from mozilla/xpcom/threads/nsProcessCommon.cpp
 
219
 * Out param `wideCmdLine` must be PR_Freed by the caller.
216
220
 */
217
221
 
218
222
static int assembleCmdLine(char *const *argv, PRUnichar **wideCmdLine)
224
228
    int i;
225
229
    int argNeedQuotes;
226
230
 
227
 
    /*
228
 
     * Find out how large the command line buffer should be.
229
 
     */
 
231
    UINT codePage = CP_UTF8; // the code page to use for the parameter strings
 
232
 
 
233
    // Find out how large the command line buffer should be.
 
234
 
230
235
    cmdLineSize = 0;
231
236
    for (arg = argv; *arg; arg++) {
232
 
        /*
233
 
         * \ and " need to be escaped by a \.  In the worst case,
234
 
         * every character is a \ or ", so the string of length
235
 
         * may double.  If we quote an argument, that needs two ".
236
 
         * Finally, we need a space between arguments, and
237
 
         * a null byte at the end of command line.
238
 
         */
239
 
        cmdLineSize += 2 * strlen(*arg)  /* \ and " need to be escaped */
240
 
                + 2                      /* we quote every argument */
241
 
                + 1;                     /* space in between, or final null */
 
237
 
 
238
        // \ and " need to be escaped by a \.  In the worst case,
 
239
        // every character is a \ or ", so the string of length
 
240
        // may double.  If we quote an argument, that needs two ".
 
241
        // Finally, we need a space between arguments, and
 
242
        // a null byte at the end of command line.
 
243
 
 
244
        cmdLineSize += 2 * strlen(*arg) + // \ and " need to be escaped
 
245
                2+                        // we quote every argument
 
246
                1;                        // space in between, or final null
242
247
    }
243
248
    p = cmdLine = (char *) PR_MALLOC(cmdLineSize*sizeof(char));
244
249
    if (p == NULL) {
246
251
    }
247
252
 
248
253
    for (arg = argv; *arg; arg++) {
249
 
        /* Add a space to separates the arguments */
 
254
        // Add a space to separates the arguments
250
255
        if (arg != argv) {
251
 
            *p++ = ' '; 
 
256
            *p++ = ' ';
252
257
        }
253
258
        q = *arg;
254
259
        numBackslashes = 0;
255
260
        argNeedQuotes = 0;
256
261
 
257
 
        /* If the argument contains white space, it needs to be quoted. */
 
262
        // If the argument contains white space, it needs to be quoted.
258
263
        if (strpbrk(*arg, " \f\n\r\t\v")) {
259
264
            argNeedQuotes = 1;
260
265
        }
268
273
                q++;
269
274
            } else if (*q == '"') {
270
275
                if (numBackslashes) {
271
 
                    /*
272
 
                     * Double the backslashes since they are followed
273
 
                     * by a quote
274
 
                     */
 
276
 
 
277
                    // Double the backslashes since they are followed
 
278
                    // by a quote
275
279
                    for (i = 0; i < 2 * numBackslashes; i++) {
276
280
                        *p++ = '\\';
277
281
                    }
278
282
                    numBackslashes = 0;
279
283
                }
280
 
                /* To escape the quote */
 
284
                // To escape the quote
281
285
                *p++ = '\\';
282
286
                *p++ = *q++;
283
287
            } else {
284
288
                if (numBackslashes) {
285
 
                    /*
286
 
                     * Backslashes are not followed by a quote, so
287
 
                     * don't need to double the backslashes.
288
 
                     */
 
289
 
 
290
                    // Backslashes are not followed by a quote, so
 
291
                    // don't need to double the backslashes.
 
292
 
289
293
                    for (i = 0; i < numBackslashes; i++) {
290
294
                        *p++ = '\\';
291
295
                    }
295
299
            }
296
300
        }
297
301
 
298
 
        /* Now we are at the end of this argument */
 
302
        // Now we are at the end of this argument
299
303
        if (numBackslashes) {
300
 
            /*
301
 
             * Double the backslashes if we have a quote string
302
 
             * delimiter at the end.
303
 
             */
 
304
 
 
305
            // Double the backslashes if we have a quote string
 
306
            // delimiter at the end.
 
307
 
304
308
            if (argNeedQuotes) {
305
309
                numBackslashes *= 2;
306
310
            }
311
315
        if (argNeedQuotes) {
312
316
            *p++ = '"';
313
317
        }
314
 
    } 
 
318
    }
315
319
 
316
320
    *p = '\0';
317
 
    PRInt32 numChars = MultiByteToWideChar(CP_ACP, 0, cmdLine, -1, NULL, 0); 
 
321
    PRInt32 numChars = MultiByteToWideChar(codePage, 0, cmdLine, -1, NULL, 0);
318
322
    *wideCmdLine = (PRUnichar *) PR_MALLOC(numChars*sizeof(PRUnichar));
319
 
    MultiByteToWideChar(CP_ACP, 0, cmdLine, -1, *wideCmdLine, numChars); 
 
323
    MultiByteToWideChar(codePage, 0, cmdLine, -1, *wideCmdLine, numChars);
320
324
    PR_Free(cmdLine);
321
325
    return 0;
322
326
}
330
334
 * in *envBlock.  Note that if envp is NULL, a NULL pointer is returned
331
335
 * in *envBlock.  Returns -1 on failure.
332
336
 */
333
 
static int assembleEnvBlock(char *const *envp, char **envBlock)
 
337
static int assembleEnvBlock(char *const *envp, PRUnichar **envBlock)
334
338
{
335
 
    char *p;
336
 
    char *q;
337
 
    char * const *env;
338
 
    char *curEnv;
339
 
    char *cwdStart, *cwdEnd;
340
 
    int envBlockSize;
341
 
 
342
 
    if (envp == NULL) {
343
 
        *envBlock = NULL;
344
 
        return 0;
345
 
    }
346
 
 
347
 
    curEnv = GetEnvironmentStrings();
348
 
 
349
 
    cwdStart = curEnv;
350
 
    while (*cwdStart) {
351
 
        if (cwdStart[0] == '=' && cwdStart[1] != '\0'
352
 
                && cwdStart[2] == ':' && cwdStart[3] == '=') {
353
 
            break;
354
 
        }
355
 
        cwdStart += strlen(cwdStart) + 1;
356
 
    }
357
 
    cwdEnd = cwdStart;
358
 
    if (*cwdEnd) {
359
 
        cwdEnd += strlen(cwdEnd) + 1;
360
 
        while (*cwdEnd) {
361
 
            if (cwdEnd[0] != '=' || cwdEnd[1] == '\0'
362
 
                    || cwdEnd[2] != ':' || cwdEnd[3] != '=') {
363
 
                break;
364
 
            }
365
 
            cwdEnd += strlen(cwdEnd) + 1;
366
 
        }
367
 
    }
368
 
    envBlockSize = cwdEnd - cwdStart;
369
 
 
370
 
    for (env = envp; *env; env++) {
371
 
        envBlockSize += strlen(*env) + 1;
 
339
  PRUnichar *p, *q;
 
340
  char * const *env;
 
341
  PRInt32 envBlockSize = 0;
 
342
 
 
343
  if (envp == NULL) {
 
344
    *envBlock = NULL;
 
345
    return 0;
 
346
  }
 
347
 
 
348
  PRInt32 len, maxLen = 0;
 
349
  for (env = envp; *env; env++) {
 
350
    len = MultiByteToWideChar(CP_UTF8, 0, *env, -1, NULL, 0);
 
351
    envBlockSize += len;
 
352
    maxLen = (len > maxLen ? len : maxLen);
372
353
    }
373
354
    envBlockSize++;
374
355
 
375
 
    p = *envBlock = (char*) PR_MALLOC(envBlockSize);
376
 
    if (p == NULL) {
377
 
        FreeEnvironmentStrings(curEnv);
378
 
        return -1;
379
 
    }
380
 
 
381
 
    q = cwdStart;
382
 
    while (q < cwdEnd) {
 
356
    PRUnichar* tempStr = (PRUnichar *) PR_MALLOC(maxLen * sizeof(PRUnichar));
 
357
    p = *envBlock = (PRUnichar *) PR_MALLOC(envBlockSize * sizeof(PRUnichar));
 
358
 
 
359
    for (env = envp; *env; env++) {
 
360
 
 
361
      len = MultiByteToWideChar(CP_UTF8, 0, *env, -1, NULL, 0);
 
362
      MultiByteToWideChar(CP_UTF8, 0, *env, -1, tempStr, len);
 
363
      q = tempStr;
 
364
 
 
365
      while (*q) {
 
366
        // copy data (one by one)
383
367
        *p++ = *q++;
384
 
    }
385
 
    FreeEnvironmentStrings(curEnv);
386
 
 
387
 
    for (env = envp; *env; env++) {
388
 
        q = *env;
389
 
        while (*q) {
390
 
            *p++ = *q++;
391
 
        }
392
 
        *p++ = '\0';
393
 
    }
 
368
      }
 
369
 
 
370
      *p++ = '\0';
 
371
    }
 
372
 
 
373
    *p++ = '\0';
 
374
    PR_Free(tempStr);
394
375
    *p = '\0';
 
376
 
395
377
    return 0;
396
378
}
397
379
 
406
388
{
407
389
  BOOL bRetVal;
408
390
 
409
 
  DEBUG_LOG(("IPCProcess: createProcess %p, %p, %p\n", std_in,
410
 
                                                       std_out,
411
 
                                                       std_err));
412
 
 
413
391
  // Determine OS Version
414
392
  OSVERSIONINFO osvi;
415
 
  BOOL bIsWindows2KOrLater = FALSE;
 
393
  BOOL bIsWin2KOrLater = FALSE;
416
394
 
417
395
  ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
418
396
  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
419
397
 
420
398
  if (GetVersionEx(&osvi)) {
421
 
    bIsWindows2KOrLater = (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
 
399
    bIsWin2KOrLater = (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
422
400
                          (osvi.dwMajorVersion >= 5);
423
401
  }
424
402
 
427
405
  for (arg = argv; *arg; arg++) {
428
406
    ++count;
429
407
  }
430
 
  
 
408
 
431
409
  // make sure that when we allocate we have 1 greater than the
432
410
  // count since we need to null terminate the list for the argv to
433
411
  // pass into PR_CreateProcess
445
423
 
446
424
  // we need to set argv[0] to the program name.
447
425
  my_argv[0] = const_cast<char*>(path);
448
 
  PRInt32 numChars = MultiByteToWideChar(CP_ACP, 0, my_argv[0], -1, NULL, 0); 
 
426
  PRInt32 numChars = MultiByteToWideChar(CP_UTF8, 0, my_argv[0], -1, NULL, 0);
449
427
  PRUnichar* wideFile = (PRUnichar *) PR_MALLOC(numChars * sizeof(PRUnichar));
450
 
  MultiByteToWideChar(CP_ACP, 0, my_argv[0], -1, wideFile, numChars); 
451
 
  
 
428
  MultiByteToWideChar(CP_UTF8, 0, my_argv[0], -1, wideFile, numChars);
 
429
 
452
430
  // null terminate the array
453
431
  my_argv[count+1] = NULL;
454
432
 
455
433
  PRUnichar *cmdLine = NULL;
456
 
  if (assembleCmdLine(argv, &cmdLine) == -1)
 
434
  if (assembleCmdLine(argv, &cmdLine) != 0)
457
435
    return IPC_NULL_HANDLE;
458
436
 
459
 
  char *envBlock = NULL;
460
 
  if (assembleEnvBlock(envp, &envBlock) == -1)
 
437
  PRUnichar *envBlock = NULL;
 
438
  if (assembleEnvBlock(envp, &envBlock) != 0) {
 
439
    PR_Free(cmdLine);
461
440
    return IPC_NULL_HANDLE;
 
441
  }
462
442
 
463
443
  PRUnichar* wideCwd = NULL;
464
 
  
 
444
 
465
445
  if (cwd != NULL) {
466
 
    numChars = MultiByteToWideChar(CP_ACP, 0, cwd, -1, NULL, 0); 
 
446
    numChars = MultiByteToWideChar(CP_UTF8, 0, cwd, -1, NULL, 0);
467
447
    PRUnichar* wideCwd = (PRUnichar *) PR_MALLOC(numChars * sizeof(PRUnichar));
468
 
    MultiByteToWideChar(CP_ACP, 0, cwd, -1, wideCwd, numChars);
469
 
    DEBUG_LOG(("IPCProcess: createProcess converted cwd to %s\n", NS_ConvertUTF16toUTF8(wideCwd).get()));
470
 
        }
471
 
  
 
448
    MultiByteToWideChar(CP_UTF8, 0, cwd, -1, wideCwd, numChars);
 
449
  }
 
450
 
472
451
  // Fill in the process's startup information
473
 
  STARTUPINFOW startupInfo;
474
 
  memset( &startupInfo, 0, sizeof(STARTUPINFOW) );
475
 
  startupInfo.cb         = sizeof(STARTUPINFOW);
476
 
  startupInfo.dwFlags    = STARTF_USESTDHANDLES;
477
 
  startupInfo.hStdInput  = std_in  ? (HANDLE) std_in  : GetStdHandle(STD_INPUT_HANDLE);
478
 
  startupInfo.hStdOutput = std_out ? (HANDLE) std_out : GetStdHandle(STD_OUTPUT_HANDLE);
479
 
  startupInfo.hStdError  = std_err ? (HANDLE) std_err : GetStdHandle(STD_ERROR_HANDLE);
480
 
  DWORD dwCreationFlags = CREATE_DEFAULT_ERROR_MODE /*| CREATE_UNICODE_ENVIRONMENT */;
 
452
  STARTUPINFOW sInfo;
 
453
  memset( &sInfo, 0, sizeof(STARTUPINFOW) );
 
454
  sInfo.cb         = sizeof(STARTUPINFOW);
 
455
  sInfo.dwFlags    = STARTF_USESTDHANDLES;
 
456
  sInfo.hStdInput  = std_in  ? (HANDLE)std_in  : GetStdHandle(STD_INPUT_HANDLE);
 
457
  sInfo.hStdOutput = std_out ? (HANDLE)std_out : GetStdHandle(STD_OUTPUT_HANDLE);
 
458
  sInfo.hStdError  = std_err ? (HANDLE)std_err : GetStdHandle(STD_ERROR_HANDLE);
 
459
  DWORD dwCreationFlags = CREATE_DEFAULT_ERROR_MODE | CREATE_UNICODE_ENVIRONMENT;
481
460
 
482
461
  char buf[128];
483
462
  BOOL bIsConsoleAttached = (GetConsoleTitle(buf, 127) > 0);
484
463
 
485
 
  if (bIsWindows2KOrLater && !bIsConsoleAttached) {
 
464
  if (bIsWin2KOrLater && !bIsConsoleAttached) {
486
465
    // Create and hide child process console
487
466
    // Does not work from Win2K console (and not at all on Win95!)
488
 
    startupInfo.dwFlags    |= STARTF_USESHOWWINDOW;
489
 
    startupInfo.wShowWindow = SW_HIDE;
 
467
    sInfo.dwFlags    |= STARTF_USESHOWWINDOW;
 
468
    sInfo.wShowWindow = SW_HIDE;
490
469
    dwCreationFlags |= CREATE_SHARED_WOW_VDM;
491
470
    dwCreationFlags |= CREATE_NEW_CONSOLE;
492
471
    if (detach) {
501
480
  }
502
481
 
503
482
  PROCESS_INFORMATION processInfo;
504
 
  
505
 
  bRetVal = CreateProcessW(wideFile,            // executable
506
 
                           cmdLine,             // command line
507
 
                           NULL,                // process security
508
 
                           NULL,                // thread security
509
 
                           TRUE,                // inherit handles
510
 
                           dwCreationFlags,     // creation flags
511
 
                           envBlock,            // environment
512
 
                           wideCwd,                     // cwd
513
 
                           &startupInfo,        // startup info
514
 
                           &processInfo );      // process info (returned)
515
 
 
516
 
  DEBUG_LOG(("IPCProcess: created process %s (%d) %p: %s\n", NS_ConvertUTF16toUTF8(cmdLine).get(),
517
 
               (int) bRetVal, processInfo.hProcess, envBlock));
 
483
 
 
484
  bRetVal = CreateProcessW(wideFile,    // executable
 
485
                           cmdLine,     // command line
 
486
                           NULL,        // process security
 
487
                           NULL,        // thread security
 
488
                           TRUE,        // inherit handles
 
489
                           dwCreationFlags, // creation flags
 
490
                           envBlock,        // environment
 
491
                           wideCwd,         // cwd
 
492
                           &sInfo,         // startup info
 
493
                           &processInfo );  // process info (returned)
 
494
 
518
495
 
519
496
  if (cmdLine)
520
497
    PR_Free(cmdLine);
521
 
    
 
498
 
522
499
  if (wideCwd)
523
500
      PR_Free(wideCwd);
524
501
 
525
502
  if (envBlock)
526
503
    PR_DELETE(envBlock);
527
 
  
 
504
 
528
505
  nsMemory::Free(my_argv);
529
506
 
 
507
 
530
508
  // Close handle to primary thread of process (we don't need it)
531
509
  CloseHandle(processInfo.hThread);
532
510
 
533
 
  if (!bRetVal)
 
511
 
 
512
  if (!bRetVal) {
534
513
    return IPC_NULL_HANDLE;
 
514
  }
535
515
 
536
516
  return processInfo.hProcess;
537
517
}
598
578
  *readPipe  = (void*) hReadPipe;
599
579
  *writePipe = (void*) hWritePipe;
600
580
 
601
 
  DEBUG_LOG(("IPCProcess: created pipe %p, %p\n", hReadPipe,
602
 
                                                  hWritePipe));
603
 
 
604
581
  return PR_SUCCESS;
605
582
}
606
583
 
607
584
 
608
585
PRStatus IPC_WaitProcessWin32(IPCProcess* process, PRInt32 *exitCode)
609
586
{
610
 
  DEBUG_LOG(("IPCProcess: wait for %p\n", process));
611
 
 
612
587
  DWORD dwRetVal = WaitForSingleObject((HANDLE) process, INFINITE);
613
588
  if (dwRetVal == WAIT_FAILED)
614
589
    return PR_FAILURE;
636
611
   * between 0 and 255.  So here on Windows, we use the exit code
637
612
   * 256 to indicate that the process is killed.
638
613
   */
639
 
  DEBUG_LOG(("IPCProcess: killing %p\n", process));
640
 
 
641
 
  if (TerminateProcess((HANDLE) process, 256))
642
 
    return PR_SUCCESS;
643
 
 
644
 
  return PR_FAILURE;
645
 
}
646
 
 
 
614
 
 
615
  return TerminateProcess((HANDLE) process, 256) ? PR_SUCCESS : PR_FAILURE;
 
616
}
 
617
 
 
618
PRStatus IPC_GetProcessIdWin32(IPCProcess* process, PRInt32 *pid)
 
619
{
 
620
  *pid = -1;
 
621
  if (! process)
 
622
    return PR_FAILURE;
 
623
 
 
624
  HMODULE kernelDLL = ::LoadLibraryW(L"kernel32.dll");
 
625
  if (kernelDLL) {
 
626
      GetProcessIdPtr getProcessId = (GetProcessIdPtr)GetProcAddress(kernelDLL,
 
627
        "GetProcessId");
 
628
      if (getProcessId)
 
629
         *pid  = getProcessId((HANDLE) process);
 
630
 
 
631
      FreeLibrary(kernelDLL);
 
632
  }
 
633
 
 
634
  return PR_SUCCESS;
 
635
}
647
636
 
648
637
PRInt32 IPC_ReadWin32(IPCFileDesc* fd, void *buf, PRInt32 amount)
649
638
{
654
643
               amount,
655
644
               &bytes,
656
645
               NULL)) {
657
 
    DEBUG_LOG(("IPCProcess: read %d bytes from %p\n", bytes, fd));
658
646
    return bytes;
659
647
  }
660
648
 
661
649
  DWORD dwLastError = GetLastError();
662
650
 
663
 
  DEBUG_LOG(("IPCProcess: error in reading from %p (code=%d)\n",
664
 
             fd, (int) dwLastError));
665
 
 
666
651
  if (dwLastError == ERROR_BROKEN_PIPE)
667
652
    return 0;
668
653
 
675
660
  unsigned long bytes;
676
661
 
677
662
  if (WriteFile((HANDLE) fd, buf, amount, &bytes, NULL )) {
678
 
    DEBUG_LOG(("IPCProcess: wrote %d bytes to %p\n", bytes, fd));
679
663
    return bytes;
680
664
  }
681
665
 
682
666
  DWORD dwLastError = GetLastError();
683
667
 
684
 
  DEBUG_LOG(("IPCProcess: error in writing to %p (code=%d)\n",
685
 
             fd, (int) dwLastError));
686
 
 
687
668
  return -1;
688
669
 
689
670
}
691
672
 
692
673
PRStatus IPC_CloseWin32(IPCFileDesc* fd)
693
674
{
694
 
  if (CloseHandle((HANDLE) fd))
695
 
    return PR_SUCCESS;
696
 
 
697
 
  return PR_FAILURE;
 
675
  return (CloseHandle((HANDLE) fd)) ? PR_SUCCESS : PR_FAILURE;
698
676
}
699
677
 
700
678