~ubuntu-branches/ubuntu/vivid/mpich/vivid-proposed

« back to all changes in this revision

Viewing changes to src/pm/smpd/smpd_launch_process.c

  • Committer: Package Import Robot
  • Author(s): Anton Gladky
  • Date: 2014-04-01 20:24:20 UTC
  • mfrom: (5.2.4 sid)
  • Revision ID: package-import@ubuntu.com-20140401202420-t5ey1ia2klt5dkq3
Tags: 3.1-4
* [c3e3398] Disable test_primitives, which is unreliable on some platforms.
            (Closes: #743047)
* [265a699] Add minimal autotest.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2
 
/*
3
 
 *  (C) 2001 by Argonne National Laboratory.
4
 
 *      See COPYRIGHT in top-level directory.
5
 
 */
6
 
#include "smpd.h"
7
 
#ifdef HAVE_SYS_TYPES_H
8
 
#include <sys/types.h>
9
 
#endif
10
 
#ifdef HAVE_SYS_SOCKET_H
11
 
#include <sys/socket.h>
12
 
#endif
13
 
#ifdef HAVE_SYS_STAT_H
14
 
/* This is needed for umask */
15
 
#include <sys/stat.h>
16
 
#endif
17
 
#include <stdlib.h>
18
 
#ifdef HAVE_ERRNO_H
19
 
#include <errno.h>
20
 
#endif
21
 
#ifdef HAVE_STRING_H
22
 
#include <string.h>
23
 
#endif
24
 
#ifdef HAVE_SIGNAL_H
25
 
#include <signal.h>
26
 
#endif
27
 
 
28
 
#ifdef HAVE_WINDOWS_H
29
 
 
30
 
#define MAX_ERROR_LENGTH 512
31
 
 
32
 
#undef FCNAME
33
 
#define FCNAME "smpd_clear_process_registry"
34
 
int smpd_clear_process_registry()
35
 
{
36
 
    HKEY tkey;
37
 
    DWORD dwLen, result;
38
 
    int i;
39
 
    DWORD dwNumSubKeys, dwMaxSubKeyLen;
40
 
    char pid_str[256];
41
 
    char err_msg[MAX_ERROR_LENGTH] = "";
42
 
 
43
 
    smpd_enter_fn(FCNAME);
44
 
 
45
 
    result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SMPD_REGISTRY_KEY "\\process", 0, KEY_ALL_ACCESS, &tkey);
46
 
    if (result != ERROR_SUCCESS)
47
 
    {
48
 
        if (result != ERROR_PATH_NOT_FOUND)
49
 
        {
50
 
            smpd_err_printf("Unable to open the " SMPD_REGISTRY_KEY "\\process registry key, error %d\n", result);
51
 
            smpd_exit_fn(FCNAME);
52
 
            return SMPD_FAIL;
53
 
        }
54
 
        return SMPD_SUCCESS;
55
 
    }
56
 
 
57
 
    result = RegQueryInfoKey(tkey, NULL, NULL, NULL, &dwNumSubKeys, &dwMaxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL);
58
 
    if (result != ERROR_SUCCESS)
59
 
    {
60
 
        RegCloseKey(tkey);
61
 
        smpd_exit_fn(FCNAME);
62
 
        return SMPD_FAIL;
63
 
    }
64
 
    if (dwMaxSubKeyLen > 256)
65
 
    {
66
 
        smpd_err_printf("Error: Invalid process subkeys, max length is too large: %d\n", dwMaxSubKeyLen);
67
 
        RegCloseKey(tkey);
68
 
        smpd_exit_fn(FCNAME);
69
 
        return SMPD_FAIL;
70
 
    }
71
 
    if (dwNumSubKeys == 0)
72
 
    {
73
 
        result = RegCloseKey(tkey);
74
 
        if (result != ERROR_SUCCESS)
75
 
        {
76
 
            smpd_translate_win_error(result, err_msg, MAX_ERROR_LENGTH, NULL);
77
 
            smpd_err_printf("Error: RegCloseKey(HKEY_LOCAL_MACHINE\\" SMPD_REGISTRY_KEY "\\process) failed, %s\n", err_msg);
78
 
            smpd_exit_fn(FCNAME);
79
 
            return SMPD_FAIL;
80
 
        }
81
 
        result = RegDeleteKey(HKEY_LOCAL_MACHINE, SMPD_REGISTRY_KEY "\\process");
82
 
        if (result != ERROR_SUCCESS)
83
 
        {
84
 
            smpd_translate_win_error(result, err_msg, MAX_ERROR_LENGTH, NULL);
85
 
            smpd_err_printf("Error: Unable to remove the HKEY_LOCAL_MACHINE\\" SMPD_REGISTRY_KEY "\\process registry key, %s\n", err_msg);
86
 
            smpd_exit_fn(FCNAME);
87
 
            return SMPD_FAIL;
88
 
        }
89
 
        smpd_exit_fn(FCNAME);
90
 
        return SMPD_SUCCESS;
91
 
    }
92
 
    /* count backwards so keys can be removed */
93
 
    for (i=dwNumSubKeys-1; i>=0; i--)
94
 
    {
95
 
        dwLen = 256;
96
 
        result = RegEnumKeyEx(tkey, i, pid_str, &dwLen, NULL, NULL, NULL, NULL);
97
 
        if (result != ERROR_SUCCESS)
98
 
        {
99
 
            smpd_err_printf("Error: Unable to enumerate the %d subkey in the " SMPD_REGISTRY_KEY "\\process registry key\n", i);
100
 
            RegCloseKey(tkey);
101
 
            smpd_exit_fn(FCNAME);
102
 
            return SMPD_FAIL;
103
 
        }
104
 
        result = RegDeleteKey(tkey, pid_str);
105
 
        if (result != ERROR_SUCCESS)
106
 
        {
107
 
            smpd_translate_win_error(result, err_msg, MAX_ERROR_LENGTH, NULL);
108
 
            smpd_err_printf("Error: RegDeleteKey(HKEY_LOCAL_MACHINE\\" SMPD_REGISTRY_KEY "\\process\\%s) failed, %s\n", pid_str, err_msg);
109
 
            smpd_exit_fn(FCNAME);
110
 
            return SMPD_FAIL;
111
 
        }
112
 
    }
113
 
    result = RegCloseKey(tkey);
114
 
    if (result != ERROR_SUCCESS)
115
 
    {
116
 
        smpd_translate_win_error(result, err_msg, MAX_ERROR_LENGTH, NULL);
117
 
        smpd_err_printf("Error: RegCloseKey(HKEY_LOCAL_MACHINE\\" SMPD_REGISTRY_KEY ") failed, %s\n", err_msg);
118
 
        smpd_exit_fn(FCNAME);
119
 
        return SMPD_FAIL;
120
 
    }
121
 
    result = RegDeleteKey(HKEY_LOCAL_MACHINE, SMPD_REGISTRY_KEY "\\process");
122
 
    if (result != ERROR_SUCCESS)
123
 
    {
124
 
        smpd_translate_win_error(result, err_msg, MAX_ERROR_LENGTH, NULL);
125
 
        smpd_err_printf("Error: Unable to remove the HKEY_LOCAL_MACHINE\\" SMPD_REGISTRY_KEY "\\process registry key, %s\n", err_msg);
126
 
        smpd_exit_fn(FCNAME);
127
 
        return SMPD_FAIL;
128
 
    }
129
 
    smpd_exit_fn(FCNAME);
130
 
    return SMPD_SUCCESS;
131
 
}
132
 
 
133
 
#undef FCNAME
134
 
#define FCNAME "smpd_validate_process_registry"
135
 
int smpd_validate_process_registry()
136
 
{
137
 
    int error;
138
 
    HKEY tkey;
139
 
    DWORD dwLen, result;
140
 
    int i;
141
 
    DWORD dwNumSubKeys, dwMaxSubKeyLen;
142
 
    char pid_str[100];
143
 
    int pid;
144
 
    HANDLE hTemp;
145
 
    char err_msg[MAX_ERROR_LENGTH] = "";
146
 
 
147
 
    smpd_enter_fn(FCNAME);
148
 
 
149
 
    result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SMPD_REGISTRY_KEY "\\process", 0, KEY_ALL_ACCESS, &tkey);
150
 
    if (result != ERROR_SUCCESS)
151
 
    {
152
 
        if (result != ERROR_PATH_NOT_FOUND)
153
 
        {
154
 
            smpd_translate_win_error(result, err_msg, MAX_ERROR_LENGTH, NULL);
155
 
            smpd_err_printf("Unable to open the smpd\\process registry key, error %d, %s\n", result, err_msg);
156
 
            smpd_exit_fn(FCNAME);
157
 
            return SMPD_FAIL;
158
 
        }
159
 
        return SMPD_SUCCESS;
160
 
    }
161
 
 
162
 
    result = RegQueryInfoKey(tkey, NULL, NULL, NULL, &dwNumSubKeys, &dwMaxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL);
163
 
    if (result != ERROR_SUCCESS)
164
 
    {
165
 
        RegCloseKey(tkey);
166
 
        smpd_exit_fn(FCNAME);
167
 
        return SMPD_FAIL;
168
 
    }
169
 
    if (dwMaxSubKeyLen > 100)
170
 
    {
171
 
        smpd_err_printf("Error: Invalid process subkeys, max length is too large: %d\n", dwMaxSubKeyLen);
172
 
        RegCloseKey(tkey);
173
 
        smpd_exit_fn(FCNAME);
174
 
        return SMPD_FAIL;
175
 
    }
176
 
    if (dwNumSubKeys == 0)
177
 
    {
178
 
        RegCloseKey(tkey);
179
 
        smpd_exit_fn(FCNAME);
180
 
        return SMPD_SUCCESS;
181
 
    }
182
 
    /* count backwards so keys can be removed */
183
 
    for (i=dwNumSubKeys-1; i>=0; i--)
184
 
    {
185
 
        dwLen = 100;
186
 
        result = RegEnumKeyEx(tkey, i, pid_str, &dwLen, NULL, NULL, NULL, NULL);
187
 
        if (result != ERROR_SUCCESS)
188
 
        {
189
 
            smpd_translate_win_error(result, err_msg, MAX_ERROR_LENGTH, NULL);
190
 
            smpd_err_printf("Error: Unable to enumerate the %d subkey in the smpd\\process registry key, %s\n", i, err_msg);
191
 
            RegCloseKey(tkey);
192
 
            smpd_exit_fn(FCNAME);
193
 
            return SMPD_FAIL;
194
 
        }
195
 
        pid = atoi(pid_str);
196
 
        printf("pid = %d\n", pid);fflush(stdout);
197
 
        hTemp = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
198
 
        if (hTemp == NULL)
199
 
        {
200
 
            error = GetLastError();
201
 
            if (error == ERROR_INVALID_PARAMETER)
202
 
            {
203
 
                RegDeleteKey(tkey, pid_str);
204
 
            }
205
 
            /*
206
 
            else
207
 
            {
208
 
                printf("error = %d\n", error);
209
 
            }
210
 
            */
211
 
        }
212
 
        else
213
 
        {
214
 
            CloseHandle(hTemp);
215
 
        }
216
 
    }
217
 
    result = RegCloseKey(tkey);
218
 
    if (result != ERROR_SUCCESS)
219
 
    {
220
 
        smpd_translate_win_error(result, err_msg, MAX_ERROR_LENGTH, NULL);
221
 
        smpd_err_printf("Error: RegCloseKey(HKEY_LOCAL_MACHINE\\" SMPD_REGISTRY_KEY "\\process) failed, %s\n", err_msg);
222
 
        smpd_exit_fn(FCNAME);
223
 
        return SMPD_FAIL;
224
 
    }
225
 
    smpd_exit_fn(FCNAME);
226
 
    return SMPD_SUCCESS;
227
 
}
228
 
 
229
 
#undef FCNAME
230
 
#define FCNAME "smpd_process_to_registry"
231
 
int smpd_process_to_registry(smpd_process_t *process, char *actual_exe)
232
 
{
233
 
    HKEY tkey;
234
 
    DWORD len, result;
235
 
    char name[1024];
236
 
    char err_msg[MAX_ERROR_LENGTH] = "";
237
 
 
238
 
    smpd_enter_fn(FCNAME);
239
 
 
240
 
    if (process == NULL)
241
 
    {
242
 
        smpd_dbg_printf("NULL process passed to smpd_process_to_registry.\n");
243
 
        return SMPD_FAIL;
244
 
    }
245
 
 
246
 
    len = snprintf(name, 1024, SMPD_REGISTRY_KEY "\\process\\%d", process->pid);
247
 
    if (len < 0 || len > 1023)
248
 
    {
249
 
        smpd_dbg_printf("unable to create a string of the registry key.\n");
250
 
        return SMPD_FAIL;
251
 
    }
252
 
 
253
 
    result = RegCreateKeyEx(HKEY_LOCAL_MACHINE, name,
254
 
        0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &tkey, NULL);
255
 
    if (result != ERROR_SUCCESS)
256
 
    {
257
 
        smpd_translate_win_error(result, err_msg, MAX_ERROR_LENGTH, NULL);
258
 
        smpd_err_printf("Unable to open the HKEY_LOCAL_MACHINE\\%s registry key, error %d, %s\n", name, result, err_msg);
259
 
        smpd_exit_fn(FCNAME);
260
 
        return SMPD_FAIL;
261
 
    }
262
 
 
263
 
    len = (DWORD)(strlen(actual_exe)+1);
264
 
    result = RegSetValueEx(tkey, "exe", 0, REG_SZ, (const BYTE *)actual_exe, len);
265
 
    if (result != ERROR_SUCCESS)
266
 
    {
267
 
        smpd_translate_win_error(result, err_msg, MAX_ERROR_LENGTH, NULL);
268
 
        smpd_err_printf("Unable to write the process registry value 'exe:%s', error %d, %s\n", process->exe, result, err_msg);
269
 
        RegCloseKey(tkey);
270
 
        smpd_exit_fn(FCNAME);
271
 
        return SMPD_FAIL;
272
 
    }
273
 
 
274
 
    result = RegCloseKey(tkey);
275
 
    if (result != ERROR_SUCCESS)
276
 
    {
277
 
        smpd_translate_win_error(result, err_msg, MAX_ERROR_LENGTH, NULL);
278
 
        smpd_err_printf("Error: RegCloseKey(HKEY_LOCAL_MACHINE\\" SMPD_REGISTRY_KEY "\\process\\%d) failed, %s\n", process->pid, err_msg);
279
 
        smpd_exit_fn(FCNAME);
280
 
        return SMPD_FAIL;
281
 
    }
282
 
    smpd_exit_fn(FCNAME);
283
 
    return SMPD_SUCCESS;
284
 
}
285
 
 
286
 
#undef FCNAME
287
 
#define FCNAME "smpd_process_from_registry"
288
 
int smpd_process_from_registry(smpd_process_t *process)
289
 
{
290
 
    DWORD len, result;
291
 
    char name[1024];
292
 
    char err_msg[MAX_ERROR_LENGTH] = "";
293
 
 
294
 
    smpd_enter_fn(FCNAME);
295
 
 
296
 
    if (process == NULL)
297
 
    {
298
 
        smpd_exit_fn(FCNAME);
299
 
        return SMPD_FAIL;
300
 
    }
301
 
 
302
 
    len = snprintf(name, 1024, SMPD_REGISTRY_KEY "\\process\\%d", process->pid);
303
 
    if (len < 0 || len > 1023)
304
 
    {
305
 
        smpd_exit_fn(FCNAME);
306
 
        return SMPD_FAIL;
307
 
    }
308
 
 
309
 
    result = RegDeleteKey(HKEY_LOCAL_MACHINE, name);
310
 
    if (result != ERROR_SUCCESS)
311
 
    {
312
 
        if (result == ERROR_FILE_NOT_FOUND || result == ERROR_PATH_NOT_FOUND)
313
 
        {
314
 
            /* Key already deleted, return success */
315
 
            smpd_exit_fn(FCNAME);
316
 
            return SMPD_SUCCESS;
317
 
        }
318
 
        smpd_translate_win_error(result, err_msg, MAX_ERROR_LENGTH, NULL);
319
 
        smpd_err_printf("Unable to delete the HKEY_LOCAL_MACHINE\\%s registry key, error %d\n", name, result, err_msg);
320
 
        smpd_exit_fn(FCNAME);
321
 
        return SMPD_FAIL;
322
 
    }
323
 
 
324
 
    smpd_exit_fn(FCNAME);
325
 
    return SMPD_SUCCESS;
326
 
}
327
 
 
328
 
#undef FCNAME
329
 
#define FCNAME "smpd_get_user_handle"
330
 
int smpd_get_user_handle(char *account, char *domain, char *password, HANDLE *handle_ptr)
331
 
{
332
 
    HANDLE hUser;
333
 
    int error;
334
 
    int num_tries = 3;
335
 
 
336
 
    smpd_enter_fn(FCNAME);
337
 
 
338
 
    if (domain)
339
 
    {
340
 
        smpd_dbg_printf("LogonUser(%s\\%s)\n", domain, account);
341
 
    }
342
 
    else
343
 
    {
344
 
        smpd_dbg_printf("LogonUser(%s)\n", account);
345
 
    }
346
 
 
347
 
    /* logon the user */
348
 
    while (!LogonUser(
349
 
        account,
350
 
        domain,
351
 
        password,
352
 
        LOGON32_LOGON_INTERACTIVE,
353
 
        LOGON32_PROVIDER_DEFAULT,
354
 
        &hUser))
355
 
    {
356
 
        error = GetLastError();
357
 
        if (error == ERROR_NO_LOGON_SERVERS)
358
 
        {
359
 
            if (num_tries)
360
 
                Sleep(250);
361
 
            else
362
 
            {
363
 
                *handle_ptr = INVALID_HANDLE_VALUE;
364
 
                smpd_exit_fn(FCNAME);
365
 
                return error;
366
 
            }
367
 
            num_tries--;
368
 
        }
369
 
        else
370
 
        {
371
 
            *handle_ptr = INVALID_HANDLE_VALUE;
372
 
            smpd_exit_fn(FCNAME);
373
 
            return error;
374
 
        }
375
 
    }
376
 
 
377
 
    *handle_ptr = hUser;
378
 
    smpd_exit_fn(FCNAME);
379
 
    return SMPD_SUCCESS;
380
 
}
381
 
 
382
 
#undef FCNAME
383
 
#define FCNAME "smpd_get_user_name"
384
 
int smpd_get_user_name(char *account, char *domain, char *full_domain)
385
 
{
386
 
    DWORD len;
387
 
    char name[SMPD_MAX_ACCOUNT_LENGTH];
388
 
    char *separator;
389
 
    size_t i;
390
 
 
391
 
    *account = '\0';
392
 
    if (domain != NULL)
393
 
        *domain = '\0';
394
 
    if (full_domain != NULL)
395
 
        *full_domain = '\0';
396
 
 
397
 
    len = 100;
398
 
    if (GetUserNameEx(NameSamCompatible, name, &len))
399
 
    {
400
 
        for (i=0; i<strlen(name); i++)
401
 
        {
402
 
            name[i] = (char)(tolower(name[i]));
403
 
        }
404
 
        separator = strchr(name, '\\');
405
 
        if (separator)
406
 
        {
407
 
            *separator = '\0';
408
 
            separator++;
409
 
        }
410
 
        if (domain != NULL)
411
 
            strcpy(domain, name);
412
 
        strcpy(account, separator);
413
 
    }
414
 
 
415
 
    if (full_domain != NULL)
416
 
    {
417
 
        len = 100;
418
 
        if (GetUserNameEx(NameDnsDomain, name, &len))
419
 
        {
420
 
            for (i=0; i<strlen(name); i++)
421
 
            {
422
 
                name[i] = (char)(tolower(name[i]));
423
 
            }
424
 
            separator = strchr(name, '\\');
425
 
            if (separator)
426
 
            {
427
 
                *separator = '\0';
428
 
                strcpy(full_domain, name);
429
 
            }
430
 
        }
431
 
    }
432
 
 
433
 
    smpd_exit_fn(FCNAME);
434
 
    return SMPD_SUCCESS;
435
 
}
436
 
 
437
 
#undef FCNAME
438
 
#define FCNAME "SetEnvironmentVariables"
439
 
static void SetEnvironmentVariables(char *bEnv)
440
 
{
441
 
    char name[SMPD_MAX_ENV_LENGTH], equals[3], value[SMPD_MAX_ENV_LENGTH];
442
 
 
443
 
    smpd_enter_fn(FCNAME);
444
 
    for (;;)
445
 
    {
446
 
        name[0] = '\0';
447
 
        equals[0] = '\0';
448
 
        value[0] = '\0';
449
 
        if (MPIU_Str_get_string(&bEnv, name, SMPD_MAX_ENV_LENGTH) != MPIU_STR_SUCCESS)
450
 
            break;
451
 
        if (name[0] == '\0')
452
 
            break;
453
 
        if (MPIU_Str_get_string(&bEnv, equals, 3) != MPIU_STR_SUCCESS)
454
 
            break;
455
 
        if (equals[0] == '\0')
456
 
            break;
457
 
        if (MPIU_Str_get_string(&bEnv, value, SMPD_MAX_ENV_LENGTH) != MPIU_STR_SUCCESS)
458
 
            break;
459
 
        smpd_dbg_printf("setting environment variable: <%s> = <%s>\n", name, value);
460
 
        SetEnvironmentVariable(name, value);
461
 
    }
462
 
    smpd_exit_fn(FCNAME);
463
 
}
464
 
 
465
 
#undef FCNAME
466
 
#define FCNAME "RemoveEnvironmentVariables"
467
 
static void RemoveEnvironmentVariables(char *bEnv)
468
 
{
469
 
    char name[SMPD_MAX_ENV_LENGTH], equals[3], value[SMPD_MAX_ENV_LENGTH];
470
 
 
471
 
    smpd_enter_fn(FCNAME);
472
 
    for (;;)
473
 
    {
474
 
        name[0] = '\0';
475
 
        equals[0] = '\0';
476
 
        value[0] = '\0';
477
 
        if (MPIU_Str_get_string(&bEnv, name, SMPD_MAX_ENV_LENGTH) != MPIU_STR_SUCCESS)
478
 
            break;
479
 
        if (name[0] == '\0')
480
 
            break;
481
 
        if (MPIU_Str_get_string(&bEnv, equals, 3) != MPIU_STR_SUCCESS)
482
 
            break;
483
 
        if (equals[0] == '\0')
484
 
            break;
485
 
        if (MPIU_Str_get_string(&bEnv, value, SMPD_MAX_ENV_LENGTH) != MPIU_STR_SUCCESS)
486
 
            break;
487
 
        /*smpd_dbg_printf("removing environment variable <%s>\n", name);*/
488
 
        SetEnvironmentVariable(name, NULL);
489
 
    }
490
 
    smpd_exit_fn(FCNAME);
491
 
}
492
 
 
493
 
#undef FCNAME
494
 
#define FCNAME "smpd_priority_class_to_win_class"
495
 
int smpd_priority_class_to_win_class(int *priorityClass)
496
 
{
497
 
    smpd_enter_fn(FCNAME);
498
 
    switch (*priorityClass)
499
 
    {
500
 
    case 0:
501
 
        *priorityClass = IDLE_PRIORITY_CLASS;
502
 
        break;
503
 
    case 1:
504
 
        *priorityClass = BELOW_NORMAL_PRIORITY_CLASS;
505
 
        break;
506
 
    case 2:
507
 
        *priorityClass = NORMAL_PRIORITY_CLASS;
508
 
        break;
509
 
    case 3:
510
 
        *priorityClass = ABOVE_NORMAL_PRIORITY_CLASS;
511
 
        break;
512
 
    case 4:
513
 
        *priorityClass = HIGH_PRIORITY_CLASS;
514
 
        break;
515
 
    default:
516
 
        *priorityClass = NORMAL_PRIORITY_CLASS;
517
 
        break;
518
 
    }
519
 
    smpd_exit_fn(FCNAME);
520
 
    return SMPD_SUCCESS;
521
 
}
522
 
 
523
 
#undef FCNAME
524
 
#define FCNAME "smpd_priority_to_win_priority"
525
 
int smpd_priority_to_win_priority(int *priority)
526
 
{
527
 
    smpd_enter_fn(FCNAME);
528
 
    switch (*priority)
529
 
    {
530
 
    case 0:
531
 
        *priority = THREAD_PRIORITY_IDLE;
532
 
        break;
533
 
    case 1:
534
 
        *priority = THREAD_PRIORITY_LOWEST;
535
 
        break;
536
 
    case 2:
537
 
        *priority = THREAD_PRIORITY_BELOW_NORMAL;
538
 
        break;
539
 
    case 3:
540
 
        *priority = THREAD_PRIORITY_NORMAL;
541
 
        break;
542
 
    case 4:
543
 
        *priority = THREAD_PRIORITY_ABOVE_NORMAL;
544
 
        break;
545
 
    case 5:
546
 
        *priority = THREAD_PRIORITY_HIGHEST;
547
 
        break;
548
 
    default:
549
 
        *priority = THREAD_PRIORITY_NORMAL;
550
 
        break;
551
 
    }
552
 
    smpd_exit_fn(FCNAME);
553
 
    return SMPD_SUCCESS;
554
 
}
555
 
 
556
 
/* Windows code */
557
 
 
558
 
typedef struct smpd_piothread_arg_t
559
 
{
560
 
    HANDLE hIn;
561
 
    SOCKET hOut;
562
 
    int pid;
563
 
} smpd_piothread_arg_t;
564
 
 
565
 
typedef struct smpd_pinthread_arg_t
566
 
{
567
 
    SOCKET hIn;
568
 
    HANDLE hOut;
569
 
    int pid;
570
 
} smpd_pinthread_arg_t;
571
 
 
572
 
#undef FCNAME
573
 
#define FCNAME "smpd_easy_send"
574
 
static int smpd_easy_send(SOCKET sock, char *buffer, int length)
575
 
{
576
 
    int error;
577
 
    int num_sent, num_left;
578
 
 
579
 
    smpd_exit_fn(FCNAME);
580
 
    num_left = length;
581
 
    while (num_left)
582
 
    {
583
 
        while ((num_sent = send(sock, buffer, num_left, 0)) == SOCKET_ERROR)
584
 
        {
585
 
            error = WSAGetLastError();
586
 
            if (error == WSAEWOULDBLOCK)
587
 
            {
588
 
                Sleep(0);
589
 
                continue;
590
 
            }
591
 
            if (error == WSAENOBUFS)
592
 
            {
593
 
                /* If there is no buffer space available then split the buffer in half and send each piece separately.*/
594
 
                if (smpd_easy_send(sock, buffer, num_left/2) == SOCKET_ERROR)
595
 
                {
596
 
                    smpd_exit_fn(FCNAME);
597
 
                    return SOCKET_ERROR;
598
 
                }
599
 
                if (smpd_easy_send(sock, buffer+(num_left/2), num_left - (num_left/2)) == SOCKET_ERROR)
600
 
                {
601
 
                    smpd_exit_fn(FCNAME);
602
 
                    return SOCKET_ERROR;
603
 
                }
604
 
                smpd_exit_fn(FCNAME);
605
 
                return length;
606
 
            }
607
 
            WSASetLastError(error);
608
 
            smpd_exit_fn(FCNAME);
609
 
            return SOCKET_ERROR;
610
 
        }
611
 
        num_left = num_left - num_sent;
612
 
        buffer = buffer + num_sent;
613
 
    }
614
 
    smpd_exit_fn(FCNAME);
615
 
    return length;
616
 
}
617
 
 
618
 
int smpd_piothread(smpd_piothread_arg_t *p)
619
 
{
620
 
    char buffer[8192];
621
 
    DWORD num_read;
622
 
    HANDLE hIn;
623
 
    SOCKET hOut;
624
 
    DWORD error;
625
 
    char bogus_char;
626
 
    int pid;
627
 
    double t1, t2;
628
 
 
629
 
    hIn = p->hIn;
630
 
    hOut = p->hOut;
631
 
    pid = p->pid;
632
 
    MPIU_Free(p);
633
 
    p = NULL;
634
 
 
635
 
    smpd_dbg_printf("*** entering smpd_piothread pid:%d sock:%d ***\n", pid, hOut);
636
 
    for (;;)
637
 
    {
638
 
        num_read = 0;
639
 
        if (!ReadFile(hIn, buffer, 8192, &num_read, NULL))
640
 
        {
641
 
            error = GetLastError();
642
 
            /* If there was an error but some bytes were read, send those bytes before exiting */
643
 
            if (num_read > 0)
644
 
            {
645
 
                if (smpd_easy_send(hOut, buffer, num_read) == SOCKET_ERROR)
646
 
                {
647
 
                    smpd_dbg_printf("smpd_easy_send of %d bytes failed.\n", num_read);
648
 
                    break;
649
 
                }
650
 
            }
651
 
            smpd_dbg_printf("ReadFile failed, error %d\n", error);
652
 
            break;
653
 
        }
654
 
        if (num_read < 1)
655
 
        {
656
 
            smpd_dbg_printf("ReadFile returned %d bytes\n", num_read);
657
 
            break;
658
 
        }
659
 
        /*smpd_dbg_printf("*** smpd_piothread read %d bytes ***\n", num_read);*/
660
 
        if (smpd_easy_send(hOut, buffer, num_read) == SOCKET_ERROR)
661
 
        {
662
 
            smpd_dbg_printf("smpd_easy_send of %d bytes failed.\n", num_read);
663
 
            break;
664
 
        }
665
 
        /*smpd_dbg_printf("*** smpd_piothread wrote %d bytes ***\n", num_read);*/
666
 
    }
667
 
    smpd_dbg_printf("*** smpd_piothread finishing pid:%d ***\n", pid);
668
 
    /*
669
 
    FlushFileBuffers((HANDLE)hOut);
670
 
    if (shutdown(hOut, SD_BOTH) == SOCKET_ERROR)
671
 
    {
672
 
        smpd_err_printf("shutdown failed, sock %d, error %d\n", hOut, WSAGetLastError());
673
 
    }
674
 
    if (closesocket(hOut) == SOCKET_ERROR)
675
 
    {
676
 
        smpd_err_printf("closesocket failed, sock %d, error %d\n", hOut, WSAGetLastError());
677
 
    }
678
 
    */
679
 
    if (shutdown(hOut, SD_SEND) == SOCKET_ERROR)
680
 
    {
681
 
        smpd_err_printf("shutdown failed, sock %d, error %d\n", hOut, WSAGetLastError());
682
 
    }
683
 
    t1 = PMPI_Wtime();
684
 
    recv(hOut, &bogus_char, 1, 0);
685
 
    if (closesocket(hOut) == SOCKET_ERROR)
686
 
    {
687
 
        smpd_err_printf("closesocket failed, sock %d, error %d\n", hOut, WSAGetLastError());
688
 
    }
689
 
    t2 = PMPI_Wtime();
690
 
    smpd_dbg_printf("closing output socket took %.3f seconds\n", t2-t1);
691
 
    CloseHandle(hIn);
692
 
    /*smpd_dbg_printf("*** exiting smpd_piothread ***\n");*/
693
 
    return 0;
694
 
}
695
 
 
696
 
/* one line at a time version */
697
 
int smpd_pinthread(smpd_pinthread_arg_t *p)
698
 
{
699
 
    char str [SMPD_MAX_CMD_LENGTH];
700
 
    int index;
701
 
    DWORD num_written;
702
 
    int num_read;
703
 
    SOCKET hIn;
704
 
    HANDLE hOut;
705
 
    int pid;
706
 
    /*int i;*/
707
 
    /*
708
 
    char bogus_char;
709
 
    double t1, t2;
710
 
    */
711
 
 
712
 
    hIn = p->hIn;
713
 
    hOut = p->hOut;
714
 
    pid = p->pid;
715
 
    MPIU_Free(p);
716
 
    p = NULL;
717
 
 
718
 
    smpd_dbg_printf("*** entering smpd_pinthread pid:%d sock:%d ***\n", pid, hIn);
719
 
    index = 0;
720
 
    for (;;)
721
 
    {
722
 
        num_read = recv(hIn, &str[index], 1, 0);
723
 
        if (num_read == SOCKET_ERROR || num_read == 0)
724
 
        {
725
 
            if (num_read == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK)
726
 
            {
727
 
                u_long optval = (u_long)TRUE;
728
 
                ioctlsocket(hIn, FIONBIO, &optval);
729
 
                continue;
730
 
            }
731
 
            if (index > 0)
732
 
            {
733
 
                /* write any buffered data before exiting */
734
 
                if (!WriteFile(hOut, str, index, &num_written, NULL))
735
 
                {
736
 
                    smpd_dbg_printf("WriteFile failed, error %d\n", GetLastError());
737
 
                    break;
738
 
                }
739
 
            }
740
 
            if (num_read != 0)
741
 
            {
742
 
                smpd_dbg_printf("recv from stdin socket failed, error %d.\n", WSAGetLastError());
743
 
            }
744
 
            break;
745
 
        }
746
 
        if (str[index] == '\n' || index == SMPD_MAX_CMD_LENGTH-1)
747
 
        {
748
 
            smpd_dbg_printf("writing %d bytes to the process's stdin\n", index+1);
749
 
            if (!WriteFile(hOut, str, index+1, &num_written, NULL))
750
 
            {
751
 
                smpd_dbg_printf("WriteFile failed, error %d\n", GetLastError());
752
 
                break;
753
 
            }
754
 
            /*
755
 
            smpd_dbg_printf("wrote: ");
756
 
            for (i=0; i<=index; i++)
757
 
            {
758
 
                smpd_dbg_printf("(%d)'%c'", (int)str[i], str[i]);
759
 
            }
760
 
            smpd_dbg_printf("\n");
761
 
            */
762
 
            index = 0;
763
 
        }
764
 
        else
765
 
        {
766
 
            smpd_dbg_printf("read character(%d)'%c'\n", (int)str[index], str[index]);
767
 
            index++;
768
 
        }
769
 
    }
770
 
    smpd_dbg_printf("*** smpd_pinthread finishing pid:%d ***\n", pid);
771
 
    FlushFileBuffers(hOut);
772
 
    if (shutdown(hIn, SD_BOTH) == SOCKET_ERROR)
773
 
    {
774
 
        smpd_err_printf("shutdown failed, sock %d, error %d\n", hIn, WSAGetLastError());
775
 
    }
776
 
    if (closesocket(hIn) == SOCKET_ERROR)
777
 
    {
778
 
        smpd_err_printf("closesocket failed, sock %d, error %d\n", hIn, WSAGetLastError());
779
 
    }
780
 
    /*
781
 
    if (shutdown(hIn, SD_SEND) == SOCKET_ERROR)
782
 
    {
783
 
        smpd_err_printf("shutdown failed, sock %d, error %d\n", hIn, WSAGetLastError());
784
 
    }
785
 
    t1 = PMPI_Wtime();
786
 
    recv(hIn, &bogus_char, 1, 0);
787
 
    if (closesocket(hIn) == SOCKET_ERROR)
788
 
    {
789
 
        smpd_err_printf("closesocket failed, sock %d, error %d\n", hIn, WSAGetLastError());
790
 
    }
791
 
    t2 = PMPI_Wtime();
792
 
    smpd_dbg_printf("closing input socket took %.3f seconds\n", t2-t1);
793
 
    */
794
 
    CloseHandle(hOut);
795
 
    /*smpd_dbg_printf("*** exiting smpd_pinthread ***\n");*/
796
 
    return 0;
797
 
}
798
 
 
799
 
#undef FCNAME
800
 
#define FCNAME "smpd_launch_process"
801
 
int smpd_launch_process(smpd_process_t *process, int priorityClass, int priority, int dbg, SMPDU_Sock_set_t set)
802
 
{
803
 
    HANDLE hStdin = INVALID_HANDLE_VALUE, hStdout = INVALID_HANDLE_VALUE, hStderr = INVALID_HANDLE_VALUE;
804
 
    SOCKET hSockStdinR = INVALID_SOCKET, hSockStdinW = INVALID_SOCKET;
805
 
    SOCKET hSockStdoutR = INVALID_SOCKET, hSockStdoutW = INVALID_SOCKET;
806
 
    SOCKET hSockStderrR = INVALID_SOCKET, hSockStderrW = INVALID_SOCKET;
807
 
    SOCKET hSockPmiR = INVALID_SOCKET, hSockPmiW = INVALID_SOCKET;
808
 
    HANDLE hPipeStdinR = NULL, hPipeStdinW = NULL;
809
 
    HANDLE hPipeStdoutR = NULL, hPipeStdoutW = NULL;
810
 
    HANDLE hPipeStderrR = NULL, hPipeStderrW = NULL;
811
 
    HANDLE hIn = INVALID_HANDLE_VALUE, hOut = INVALID_HANDLE_VALUE, hErr = INVALID_HANDLE_VALUE;
812
 
    STARTUPINFO saInfo;
813
 
    PROCESS_INFORMATION psInfo = { 0 };
814
 
    void *pEnv=NULL;
815
 
    char tSavedPath[MAX_PATH] = ".";
816
 
    DWORD launch_flag = 0;
817
 
    int nError = 0, result = 0;
818
 
    /*unsigned long blocking_flag = 0;*/
819
 
    SMPDU_Sock_t sock_in = SMPDU_SOCK_INVALID_SOCK, sock_out = SMPDU_SOCK_INVALID_SOCK, sock_err = SMPDU_SOCK_INVALID_SOCK, sock_pmi = SMPDU_SOCK_INVALID_SOCK;
820
 
    SECURITY_ATTRIBUTES saAttr;
821
 
    char str[8192], sock_str[20];
822
 
    BOOL bSuccess = TRUE;
823
 
    char *actual_exe, exe_data[SMPD_MAX_EXE_LENGTH];
824
 
    char *args;
825
 
    char temp_exe[SMPD_MAX_EXE_LENGTH];
826
 
    SMPDU_Sock_t sock_pmi_listener;
827
 
    smpd_context_t *listener_context;
828
 
    int listener_port = 0;
829
 
    char host_description[SMPD_MAX_HOST_DESC_LENGTH];
830
 
    char err_msg[MAX_ERROR_LENGTH] = "";
831
 
 
832
 
    smpd_enter_fn(FCNAME);
833
 
 
834
 
    /* Initialize the psInfo structure in case there is an error an we jump to CLEANUP before psInfo is set */
835
 
    psInfo.hProcess = INVALID_HANDLE_VALUE;
836
 
 
837
 
    /* resolve the executable name */
838
 
    if (process->path[0] != '\0')
839
 
    {
840
 
        args = process->exe;
841
 
        result = MPIU_Str_get_string(&args, temp_exe, SMPD_MAX_EXE_LENGTH);
842
 
        if (result != MPIU_STR_SUCCESS)
843
 
        {
844
 
        }
845
 
        smpd_dbg_printf("searching for '%s' in '%s'\n", temp_exe, process->path);
846
 
        if (smpd_search_path(process->path, temp_exe, SMPD_MAX_EXE_LENGTH, exe_data))
847
 
        {
848
 
            if (args != NULL)
849
 
            {
850
 
                strncat(exe_data, " ", SMPD_MAX_EXE_LENGTH - strlen(exe_data));
851
 
                strncat(exe_data, args, SMPD_MAX_EXE_LENGTH - strlen(exe_data));
852
 
                exe_data[SMPD_MAX_EXE_LENGTH-1] = '\0';
853
 
            }
854
 
            actual_exe = exe_data;
855
 
        }
856
 
        else
857
 
        {
858
 
            actual_exe = process->exe;
859
 
        }
860
 
    }
861
 
    else
862
 
    {
863
 
        actual_exe = process->exe;
864
 
    }
865
 
 
866
 
    smpd_priority_class_to_win_class(&priorityClass);
867
 
    smpd_priority_to_win_priority(&priority);
868
 
 
869
 
    /* Save stdin, stdout, and stderr */
870
 
    result = WaitForSingleObject(smpd_process.hLaunchProcessMutex, INFINITE);
871
 
    if (result == WAIT_FAILED)
872
 
    {
873
 
        result = GetLastError();
874
 
        smpd_translate_win_error(result, err_msg, MAX_ERROR_LENGTH, NULL);
875
 
        smpd_err_printf("Error waiting for smpd_process.hLaunchProcessMutex %d, %s\n", result, err_msg);
876
 
        smpd_exit_fn(FCNAME);
877
 
        return SMPD_FAIL;
878
 
    }
879
 
    hStdin = GetStdHandle(STD_INPUT_HANDLE);
880
 
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
881
 
    hStderr = GetStdHandle(STD_ERROR_HANDLE);
882
 
    if (hStdin == INVALID_HANDLE_VALUE || hStdout == INVALID_HANDLE_VALUE  || hStderr == INVALID_HANDLE_VALUE)
883
 
    {
884
 
        nError = GetLastError(); /* This will only be correct if stderr failed */
885
 
        ReleaseMutex(smpd_process.hLaunchProcessMutex);
886
 
        smpd_translate_win_error(nError, err_msg, MAX_ERROR_LENGTH, NULL);
887
 
        smpd_err_printf("GetStdHandle failed, error %d, %s\n", nError, err_msg);
888
 
        smpd_exit_fn(FCNAME);
889
 
        return SMPD_FAIL;;
890
 
    }
891
 
 
892
 
    /* Create sockets for stdin, stdout, and stderr */
893
 
    nError = smpd_make_socket_loop_choose(&hSockStdinR, SMPD_FALSE, &hSockStdinW, SMPD_TRUE);
894
 
    if (nError)
895
 
    {
896
 
        smpd_err_printf("smpd_make_socket_loop failed, error %d\n", nError);
897
 
        goto CLEANUP;
898
 
    }
899
 
    nError = smpd_make_socket_loop_choose(&hSockStdoutR, SMPD_TRUE, &hSockStdoutW, SMPD_FALSE);
900
 
    if (nError)
901
 
    {
902
 
        smpd_err_printf("smpd_make_socket_loop failed, error %d\n", nError);
903
 
        goto CLEANUP;
904
 
    }
905
 
    nError = smpd_make_socket_loop_choose(&hSockStderrR, SMPD_TRUE, &hSockStderrW, SMPD_FALSE);
906
 
    if (nError)
907
 
    {
908
 
        smpd_err_printf("smpd_make_socket_loop failed, error %d\n", nError);
909
 
        goto CLEANUP;
910
 
    }
911
 
    if (process->pmi != NULL)
912
 
    {
913
 
        if (smpd_process.use_inherited_handles)
914
 
        {
915
 
            nError = smpd_make_socket_loop(&hSockPmiR, &hSockPmiW);
916
 
            if (nError)
917
 
            {
918
 
                smpd_err_printf("smpd_make_socket_loop failed, error %d\n", nError);
919
 
                goto CLEANUP;
920
 
            }
921
 
        }
922
 
        else
923
 
        {
924
 
            nError = SMPDU_Sock_listen(set, NULL, &listener_port, &sock_pmi_listener); 
925
 
            if (nError != SMPD_SUCCESS)
926
 
            {
927
 
                smpd_err_printf("SMPDU_Sock_listen failed,\nsock error: %s\n", get_sock_error_string(nError));
928
 
                goto CLEANUP;
929
 
            }
930
 
            smpd_dbg_printf("pmi listening on port %d\n", listener_port);
931
 
 
932
 
            nError = smpd_create_context(SMPD_CONTEXT_PMI_LISTENER, set, sock_pmi_listener, -1, &listener_context);
933
 
            if (nError != SMPD_SUCCESS)
934
 
            {
935
 
                smpd_err_printf("unable to create a context for the pmi listener.\n");
936
 
                goto CLEANUP;
937
 
            }
938
 
            nError = SMPDU_Sock_set_user_ptr(sock_pmi_listener, listener_context);
939
 
            if (nError != SMPD_SUCCESS)
940
 
            {
941
 
                smpd_err_printf("SMPDU_Sock_set_user_ptr failed,\nsock error: %s\n", get_sock_error_string(nError));
942
 
                goto CLEANUP;
943
 
            }
944
 
            listener_context->state = SMPD_PMI_LISTENING;
945
 
            /* Adding process rank since the interface for SMPDU_Sock_get_host_description changed */
946
 
            nError = SMPDU_Sock_get_host_description(process->rank, host_description, SMPD_MAX_HOST_DESC_LENGTH);
947
 
            if (nError != SMPD_SUCCESS)
948
 
            {
949
 
                smpd_err_printf("SMPDU_Sock_get_host_description failed,\nsock error: %s\n", get_sock_error_string(nError));
950
 
                goto CLEANUP;
951
 
            }
952
 
            /* save the listener sock in the slot reserved for the client sock so we can match the listener
953
 
            to the process structure when the client sock is accepted */
954
 
            process->pmi->sock = sock_pmi_listener;
955
 
        }
956
 
    }
957
 
 
958
 
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
959
 
    saAttr.lpSecurityDescriptor = NULL;
960
 
    saAttr.bInheritHandle = TRUE;
961
 
 
962
 
    /* Create the pipes for stdout, stderr */
963
 
    if (!CreatePipe(&hPipeStdinR, &hPipeStdinW, &saAttr, 0))
964
 
    {
965
 
        smpd_err_printf("CreatePipe(stdin) failed, error %d\n", GetLastError());
966
 
        goto CLEANUP;
967
 
    }
968
 
    if (!CreatePipe(&hPipeStdoutR, &hPipeStdoutW, &saAttr, 0))
969
 
    {
970
 
        smpd_err_printf("CreatePipe(stdout) failed, error %d\n", GetLastError());
971
 
        goto CLEANUP;
972
 
    }
973
 
    if (!CreatePipe(&hPipeStderrR, &hPipeStderrW, &saAttr, 0))
974
 
    {
975
 
        smpd_err_printf("CreatePipe(stderr) failed, error %d\n", GetLastError());
976
 
        goto CLEANUP;
977
 
    }
978
 
 
979
 
    /* Make the ends of the pipes that this process will use not inheritable */
980
 
    /*
981
 
    if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hSockStdinW, GetCurrentProcess(), &hIn, 
982
 
        0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
983
 
    {
984
 
        nError = GetLastError();
985
 
        smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
986
 
        goto CLEANUP;
987
 
    }
988
 
    */
989
 
    if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hPipeStdinW, GetCurrentProcess(), &hIn, 
990
 
        0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
991
 
    {
992
 
        nError = GetLastError();
993
 
        smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
994
 
        goto CLEANUP;
995
 
    }
996
 
    /*
997
 
    if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hSockStdoutR, GetCurrentProcess(), &hOut, 
998
 
        0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
999
 
    {
1000
 
        nError = GetLastError();
1001
 
        smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1002
 
        goto CLEANUP;
1003
 
    }
1004
 
    if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hSockStderrR, GetCurrentProcess(), &hErr, 
1005
 
        0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1006
 
    {
1007
 
        nError = GetLastError();
1008
 
        smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1009
 
        goto CLEANUP;
1010
 
    }
1011
 
    */
1012
 
    if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hPipeStdoutR, GetCurrentProcess(), &hOut, 
1013
 
        0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1014
 
    {
1015
 
        nError = GetLastError();
1016
 
        smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1017
 
        goto CLEANUP;
1018
 
    }
1019
 
    if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hPipeStderrR, GetCurrentProcess(), &hErr, 
1020
 
        0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1021
 
    {
1022
 
        nError = GetLastError();
1023
 
        smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1024
 
        goto CLEANUP;
1025
 
    }
1026
 
    if (process->pmi != NULL && smpd_process.use_inherited_handles)
1027
 
    {
1028
 
        if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hSockPmiR, GetCurrentProcess(), (LPHANDLE)&hSockPmiR, 
1029
 
            0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1030
 
        {
1031
 
            nError = GetLastError();
1032
 
            smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1033
 
            goto CLEANUP;
1034
 
        }
1035
 
    }
1036
 
 
1037
 
    /* prevent the socket loops from being inherited */
1038
 
    if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hSockStdinR, GetCurrentProcess(), (LPHANDLE)&hSockStdinR, 
1039
 
        0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1040
 
    {
1041
 
        nError = GetLastError();
1042
 
        smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1043
 
        goto CLEANUP;
1044
 
    }
1045
 
    if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hSockStdoutR, GetCurrentProcess(), (LPHANDLE)&hSockStdoutR, 
1046
 
        0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1047
 
    {
1048
 
        nError = GetLastError();
1049
 
        smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1050
 
        goto CLEANUP;
1051
 
    }
1052
 
    if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hSockStderrR, GetCurrentProcess(), (LPHANDLE)&hSockStderrR, 
1053
 
        0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1054
 
    {
1055
 
        nError = GetLastError();
1056
 
        smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1057
 
        goto CLEANUP;
1058
 
    }
1059
 
    if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hSockStdinW, GetCurrentProcess(), (LPHANDLE)&hSockStdinW, 
1060
 
        0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1061
 
    {
1062
 
        nError = GetLastError();
1063
 
        smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1064
 
        goto CLEANUP;
1065
 
    }
1066
 
    if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hSockStdoutW, GetCurrentProcess(), (LPHANDLE)&hSockStdoutW, 
1067
 
        0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1068
 
    {
1069
 
        nError = GetLastError();
1070
 
        smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1071
 
        goto CLEANUP;
1072
 
    }
1073
 
    if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hSockStderrW, GetCurrentProcess(), (LPHANDLE)&hSockStderrW, 
1074
 
        0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1075
 
    {
1076
 
        nError = GetLastError();
1077
 
        smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1078
 
        goto CLEANUP;
1079
 
    }
1080
 
 
1081
 
    /* make the ends used by the spawned process blocking */
1082
 
    /*
1083
 
    blocking_flag = 0;
1084
 
    ioctlsocket(hSockStdinR, FIONBIO, &blocking_flag);
1085
 
    */
1086
 
    /*
1087
 
    blocking_flag = 0;
1088
 
    ioctlsocket(hSockStdoutW, FIONBIO, &blocking_flag);
1089
 
    blocking_flag = 0;
1090
 
    ioctlsocket(hSockStderrW, FIONBIO, &blocking_flag);
1091
 
    */
1092
 
 
1093
 
    /* Set stdin, stdout, and stderr to the ends of the pipe the created process will use */
1094
 
    /*
1095
 
    if (!SetStdHandle(STD_INPUT_HANDLE, (HANDLE)hSockStdinR))
1096
 
    {
1097
 
        nError = GetLastError();
1098
 
        smpd_err_printf("SetStdHandle failed, error %d\n", nError);
1099
 
        goto CLEANUP;
1100
 
    }
1101
 
    */
1102
 
    if (!SetStdHandle(STD_INPUT_HANDLE, (HANDLE)hPipeStdinR))
1103
 
    {
1104
 
        nError = GetLastError();
1105
 
        smpd_err_printf("SetStdHandle failed, error %d\n", nError);
1106
 
        goto CLEANUP;
1107
 
    }
1108
 
    /*
1109
 
    if (!SetStdHandle(STD_OUTPUT_HANDLE, (HANDLE)hSockStdoutW))
1110
 
    {
1111
 
        nError = GetLastError();
1112
 
        smpd_err_printf("SetStdHandle failed, error %d\n", nError);
1113
 
        goto RESTORE_CLEANUP;
1114
 
    }
1115
 
    if (!SetStdHandle(STD_ERROR_HANDLE, (HANDLE)hSockStderrW))
1116
 
    {
1117
 
        nError = GetLastError();
1118
 
        smpd_err_printf("SetStdHandle failed, error %d\n", nError);
1119
 
        goto RESTORE_CLEANUP;
1120
 
    }
1121
 
    */
1122
 
    if (!SetStdHandle(STD_OUTPUT_HANDLE, (HANDLE)hPipeStdoutW))
1123
 
    {
1124
 
        nError = GetLastError();
1125
 
        smpd_err_printf("SetStdHandle failed, error %d\n", nError);
1126
 
        goto RESTORE_CLEANUP;
1127
 
    }
1128
 
    if (!SetStdHandle(STD_ERROR_HANDLE, (HANDLE)hPipeStderrW))
1129
 
    {
1130
 
        nError = GetLastError();
1131
 
        smpd_err_printf("SetStdHandle failed, error %d\n", nError);
1132
 
        goto RESTORE_CLEANUP;
1133
 
    }
1134
 
 
1135
 
    /* Create the process */
1136
 
    memset(&saInfo, 0, sizeof(STARTUPINFO));
1137
 
    saInfo.cb = sizeof(STARTUPINFO);
1138
 
    /*saInfo.hStdInput = (HANDLE)hSockStdinR;*/
1139
 
    saInfo.hStdInput = (HANDLE)hPipeStdinR;
1140
 
    /*
1141
 
    saInfo.hStdOutput = (HANDLE)hSockStdoutW;
1142
 
    saInfo.hStdError = (HANDLE)hSockStderrW;
1143
 
    */
1144
 
    saInfo.hStdOutput = (HANDLE)hPipeStdoutW;
1145
 
    saInfo.hStdError = (HANDLE)hPipeStderrW;
1146
 
    saInfo.dwFlags = STARTF_USESTDHANDLES;
1147
 
 
1148
 
    SetEnvironmentVariables(process->env);
1149
 
    if (process->pmi != NULL)
1150
 
    {
1151
 
        sprintf(str, "%d", process->rank);
1152
 
        smpd_dbg_printf("env: PMI_RANK=%s\n", str);
1153
 
        SetEnvironmentVariable("PMI_RANK", str);
1154
 
        sprintf(str, "%d", process->nproc);
1155
 
        smpd_dbg_printf("env: PMI_SIZE=%s\n", str);
1156
 
        SetEnvironmentVariable("PMI_SIZE", str);
1157
 
        sprintf(str, "%s", process->kvs_name);
1158
 
        smpd_dbg_printf("env: PMI_KVS=%s\n", str);
1159
 
        SetEnvironmentVariable("PMI_KVS", str);
1160
 
        sprintf(str, "%s", process->domain_name);
1161
 
        smpd_dbg_printf("env: PMI_DOMAIN=%s\n", str);
1162
 
        SetEnvironmentVariable("PMI_DOMAIN", str);
1163
 
        if (smpd_process.use_inherited_handles)
1164
 
        {
1165
 
            smpd_encode_handle(sock_str, (HANDLE)hSockPmiW);
1166
 
            sprintf(str, "%s", sock_str);
1167
 
            smpd_dbg_printf("env: PMI_SMPD_FD=%s\n", str);
1168
 
            SetEnvironmentVariable("PMI_SMPD_FD", str);
1169
 
        }
1170
 
        else
1171
 
        {
1172
 
            smpd_dbg_printf("env: PMI_HOST=%s\n", host_description);
1173
 
            SetEnvironmentVariable("PMI_HOST", host_description);
1174
 
            sprintf(str, "%d", listener_port);
1175
 
            smpd_dbg_printf("env: PMI_PORT=%s\n", str);
1176
 
            SetEnvironmentVariable("PMI_PORT", str);
1177
 
        }
1178
 
        sprintf(str, "%d", smpd_process.id);
1179
 
        smpd_dbg_printf("env: PMI_SMPD_ID=%s\n", str);
1180
 
        SetEnvironmentVariable("PMI_SMPD_ID", str);
1181
 
        sprintf(str, "%d", process->id);
1182
 
        smpd_dbg_printf("env: PMI_SMPD_KEY=%s\n", str);
1183
 
        SetEnvironmentVariable("PMI_SMPD_KEY", str);
1184
 
        if (process->clique[0] != '\0')
1185
 
        {
1186
 
            sprintf(str, "%s", process->clique);
1187
 
            smpd_dbg_printf("env: PMI_CLIQUE=%s\n", str);
1188
 
            SetEnvironmentVariable("PMI_CLIQUE", str);
1189
 
        }
1190
 
        sprintf(str, "%d", process->spawned);
1191
 
        smpd_dbg_printf("env: PMI_SPAWN=%s\n", str);
1192
 
        SetEnvironmentVariable("PMI_SPAWN", str);
1193
 
        sprintf(str, "%d", process->appnum);
1194
 
        smpd_dbg_printf("env: PMI_APPNUM=%s\n", str);
1195
 
        SetEnvironmentVariable("PMI_APPNUM", str);
1196
 
    }
1197
 
    pEnv = GetEnvironmentStrings();
1198
 
 
1199
 
    GetCurrentDirectory(MAX_PATH, tSavedPath);
1200
 
    SetCurrentDirectory(process->dir);
1201
 
 
1202
 
    launch_flag = 
1203
 
        CREATE_SUSPENDED | /*CREATE_NEW_CONSOLE*/ /*DETACHED_PROCESS*/ CREATE_NO_WINDOW | priorityClass;
1204
 
    if (dbg)
1205
 
        launch_flag = launch_flag | DEBUG_PROCESS;
1206
 
 
1207
 
    smpd_dbg_printf("CreateProcess(%s)\n", actual_exe);
1208
 
    psInfo.hProcess = INVALID_HANDLE_VALUE;
1209
 
    if (CreateProcess(
1210
 
        NULL,
1211
 
        actual_exe,
1212
 
        NULL, NULL, TRUE,
1213
 
        launch_flag,
1214
 
        pEnv,
1215
 
        NULL,
1216
 
        &saInfo, &psInfo))
1217
 
    {
1218
 
        SetThreadPriority(psInfo.hThread, priority);
1219
 
        process->pid = psInfo.dwProcessId;
1220
 
    }
1221
 
    else
1222
 
    {
1223
 
        nError = GetLastError();
1224
 
        smpd_err_printf("CreateProcess('%s') failed, error %d\n", process->exe, nError);
1225
 
        smpd_translate_win_error(nError, process->err_msg, SMPD_MAX_ERROR_LEN, "CreateProcess(%s) on '%s' failed, error %d - ",
1226
 
            process->exe, smpd_process.host, nError);
1227
 
        psInfo.hProcess = INVALID_HANDLE_VALUE;
1228
 
        bSuccess = FALSE;
1229
 
    }
1230
 
 
1231
 
#ifdef HAVE_WINDOWS_H
1232
 
    if(smpd_process.set_affinity)
1233
 
    {
1234
 
        DWORD_PTR mask;
1235
 
        if(process->binding_proc != -1){
1236
 
            /* Get affinity mask corresponding to the binding proc */
1237
 
            mask = smpd_get_processor_affinity_mask(process->binding_proc);
1238
 
        }
1239
 
        else{
1240
 
            /* Get affinity mask decided by smpd - auto binding */
1241
 
            mask = smpd_get_next_process_affinity_mask();
1242
 
        }
1243
 
        if(mask != NULL){
1244
 
            /* FIXME: The return vals of these functions are not checked ! */
1245
 
            smpd_dbg_printf("Setting the process/thread affinity (mask=%lu)\n", mask);
1246
 
            SetProcessAffinityMask(psInfo.hProcess, mask);
1247
 
            SetThreadAffinityMask(psInfo.hThread, mask);
1248
 
                }
1249
 
        else{
1250
 
            smpd_dbg_printf("Unable to set process/thread affinity (mask=%lu)\n", mask);
1251
 
        }
1252
 
    }
1253
 
#endif
1254
 
 
1255
 
    FreeEnvironmentStrings((TCHAR*)pEnv);
1256
 
    SetCurrentDirectory(tSavedPath);
1257
 
    RemoveEnvironmentVariables(process->env);
1258
 
    if (process->pmi != NULL)
1259
 
    {
1260
 
        SetEnvironmentVariable("PMI_RANK", NULL);
1261
 
        SetEnvironmentVariable("PMI_SIZE", NULL);
1262
 
        SetEnvironmentVariable("PMI_KVS", NULL);
1263
 
        SetEnvironmentVariable("PMI_DOMAIN", NULL);
1264
 
        if (smpd_process.use_inherited_handles)
1265
 
        {
1266
 
            SetEnvironmentVariable("PMI_SMPD_FD", NULL);
1267
 
        }
1268
 
        else
1269
 
        {
1270
 
            SetEnvironmentVariable("PMI_HOST", NULL);
1271
 
            SetEnvironmentVariable("PMI_PORT", NULL);
1272
 
        }
1273
 
        SetEnvironmentVariable("PMI_SMPD_ID", NULL);
1274
 
        SetEnvironmentVariable("PMI_SMPD_KEY", NULL);
1275
 
        SetEnvironmentVariable("PMI_SPAWN", NULL);
1276
 
    }
1277
 
 
1278
 
    if (bSuccess)
1279
 
    {
1280
 
        /* make sock structures out of the sockets */
1281
 
        /*
1282
 
        nError = SMPDU_Sock_native_to_sock(set, hIn, NULL, &sock_in);
1283
 
        if (nError != SMPD_SUCCESS)
1284
 
        {
1285
 
            smpd_err_printf("SMPDU_Sock_native_to_sock failed, error %s\n", get_sock_error_string(nError));
1286
 
        }
1287
 
        */
1288
 
        /*printf("native sock for stdin\n");fflush(stdout);*/
1289
 
        nError = SMPDU_Sock_native_to_sock(set, (SMPDU_SOCK_NATIVE_FD)hSockStdinW, NULL, &sock_in);
1290
 
        if (nError != SMPD_SUCCESS)
1291
 
        {
1292
 
            smpd_err_printf("SMPDU_Sock_native_to_sock failed, error %s\n", get_sock_error_string(nError));
1293
 
        }
1294
 
        /*printf("native sock for stdout\n");fflush(stdout);*/
1295
 
        nError = SMPDU_Sock_native_to_sock(set, (SMPDU_SOCK_NATIVE_FD)hSockStdoutR, NULL, &sock_out);
1296
 
        if (nError != SMPD_SUCCESS)
1297
 
        {
1298
 
            smpd_err_printf("SMPDU_Sock_native_to_sock failed, error %s\n", get_sock_error_string(nError));
1299
 
        }
1300
 
        /*printf("native sock for stderr\n");fflush(stdout);*/
1301
 
        nError = SMPDU_Sock_native_to_sock(set, (SMPDU_SOCK_NATIVE_FD)hSockStderrR, NULL, &sock_err);
1302
 
        if (nError != SMPD_SUCCESS)
1303
 
        {
1304
 
            smpd_err_printf("SMPDU_Sock_native_to_sock failed, error %s\n", get_sock_error_string(nError));
1305
 
        }
1306
 
        if (process->pmi != NULL && smpd_process.use_inherited_handles)
1307
 
        {
1308
 
            /*printf("native sock for pmi\n");fflush(stdout);*/
1309
 
            nError = SMPDU_Sock_native_to_sock(set, (SMPDU_SOCK_NATIVE_FD)hSockPmiR, NULL, &sock_pmi);
1310
 
            if (nError != SMPD_SUCCESS)
1311
 
            {
1312
 
                smpd_err_printf("SMPDU_Sock_native_to_sock failed, error %s\n", get_sock_error_string(nError));
1313
 
            }
1314
 
        }
1315
 
 
1316
 
        process->in->sock = sock_in;
1317
 
        process->out->sock = sock_out;
1318
 
        process->err->sock = sock_err;
1319
 
        if (process->pmi != NULL && smpd_process.use_inherited_handles)
1320
 
            process->pmi->sock = sock_pmi;
1321
 
        process->pid = process->in->id = process->out->id = process->err->id = psInfo.dwProcessId;
1322
 
        SMPDU_Sock_set_user_ptr(sock_in, process->in);
1323
 
        SMPDU_Sock_set_user_ptr(sock_out, process->out);
1324
 
        SMPDU_Sock_set_user_ptr(sock_err, process->err);
1325
 
        if (process->pmi != NULL && smpd_process.use_inherited_handles)
1326
 
            SMPDU_Sock_set_user_ptr(sock_pmi, process->pmi);
1327
 
    }
1328
 
    else
1329
 
    {
1330
 
        /* close all the sockets and handles allocated in this function */
1331
 
        /*CloseHandle(hIn);*/
1332
 
        CloseHandle((HANDLE)hSockStdinW);
1333
 
        CloseHandle((HANDLE)hSockStdoutR);
1334
 
        CloseHandle((HANDLE)hSockStderrR);
1335
 
        if (process->pmi != NULL && smpd_process.use_inherited_handles)
1336
 
            CloseHandle((HANDLE)hSockPmiR);
1337
 
    }
1338
 
 
1339
 
RESTORE_CLEANUP:
1340
 
    /* Restore stdin, stdout, stderr */
1341
 
    SetStdHandle(STD_INPUT_HANDLE, hStdin);
1342
 
    SetStdHandle(STD_OUTPUT_HANDLE, hStdout);
1343
 
    SetStdHandle(STD_ERROR_HANDLE, hStderr);
1344
 
 
1345
 
CLEANUP:
1346
 
    ReleaseMutex(smpd_process.hLaunchProcessMutex);
1347
 
    /*CloseHandle((HANDLE)hSockStdinR);*/
1348
 
    CloseHandle((HANDLE)hPipeStdinR);
1349
 
    /*
1350
 
    CloseHandle((HANDLE)hSockStdoutW);
1351
 
    CloseHandle((HANDLE)hSockStderrW);
1352
 
    */
1353
 
    CloseHandle((HANDLE)hPipeStdoutW);
1354
 
    CloseHandle((HANDLE)hPipeStderrW);
1355
 
    if (process->pmi != NULL && smpd_process.use_inherited_handles)
1356
 
        CloseHandle((HANDLE)hSockPmiW);
1357
 
 
1358
 
    if (psInfo.hProcess != INVALID_HANDLE_VALUE)
1359
 
    {
1360
 
        HANDLE hThread;
1361
 
        smpd_piothread_arg_t *arg_ptr;
1362
 
        smpd_pinthread_arg_t *in_arg_ptr;
1363
 
 
1364
 
        in_arg_ptr = (smpd_pinthread_arg_t*)MPIU_Malloc(sizeof(smpd_pinthread_arg_t));
1365
 
        in_arg_ptr->hIn = hSockStdinR;
1366
 
        in_arg_ptr->hOut = hPipeStdinW;
1367
 
        in_arg_ptr->pid = psInfo.dwProcessId;
1368
 
        hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)smpd_pinthread, in_arg_ptr, 0, NULL);
1369
 
        CloseHandle(hThread);
1370
 
        arg_ptr = (smpd_piothread_arg_t*)MPIU_Malloc(sizeof(smpd_piothread_arg_t));
1371
 
        arg_ptr->hIn = hOut;
1372
 
        arg_ptr->hOut = hSockStdoutW;
1373
 
        arg_ptr->pid = psInfo.dwProcessId;
1374
 
        hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)smpd_piothread, arg_ptr, 0, NULL);
1375
 
        CloseHandle(hThread);
1376
 
        arg_ptr = (smpd_piothread_arg_t*)MPIU_Malloc(sizeof(smpd_piothread_arg_t));
1377
 
        arg_ptr->hIn = hErr;
1378
 
        arg_ptr->hOut = hSockStderrW;
1379
 
        arg_ptr->pid = psInfo.dwProcessId;
1380
 
        hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)smpd_piothread, arg_ptr, 0, NULL);
1381
 
        CloseHandle(hThread);
1382
 
 
1383
 
        if (process->pmi != NULL && smpd_process.use_inherited_handles)
1384
 
            process->context_refcount = 3;
1385
 
        else
1386
 
            process->context_refcount = 2;
1387
 
        process->out->read_state = SMPD_READING_STDOUT;
1388
 
        result = SMPDU_Sock_post_read(sock_out, process->out->read_cmd.cmd, 1, 1, NULL);
1389
 
        if (result != SMPD_SUCCESS)
1390
 
        {
1391
 
            smpd_err_printf("posting first read from stdout context failed, sock error: %s\n",
1392
 
                get_sock_error_string(result));
1393
 
            smpd_exit_fn(FCNAME);
1394
 
            return SMPD_FAIL;
1395
 
        }
1396
 
        process->err->read_state = SMPD_READING_STDERR;
1397
 
        result = SMPDU_Sock_post_read(sock_err, process->err->read_cmd.cmd, 1, 1, NULL);
1398
 
        if (result != SMPD_SUCCESS)
1399
 
        {
1400
 
            smpd_err_printf("posting first read from stderr context failed, sock error: %s\n",
1401
 
                get_sock_error_string(result));
1402
 
            smpd_exit_fn(FCNAME);
1403
 
            return SMPD_FAIL;
1404
 
        }
1405
 
        if (process->pmi != NULL && smpd_process.use_inherited_handles)
1406
 
        {
1407
 
            result = smpd_post_read_command(process->pmi);
1408
 
            if (result != SMPD_SUCCESS)
1409
 
            {
1410
 
                smpd_err_printf("unable to post a read of the first command on the pmi control channel.\n");
1411
 
                smpd_exit_fn(FCNAME);
1412
 
                return SMPD_FAIL;
1413
 
            }
1414
 
        }
1415
 
        process->wait.hProcess = process->in->wait.hProcess = process->out->wait.hProcess = process->err->wait.hProcess = psInfo.hProcess;
1416
 
        process->wait.hThread = process->in->wait.hThread = process->out->wait.hThread = process->err->wait.hThread = psInfo.hThread;
1417
 
        smpd_process_to_registry(process, actual_exe);
1418
 
        ResumeThread(psInfo.hThread);
1419
 
        smpd_exit_fn(FCNAME);
1420
 
        return SMPD_SUCCESS;
1421
 
    }
1422
 
 
1423
 
    smpd_exit_fn(FCNAME);
1424
 
    return SMPD_FAIL;
1425
 
}
1426
 
 
1427
 
#undef FCNAME
1428
 
#define FCNAME "smpd_parse_account_domain"
1429
 
void smpd_parse_account_domain(const char *domain_account, char *account, char *domain)
1430
 
{
1431
 
    const char *pCh;
1432
 
    char *pCh2;
1433
 
 
1434
 
    smpd_enter_fn(FCNAME);
1435
 
 
1436
 
    if ((strchr(domain_account, '\\') == NULL) && (strchr(domain_account, '@') != NULL))
1437
 
    {
1438
 
        pCh = domain_account;
1439
 
        pCh2 = account;
1440
 
        while ((*pCh != '@') && (*pCh != '\0'))
1441
 
        {
1442
 
            *pCh2 = *pCh;
1443
 
            pCh++;
1444
 
            pCh2++;
1445
 
        }
1446
 
        *pCh2 = '\0';
1447
 
        if (*pCh == '@')
1448
 
        {
1449
 
            pCh++;
1450
 
            strcpy(domain, pCh);
1451
 
        }
1452
 
        else
1453
 
        {
1454
 
            domain[0] = '\0';
1455
 
        }
1456
 
    }
1457
 
    else
1458
 
    {
1459
 
        pCh = domain_account;
1460
 
        pCh2 = domain;
1461
 
        while ((*pCh != '\\') && (*pCh != '\0'))
1462
 
        {
1463
 
            *pCh2 = *pCh;
1464
 
            pCh++;
1465
 
            pCh2++;
1466
 
        }
1467
 
        if (*pCh == '\\')
1468
 
        {
1469
 
            pCh++;
1470
 
            strcpy(account, pCh);
1471
 
            *pCh2 = '\0';
1472
 
        }
1473
 
        else
1474
 
        {
1475
 
            strcpy(account, domain_account);
1476
 
            domain[0] = '\0';
1477
 
        }
1478
 
    }
1479
 
 
1480
 
    smpd_exit_fn(FCNAME);
1481
 
}
1482
 
 
1483
 
#else
1484
 
 
1485
 
/* Unix code */
1486
 
 
1487
 
/*
1488
 
static void set_environment_variables(char *bEnv)
1489
 
{
1490
 
    char name[1024]="", value[8192]="";
1491
 
    char *pChar;
1492
 
    
1493
 
    pChar = name;
1494
 
    while (*bEnv != '\0')
1495
 
    {
1496
 
        if (*bEnv == '=')
1497
 
        {
1498
 
            *pChar = '\0';
1499
 
            pChar = value;
1500
 
        }
1501
 
        else
1502
 
        {
1503
 
            if (*bEnv == ';')
1504
 
            {
1505
 
                *pChar = '\0';
1506
 
                pChar = name;
1507
 
                smpd_dbg_printf("env: %s=%s\n", name, value);
1508
 
                setenv(name, value, 1);
1509
 
            }
1510
 
            else
1511
 
            {
1512
 
                *pChar = *bEnv;
1513
 
                pChar++;
1514
 
            }
1515
 
        }
1516
 
        bEnv++;
1517
 
    }
1518
 
    *pChar = '\0';
1519
 
    if (name[0] != '\0')
1520
 
    {
1521
 
        smpd_dbg_printf("env: %s=%s\n", name, value);
1522
 
        setenv(name, value, 1);
1523
 
    }
1524
 
}
1525
 
*/
1526
 
 
1527
 
#ifdef HAVE_SETENV
1528
 
#undef FCNAME
1529
 
#define FCNAME "set_environment_variables"
1530
 
static void set_environment_variables(char *bEnv)
1531
 
{
1532
 
    char name[1024], equals[3], value[8192];
1533
 
 
1534
 
    smpd_enter_fn(FCNAME);
1535
 
    while (1)
1536
 
    {
1537
 
        name[0] = '\0';
1538
 
        equals[0] = '\0';
1539
 
        value[0] = '\0';
1540
 
        if (MPIU_Str_get_string(&bEnv, name, 1024) != MPIU_STR_SUCCESS)
1541
 
            break;
1542
 
        if (name[0] == '\0')
1543
 
            break;
1544
 
        if (MPIU_Str_get_string(&bEnv, equals, 3) != MPIU_STR_SUCCESS)
1545
 
            break;
1546
 
        if (equals[0] == '\0')
1547
 
            break;
1548
 
        if (MPIU_Str_get_string(&bEnv, value, 8192) != MPIU_STR_SUCCESS)
1549
 
            break;
1550
 
        setenv(name, value, 1);
1551
 
    }
1552
 
    smpd_exit_fn(FCNAME);
1553
 
}
1554
 
#else
1555
 
#undef FCNAME
1556
 
#define FCNAME "get_env_size"
1557
 
static int get_env_size(char *bEnv, int *count)
1558
 
{
1559
 
    char name[1024], equals[3], value[8192];
1560
 
    int size = 0;
1561
 
 
1562
 
    smpd_enter_fn(FCNAME);
1563
 
    while (1)
1564
 
    {
1565
 
        name[0] = '\0';
1566
 
        equals[0] = '\0';
1567
 
        value[0] = '\0';
1568
 
        if (MPIU_Str_get_string(&bEnv, name, 1024) != MPIU_STR_SUCCESS)
1569
 
            break;
1570
 
        if (name[0] == '\0')
1571
 
            break;
1572
 
        if (MPIU_Str_get_string(&bEnv, equals, 3) != MPIU_STR_SUCCESS)
1573
 
            break;
1574
 
        if (equals[0] == '\0')
1575
 
            break;
1576
 
        if (MPIU_Str_get_string(&bEnv, value, 8192) != MPIU_STR_SUCCESS)
1577
 
            break;
1578
 
        *count = *count + 1;
1579
 
        size = size + strlen(name) + strlen(value) + 2; /* length of 'name=value\0' */
1580
 
    }
1581
 
    smpd_exit_fn(FCNAME);
1582
 
    return size;
1583
 
}
1584
 
 
1585
 
#undef FCNAME
1586
 
#define FCNAME "add_environment_variables"
1587
 
static void add_environment_variables(char *str, char **vars, char *bEnv)
1588
 
{
1589
 
    char name[1024], equals[3], value[8192];
1590
 
    int i = 0;
1591
 
 
1592
 
    smpd_enter_fn(FCNAME);
1593
 
    while (1)
1594
 
    {
1595
 
        name[0] = '\0';
1596
 
        equals[0] = '\0';
1597
 
        value[0] = '\0';
1598
 
        if (MPIU_Str_get_string(&bEnv, name, 1024) != MPIU_STR_SUCCESS)
1599
 
            break;
1600
 
        if (name[0] == '\0')
1601
 
            break;
1602
 
        if (MPIU_Str_get_string(&bEnv, equals, 3) != MPIU_STR_SUCCESS)
1603
 
            break;
1604
 
        if (equals[0] == '\0')
1605
 
            break;
1606
 
        if (MPIU_Str_get_string(&bEnv, value, 8192) != MPIU_STR_SUCCESS)
1607
 
            break;
1608
 
        vars[i] = str;
1609
 
        str += sprintf(str, "%s=%s", name, value) + 1;
1610
 
        i++;
1611
 
    }
1612
 
    smpd_exit_fn(FCNAME);
1613
 
}
1614
 
#endif
1615
 
 
1616
 
#ifdef USE_PTHREAD_STDIN_REDIRECTION
1617
 
static void child_exited(int signo)
1618
 
{
1619
 
    pid_t pid;
1620
 
    int status;
1621
 
    smpd_process_t *iter;
1622
 
 
1623
 
    /*
1624
 
     * For some reason on the Macs, stdout and stderr are not closed when the
1625
 
     * process exits so we can't use the closing of the redirected stdout and
1626
 
     * stderr sockets as indications that the process has exited.  So this
1627
 
     * signal handler closes the stdout/err redirection socket on a SIGCHLD
1628
 
     * signal to simulate that behavior.
1629
 
     */
1630
 
    if (signo == SIGCHLD)
1631
 
    {
1632
 
        smpd_dbg_printf("SIGCHLD received\n");
1633
 
        for (;;)
1634
 
        {
1635
 
            status = 0;
1636
 
            pid = waitpid(-1, &status, WNOHANG);
1637
 
            if (pid <= 0)
1638
 
                break;
1639
 
 
1640
 
            smpd_dbg_printf("SIGCHILD pid = %d\n", pid);
1641
 
            iter = smpd_process.process_list;
1642
 
            {
1643
 
                while (iter != NULL)
1644
 
                {
1645
 
                    if (iter->wait == pid)
1646
 
                    {
1647
 
                        if (WIFEXITED(status))
1648
 
                        {
1649
 
                            iter->exitcode =  WEXITSTATUS(status);
1650
 
                        }
1651
 
                        else
1652
 
                        {
1653
 
                            iter->exitcode = -123;
1654
 
                        }
1655
 
                        if (iter->out != NULL)
1656
 
                        {
1657
 
                            if (iter->out->read_state == SMPD_READING_STDOUT)
1658
 
                            {
1659
 
                                smpd_dbg_printf("closing stdout redirection\n");
1660
 
                                iter->out->state = SMPD_CLOSING;
1661
 
                                SMPDU_Sock_post_close(iter->out->sock);
1662
 
                            }
1663
 
                            else
1664
 
                            {
1665
 
                                smpd_err_printf("iter->out->read_state = %d\n", iter->out->read_state);
1666
 
                            }
1667
 
                        }
1668
 
                        if (iter->err != NULL)
1669
 
                        {
1670
 
                            if (iter->err->read_state == SMPD_READING_STDERR)
1671
 
                            {
1672
 
                                smpd_dbg_printf("closing stderr redirection\n");
1673
 
                                iter->err->state = SMPD_CLOSING;
1674
 
                                SMPDU_Sock_post_close(iter->err->sock);
1675
 
                            }
1676
 
                            else
1677
 
                            {
1678
 
                                smpd_err_printf("iter->err->read_state = %d\n", iter->err->read_state);
1679
 
                            }
1680
 
                        }
1681
 
                        break;
1682
 
                    }
1683
 
                    iter = iter->next;
1684
 
                }
1685
 
            }
1686
 
        }
1687
 
    }
1688
 
    else
1689
 
    {
1690
 
        smpd_dbg_printf("unexpected signal %d received\n", signo);
1691
 
    }
1692
 
}
1693
 
#endif
1694
 
 
1695
 
#undef FCNAME
1696
 
#define FCNAME "smpd_launch_process"
1697
 
int smpd_launch_process(smpd_process_t *process, int priorityClass, int priority, int dbg, SMPDU_Sock_set_t set)
1698
 
{
1699
 
    int result;
1700
 
    int stdin_pipe_fds[2], stdout_pipe_fds[2];
1701
 
    int  stderr_pipe_fds[2], pmi_pipe_fds[2];
1702
 
    int pid;
1703
 
    SMPDU_Sock_t sock_in, sock_out, sock_err, sock_pmi;
1704
 
    char args[SMPD_MAX_EXE_LENGTH];
1705
 
    char *argv[1024];
1706
 
    char *token;
1707
 
    int i;
1708
 
    char str[1024];
1709
 
    char *str_iter;
1710
 
    int total, num_chars;
1711
 
    char *actual_exe, exe_data[SMPD_MAX_EXE_LENGTH];
1712
 
    char *temp_str;
1713
 
    char temp_exe[SMPD_MAX_EXE_LENGTH];
1714
 
    smpd_command_t *cmd_ptr;
1715
 
    static char *pPutEnv = NULL;
1716
 
    char *pLastEnv, *env_iter;
1717
 
    int env_count, env_size;
1718
 
    char **pEnvArray;
1719
 
 
1720
 
    smpd_enter_fn(FCNAME);
1721
 
 
1722
 
#ifdef USE_PTHREAD_STDIN_REDIRECTION
1723
 
    {
1724
 
        /* On the Macs we must use a signal handler to determine when a process
1725
 
         * has exited.  On all other systems we use the closing of stdout and
1726
 
         * stderr to determine that a process has exited.
1727
 
         */
1728
 
        static int sighandler_setup = 0;
1729
 
        if (!sighandler_setup)
1730
 
        {
1731
 
            smpd_dbg_printf("setting child_exited signal handler\n");
1732
 
            smpd_signal(SIGCHLD, child_exited);
1733
 
            sighandler_setup = 1;
1734
 
        }
1735
 
    }
1736
 
#endif
1737
 
 
1738
 
    /* resolve the executable name */
1739
 
    if (process->path[0] != '\0')
1740
 
    {
1741
 
        temp_str = process->exe;
1742
 
        result = MPIU_Str_get_string(&temp_str, temp_exe, SMPD_MAX_EXE_LENGTH);
1743
 
        if (result != MPIU_STR_SUCCESS)
1744
 
        {
1745
 
        }
1746
 
        smpd_dbg_printf("searching for '%s' in '%s'\n", temp_exe, process->path);
1747
 
        if (smpd_search_path(process->path, temp_exe, SMPD_MAX_EXE_LENGTH, exe_data))
1748
 
        {
1749
 
            smpd_dbg_printf("found: '%s'\n", exe_data);
1750
 
            if (strstr(exe_data, " "))
1751
 
            {
1752
 
                smpd_err_printf("Currently unable to handle paths with spaces in them.\n");
1753
 
            }
1754
 
            if (temp_str != NULL)
1755
 
            {
1756
 
                strncat(exe_data, " ", SMPD_MAX_EXE_LENGTH - strlen(exe_data));
1757
 
                strncat(exe_data, temp_str, SMPD_MAX_EXE_LENGTH - strlen(exe_data));
1758
 
                exe_data[SMPD_MAX_EXE_LENGTH-1] = '\0';
1759
 
            }
1760
 
            actual_exe = exe_data;
1761
 
        }
1762
 
        else
1763
 
        {
1764
 
            actual_exe = process->exe;
1765
 
        }
1766
 
    }
1767
 
    else
1768
 
    {
1769
 
        actual_exe = process->exe;
1770
 
    }
1771
 
    
1772
 
    /* create argv from the command */
1773
 
    i = 0;
1774
 
    total = 0;
1775
 
    /*str_iter = process->exe;*/
1776
 
    str_iter = actual_exe;
1777
 
    while (str_iter && i<1024)
1778
 
    {
1779
 
        result = MPIU_Str_get_string(&str_iter, &args[total],
1780
 
                                   SMPD_MAX_EXE_LENGTH - total);
1781
 
        argv[i] = &args[total];
1782
 
        i++;
1783
 
        total += strlen(&args[total])+1; /* move over the null termination */
1784
 
    }
1785
 
    argv[i] = NULL;
1786
 
 
1787
 
    /* create pipes for redirecting I/O */
1788
 
    /*
1789
 
    pipe(stdin_pipe_fds);
1790
 
    pipe(stdout_pipe_fds);
1791
 
    pipe(stderr_pipe_fds);
1792
 
    */
1793
 
    socketpair(AF_UNIX, SOCK_STREAM, 0, stdin_pipe_fds);
1794
 
    socketpair(AF_UNIX, SOCK_STREAM, 0, stdout_pipe_fds);
1795
 
    socketpair(AF_UNIX, SOCK_STREAM, 0, stderr_pipe_fds);
1796
 
    if (process->pmi != NULL)
1797
 
    {
1798
 
        socketpair(AF_UNIX, SOCK_STREAM, 0, pmi_pipe_fds);
1799
 
    }
1800
 
 
1801
 
    pid = fork();
1802
 
    if (pid < 0)
1803
 
    {
1804
 
        smpd_err_printf("fork failed - error %d.\n", errno);
1805
 
        smpd_exit_fn(FCNAME);
1806
 
        return SMPD_FAIL;
1807
 
    }
1808
 
 
1809
 
    if (pid == 0)
1810
 
    {
1811
 
        /* child process */
1812
 
        smpd_dbg_printf("client is alive and about to exec '%s'\n", argv[0]);
1813
 
 
1814
 
#ifdef HAVE_SETENV
1815
 
        if (process->pmi != NULL)
1816
 
        {
1817
 
            sprintf(str, "%d", process->rank);
1818
 
            smpd_dbg_printf("env: PMI_RANK=%s\n", str);
1819
 
            setenv("PMI_RANK", str, 1);
1820
 
            sprintf(str, "%d", process->nproc);
1821
 
            smpd_dbg_printf("env: PMI_SIZE=%s\n", str);
1822
 
            setenv("PMI_SIZE", str, 1);
1823
 
            sprintf(str, "%s", process->kvs_name);
1824
 
            smpd_dbg_printf("env: PMI_KVS=%s\n", str);
1825
 
            setenv("PMI_KVS", str, 1);
1826
 
            sprintf(str, "%s", process->domain_name);
1827
 
            smpd_dbg_printf("env: PMI_DOMAIN=%s\n", str);
1828
 
            setenv("PMI_DOMAIN", str, 1);
1829
 
            sprintf(str, "%d", pmi_pipe_fds[1]);
1830
 
            smpd_dbg_printf("env: PMI_SMPD_FD=%s\n", str);
1831
 
            setenv("PMI_SMPD_FD", str, 1);
1832
 
            sprintf(str, "%d", smpd_process.id);
1833
 
            smpd_dbg_printf("env: PMI_SMPD_ID=%s\n", str);
1834
 
            setenv("PMI_SMPD_ID", str, 1);
1835
 
            sprintf(str, "%d", process->id);
1836
 
            smpd_dbg_printf("env: PMI_SMPD_KEY=%s\n", str);
1837
 
            setenv("PMI_SMPD_KEY", str, 1);
1838
 
            sprintf(str, "%d", process->spawned);
1839
 
            smpd_dbg_printf("env: PMI_SPAWN=%s\n", str);
1840
 
            setenv("PMI_SPAWN", str, 1);
1841
 
            sprintf(str, "%d", process->appnum);
1842
 
            smpd_dbg_printf("env: PMI_APPNUM=%s\n", str);
1843
 
            setenv("PMI_APPNUM", str, 1);
1844
 
            sprintf(str, "%s", process->clique);
1845
 
            smpd_dbg_printf("env: PMI_CLIQUE=%s\n", str);
1846
 
            setenv("PMI_CLIQUE", str, 1);
1847
 
        }
1848
 
        set_environment_variables(process->env);
1849
 
#else
1850
 
        pLastEnv = pPutEnv;
1851
 
        env_count = 0;
1852
 
        env_size = get_env_size(process->env, &env_count) + 1024;
1853
 
        env_count += 10;
1854
 
        pPutEnv = (char*)MPIU_Malloc(env_size * sizeof(char));
1855
 
        pEnvArray = (char**)MPIU_Malloc(env_count * sizeof(char*));
1856
 
        env_iter = pPutEnv;
1857
 
        pEnvArray[0] = env_iter;
1858
 
        env_iter += sprintf(env_iter, "PMI_RANK=%d", process->rank) + 1;
1859
 
        pEnvArray[1] = env_iter;
1860
 
        env_iter += sprintf(env_iter, "PMI_SIZE=%d", process->nproc) + 1;
1861
 
        pEnvArray[2] = env_iter;
1862
 
        env_iter += sprintf(env_iter, "PMI_KVS=%s", process->kvs_name) + 1;
1863
 
        pEnvArray[3] = env_iter;
1864
 
        env_iter += sprintf(env_iter, "PMI_DOMAIN=%s", process->domain_name) + 1;
1865
 
        pEnvArray[4] = env_iter;
1866
 
        env_iter += sprintf(env_iter, "PMI_SMPD_FD=%d", pmi_pipe_fds[1]) + 1;
1867
 
        pEnvArray[5] = env_iter;
1868
 
        env_iter += sprintf(env_iter, "PMI_SMPD_ID=%d", smpd_process.id) + 1;
1869
 
        pEnvArray[6] = env_iter;
1870
 
        env_iter += sprintf(env_iter, "PMI_SMPD_KEY=%d", process->id) + 1;
1871
 
        pEnvArray[7] = env_iter;
1872
 
        env_iter += sprintf(env_iter, "PMI_SPAWN=%d", process->spawned) + 1;
1873
 
        pEnvArray[8] = env_iter;
1874
 
        env_iter += sprintf(env_iter, "PMI_APPNUM=%d", process->appnum) + 1;
1875
 
        pEnvArray[9] = env_iter;
1876
 
        env_iter += sprintf(env_iter, "PMI_CLIQUE=%s", process->clique) + 1;
1877
 
        add_environment_variables(env_iter, &pEnvArray[10], process->env);
1878
 
        for (i=0; i<env_count; i++)
1879
 
        {
1880
 
            result = putenv(pEnvArray[i]);
1881
 
            if (result != 0)
1882
 
            {
1883
 
                smpd_err_printf("putenv failed: %d\n", errno);
1884
 
            }
1885
 
        }
1886
 
        if (pLastEnv != NULL)
1887
 
            MPIU_Free(pLastEnv);
1888
 
#endif
1889
 
        result = dup2(stdin_pipe_fds[0], 0);   /* dup a new stdin */
1890
 
        if (result == -1)
1891
 
        {
1892
 
            smpd_err_printf("dup2 stdin failed: %d\n", errno);
1893
 
        }
1894
 
        close(stdin_pipe_fds[0]);
1895
 
        close(stdin_pipe_fds[1]);
1896
 
 
1897
 
        result = dup2(stdout_pipe_fds[1], 1);  /* dup a new stdout */
1898
 
        if (result == -1)
1899
 
        {
1900
 
            smpd_err_printf("dup2 stdout failed: %d\n", errno);
1901
 
        }
1902
 
        close(stdout_pipe_fds[0]);
1903
 
        close(stdout_pipe_fds[1]);
1904
 
 
1905
 
        result = dup2(stderr_pipe_fds[1], 2);  /* dup a new stderr */
1906
 
        if (result == -1)
1907
 
        {
1908
 
            smpd_err_printf("dup2 stderr failed: %d\n", errno);
1909
 
        }
1910
 
        close(stderr_pipe_fds[0]);
1911
 
        close(stderr_pipe_fds[1]);
1912
 
 
1913
 
        if (process->pmi != NULL)
1914
 
        {
1915
 
            close(pmi_pipe_fds[0]); /* close the other end */
1916
 
        }
1917
 
 
1918
 
        /* change the working directory */
1919
 
        result = -1;
1920
 
        if (process->dir[0] != '\0')
1921
 
            result = chdir( process->dir );
1922
 
        if (result < 0)
1923
 
            chdir( getenv( "HOME" ) );
1924
 
 
1925
 
        /* reset the file mode creation mask */
1926
 
        umask(0);
1927
 
 
1928
 
        result = execvp( argv[0], argv );
1929
 
 
1930
 
        result = errno;
1931
 
        {
1932
 
            char myhostname[SMPD_MAX_HOST_LENGTH];
1933
 
            smpd_get_hostname(myhostname, SMPD_MAX_HOST_LENGTH);
1934
 
            snprintf(process->err_msg, SMPD_MAX_ERROR_LEN, "Unable to exec '%s' on %s.  Error %d - %s\n", process->exe, myhostname, result, strerror(result));
1935
 
            /*sprintf(process->err_msg, "Error %d - %s", result, strerror(result));*/
1936
 
        }
1937
 
 
1938
 
        if (process->pmi != NULL)
1939
 
        {
1940
 
            /* create the abort command */
1941
 
            result = smpd_create_command("abort", smpd_process.id, 0, SMPD_FALSE, &cmd_ptr);
1942
 
            if (result != SMPD_SUCCESS)
1943
 
            {
1944
 
                smpd_err_printf("unable to create an abort command in response to failed launch command: '%s'\n", process->exe);
1945
 
                exit(-1);
1946
 
            }
1947
 
            /* launch process should provide a reason for the error, for now just return FAIL */
1948
 
            result = smpd_add_command_arg(cmd_ptr, "result", SMPD_FAIL_STR);
1949
 
            if (result != SMPD_SUCCESS)
1950
 
            {
1951
 
                smpd_err_printf("unable to add the result field to the result command in response to launch command: '%s'\n", process->exe);
1952
 
                exit(-1);
1953
 
            }
1954
 
            if (process->err_msg[0] != '\0')
1955
 
            {
1956
 
                result = smpd_add_command_arg(cmd_ptr, "error", process->err_msg);
1957
 
                if (result != SMPD_SUCCESS)
1958
 
                {
1959
 
                    smpd_err_printf("unable to add the error field to the abort command in response to failed launch command: '%s'\n", process->exe);
1960
 
                    exit(-1);
1961
 
                }
1962
 
            }
1963
 
 
1964
 
            /* send the result back */
1965
 
            smpd_package_command(cmd_ptr);
1966
 
            result = write(pmi_pipe_fds[1], cmd_ptr->cmd_hdr_str, SMPD_CMD_HDR_LENGTH);
1967
 
            if (result != SMPD_CMD_HDR_LENGTH)
1968
 
            {
1969
 
                smpd_err_printf("unable to write the abort command header in response to failed launch command: '%s'\n", process->exe);
1970
 
                exit(-1);
1971
 
            }
1972
 
            result = write(pmi_pipe_fds[1], cmd_ptr->cmd, cmd_ptr->length);
1973
 
            if (result != cmd_ptr->length)
1974
 
            {
1975
 
                smpd_err_printf("unable to write the abort command in response to failed launch command: '%s'\n", process->exe);
1976
 
                exit(-1);
1977
 
            }
1978
 
 
1979
 
            /* send a closed message on the pmi socket? */
1980
 
        }
1981
 
 
1982
 
        exit(result);
1983
 
    }
1984
 
 
1985
 
    /* parent process */
1986
 
    process->pid = pid;
1987
 
    close(stdin_pipe_fds[0]);
1988
 
    close(stdout_pipe_fds[1]);
1989
 
    close(stderr_pipe_fds[1]);
1990
 
    if (process->pmi != NULL)
1991
 
    {
1992
 
        close(pmi_pipe_fds[1]);
1993
 
    }
1994
 
 
1995
 
    /* make sock structures out of the sockets */
1996
 
    result = SMPDU_Sock_native_to_sock(set, stdin_pipe_fds[1], NULL, &sock_in);
1997
 
    if (result != SMPD_SUCCESS)
1998
 
    {
1999
 
        smpd_err_printf("SMPDU_Sock_native_to_sock failed, error %s\n", get_sock_error_string(result));
2000
 
    }
2001
 
    result = SMPDU_Sock_native_to_sock(set, stdout_pipe_fds[0], NULL, &sock_out);
2002
 
    if (result != SMPD_SUCCESS)
2003
 
    {
2004
 
        smpd_err_printf("SMPDU_Sock_native_to_sock failed, error %s\n", get_sock_error_string(result));
2005
 
    }
2006
 
    result = SMPDU_Sock_native_to_sock(set, stderr_pipe_fds[0], NULL, &sock_err);
2007
 
    if (result != SMPD_SUCCESS)
2008
 
    {
2009
 
        smpd_err_printf("SMPDU_Sock_native_to_sock failed, error %s\n", get_sock_error_string(result));
2010
 
    }
2011
 
    if (process->pmi != NULL)
2012
 
    {
2013
 
        result = SMPDU_Sock_native_to_sock(set, pmi_pipe_fds[0], NULL, &sock_pmi);
2014
 
        if (result != SMPD_SUCCESS)
2015
 
        {
2016
 
            smpd_err_printf("SMPDU_Sock_native_to_sock failed, error %s\n", get_sock_error_string(result));
2017
 
        }
2018
 
    }
2019
 
    process->in->sock = sock_in;
2020
 
    process->out->sock = sock_out;
2021
 
    process->err->sock = sock_err;
2022
 
    if (process->pmi != NULL)
2023
 
    {
2024
 
        process->pmi->sock = sock_pmi;
2025
 
    }
2026
 
    process->pid = process->in->id = process->out->id = process->err->id = pid;
2027
 
    result = SMPDU_Sock_set_user_ptr(sock_in, process->in);
2028
 
    if (result != SMPD_SUCCESS)
2029
 
    {
2030
 
        smpd_err_printf("SMPDU_Sock_set_user_ptr failed, error %s\n", get_sock_error_string(result));
2031
 
    }
2032
 
    result = SMPDU_Sock_set_user_ptr(sock_out, process->out);
2033
 
    if (result != SMPD_SUCCESS)
2034
 
    {
2035
 
        smpd_err_printf("SMPDU_Sock_set_user_ptr failed, error %s\n", get_sock_error_string(result));
2036
 
    }
2037
 
    result = SMPDU_Sock_set_user_ptr(sock_err, process->err);
2038
 
    if (result != SMPD_SUCCESS)
2039
 
    {
2040
 
        smpd_err_printf("SMPDU_Sock_set_user_ptr failed, error %s\n", get_sock_error_string(result));
2041
 
    }
2042
 
    if (process->pmi != NULL)
2043
 
    {
2044
 
        result = SMPDU_Sock_set_user_ptr(sock_pmi, process->pmi);
2045
 
        if (result != SMPD_SUCCESS)
2046
 
        {
2047
 
            smpd_err_printf("SMPDU_Sock_set_user_ptr failed, error %s\n", get_sock_error_string(result));
2048
 
        }
2049
 
    }
2050
 
 
2051
 
    process->context_refcount = (process->pmi != NULL) ? 3 : 2;
2052
 
    process->out->read_state = SMPD_READING_STDOUT;
2053
 
    result = SMPDU_Sock_post_read(sock_out, process->out->read_cmd.cmd, 1, 1, NULL);
2054
 
    if (result != SMPD_SUCCESS)
2055
 
    {
2056
 
        smpd_err_printf("posting first read from stdout context failed, sock error: %s\n",
2057
 
            get_sock_error_string(result));
2058
 
        smpd_exit_fn(FCNAME);
2059
 
        return SMPD_FAIL;
2060
 
    }
2061
 
    process->err->read_state = SMPD_READING_STDERR;
2062
 
    result = SMPDU_Sock_post_read(sock_err, process->err->read_cmd.cmd, 1, 1, NULL);
2063
 
    if (result != SMPD_SUCCESS)
2064
 
    {
2065
 
        smpd_err_printf("posting first read from stderr context failed, sock error: %s\n",
2066
 
            get_sock_error_string(result));
2067
 
        smpd_exit_fn(FCNAME);
2068
 
        return SMPD_FAIL;
2069
 
    }
2070
 
    if (process->pmi != NULL)
2071
 
    {
2072
 
        result = smpd_post_read_command(process->pmi);
2073
 
        if (result != SMPD_SUCCESS)
2074
 
        {
2075
 
            smpd_err_printf("unable to post a read of the first command on the pmi control context.\n");
2076
 
            smpd_exit_fn(FCNAME);
2077
 
            return SMPD_FAIL;
2078
 
        }
2079
 
    }
2080
 
    process->wait = process->in->wait = process->out->wait = process->err->wait = pid;
2081
 
 
2082
 
    smpd_exit_fn(FCNAME);
2083
 
    return SMPD_SUCCESS;
2084
 
}
2085
 
 
2086
 
#endif
2087
 
 
2088
 
#undef FCNAME
2089
 
#define FCNAME "smpd_wait_process"
2090
 
int smpd_wait_process(smpd_pwait_t wait, int *exit_code_ptr)
2091
 
{
2092
 
#ifdef HAVE_WINDOWS_H
2093
 
    int result;
2094
 
    DWORD exit_code;
2095
 
 
2096
 
    smpd_enter_fn(FCNAME);
2097
 
 
2098
 
    if (wait.hProcess == INVALID_HANDLE_VALUE || wait.hProcess == NULL)
2099
 
    {
2100
 
        smpd_dbg_printf("No process to wait for.\n");
2101
 
        *exit_code_ptr = -1;
2102
 
        smpd_exit_fn(FCNAME);
2103
 
        return SMPD_SUCCESS;
2104
 
    }
2105
 
    if (WaitForSingleObject(wait.hProcess, INFINITE) != WAIT_OBJECT_0)
2106
 
    {
2107
 
        smpd_err_printf("WaitForSingleObject failed, error %d\n", GetLastError());
2108
 
        *exit_code_ptr = -1;
2109
 
        smpd_exit_fn(FCNAME);
2110
 
        return SMPD_FAIL;
2111
 
    }
2112
 
    result = GetExitCodeProcess(wait.hProcess, &exit_code);
2113
 
    if (!result)
2114
 
    {
2115
 
        smpd_err_printf("GetExitCodeProcess failed, error %d\n", GetLastError());
2116
 
        *exit_code_ptr = -1;
2117
 
        smpd_exit_fn(FCNAME);
2118
 
        return SMPD_FAIL;
2119
 
    }
2120
 
    CloseHandle(wait.hProcess);
2121
 
    CloseHandle(wait.hThread);
2122
 
 
2123
 
    *exit_code_ptr = exit_code;
2124
 
 
2125
 
    smpd_exit_fn(FCNAME);
2126
 
    return SMPD_SUCCESS;
2127
 
#else
2128
 
    int status;
2129
 
    smpd_pwait_t result;
2130
 
    smpd_enter_fn(FCNAME);
2131
 
 
2132
 
    smpd_dbg_printf("waiting for process %d\n", wait);
2133
 
    result = -1;
2134
 
    while (result == -1)
2135
 
    {
2136
 
        result = waitpid(wait, &status, WUNTRACED);
2137
 
        if (result == -1)
2138
 
        {
2139
 
            switch (errno)
2140
 
            {
2141
 
            case EINTR:
2142
 
                break;
2143
 
            case ECHILD:
2144
 
#ifdef USE_PTHREAD_STDIN_REDIRECTION
2145
 
                /* On the Macs where stdout/err redirection hangs a SIGCHLD 
2146
 
                 * handler has been set up so ignore ECHILD errors.
2147
 
                 */
2148
 
#else
2149
 
                smpd_err_printf("waitpid(%d) returned ECHILD\n", wait);
2150
 
                *exit_code_ptr = -10;
2151
 
#endif
2152
 
                smpd_exit_fn(FCNAME);
2153
 
                return SMPD_SUCCESS;
2154
 
                break;
2155
 
            case EINVAL:
2156
 
                smpd_err_printf("waitpid(%d) returned EINVAL\n", wait);
2157
 
                *exit_code_ptr = -11;
2158
 
                smpd_exit_fn(FCNAME);
2159
 
                return SMPD_SUCCESS;
2160
 
                break;
2161
 
            default:
2162
 
                smpd_err_printf("waitpid(%d) returned %d\n", wait, errno);
2163
 
                *exit_code_ptr = -12;
2164
 
                smpd_exit_fn(FCNAME);
2165
 
                return SMPD_SUCCESS;
2166
 
                break;
2167
 
            }
2168
 
        }
2169
 
    }
2170
 
    if (WIFEXITED(status))
2171
 
    {
2172
 
        *exit_code_ptr =  WEXITSTATUS(status);
2173
 
    }
2174
 
    else
2175
 
    {
2176
 
        smpd_err_printf("WIFEXITED(%d) failed, setting exit code to -1\n", wait);
2177
 
        *exit_code_ptr = -1;
2178
 
        if (WIFSIGNALED(status))
2179
 
        {
2180
 
            *exit_code_ptr = -2;
2181
 
        }
2182
 
        if (WIFSTOPPED(status))
2183
 
        {
2184
 
            *exit_code_ptr = -3;
2185
 
        }
2186
 
#ifdef WCOREDUMP
2187
 
        if (WCOREDUMP(status))
2188
 
        {
2189
 
            *exit_code_ptr = -4;
2190
 
        }
2191
 
#endif
2192
 
    }
2193
 
 
2194
 
    smpd_exit_fn(FCNAME);
2195
 
    return SMPD_SUCCESS;
2196
 
#endif
2197
 
}
2198
 
 
2199
 
#define SMPD_MAX_SUSPEND_RETRY_COUNT 4
2200
 
 
2201
 
#undef FCNAME
2202
 
#define FCNAME "smpd_suspend_process"
2203
 
int smpd_suspend_process(smpd_process_t *process)
2204
 
{
2205
 
#ifdef HAVE_WINDOWS_H
2206
 
    int result = SMPD_SUCCESS;
2207
 
    int retry_cnt = 0;
2208
 
    smpd_enter_fn(FCNAME);
2209
 
 
2210
 
    do{
2211
 
        if (SuspendThread(process->wait.hThread) == -1){
2212
 
            int exit_code;
2213
 
 
2214
 
            /* Check if the thread is still active */
2215
 
            if(!GetExitCodeThread(process->wait.hThread, &exit_code)){
2216
 
                smpd_err_printf("Getting exit code for thread failed\n");
2217
 
                break;
2218
 
            }
2219
 
            else{
2220
 
                if(exit_code != STILL_ACTIVE){
2221
 
                    smpd_err_printf("The thread to be suspended is no longer active, exit_code = %d\n", exit_code);
2222
 
                    break;
2223
 
                }
2224
 
                else{
2225
 
                    smpd_err_printf("The thread is active but cannot be suspended\n");
2226
 
                }
2227
 
            }
2228
 
 
2229
 
                result = GetLastError();
2230
 
                smpd_err_printf("SuspendThread failed[%d times] with error %d for process %d:%s:'%s'\n",
2231
 
                    retry_cnt, result, process->rank, process->kvs_name, process->exe);
2232
 
        }
2233
 
        else{
2234
 
            break;
2235
 
        }
2236
 
 
2237
 
        /* Ignore error and proceed if we fail to suspend */
2238
 
        result = SMPD_SUCCESS;
2239
 
        retry_cnt++;
2240
 
    }while(retry_cnt < SMPD_MAX_SUSPEND_RETRY_COUNT);
2241
 
 
2242
 
    smpd_exit_fn(FCNAME);
2243
 
    /* Ignore error */
2244
 
    return SMPD_SUCCESS;
2245
 
#else
2246
 
    smpd_enter_fn(FCNAME);
2247
 
 
2248
 
    smpd_dbg_printf("stopping process %d\n", process->wait);
2249
 
    kill(process->wait, SIGSTOP);
2250
 
 
2251
 
    smpd_exit_fn(FCNAME);
2252
 
    return SMPD_SUCCESS;
2253
 
#endif
2254
 
}
2255
 
 
2256
 
#ifdef HAVE_WINDOWS_H
2257
 
static BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode)
2258
 
{
2259
 
    DWORD dwTID, dwCode, dwErr = 0;
2260
 
    HANDLE hProcessDup = INVALID_HANDLE_VALUE;
2261
 
    HANDLE hRT = NULL;
2262
 
    HINSTANCE hKernel = GetModuleHandle("Kernel32");
2263
 
    BOOL bSuccess = FALSE;
2264
 
 
2265
 
    BOOL bDup = DuplicateHandle(GetCurrentProcess(),
2266
 
        hProcess,
2267
 
        GetCurrentProcess(),
2268
 
        &hProcessDup,
2269
 
        PROCESS_ALL_ACCESS,
2270
 
        FALSE,
2271
 
        0);
2272
 
 
2273
 
    if (GetExitCodeProcess((bDup) ? hProcessDup : hProcess, &dwCode) &&
2274
 
        (dwCode == STILL_ACTIVE))
2275
 
    {
2276
 
        FARPROC pfnExitProc;
2277
 
 
2278
 
        pfnExitProc = GetProcAddress(hKernel, "ExitProcess");
2279
 
 
2280
 
        if (pfnExitProc)
2281
 
        {
2282
 
            hRT = CreateRemoteThread((bDup) ? hProcessDup : hProcess,
2283
 
                NULL,
2284
 
                0,
2285
 
                /*
2286
 
                This relies on the probability that Kernel32.dll is mapped to the same place on all processes
2287
 
                If it gets relocated, this function will produce spurious results
2288
 
                */
2289
 
                (LPTHREAD_START_ROUTINE)pfnExitProc,
2290
 
                UintToPtr(uExitCode)/*(LPVOID)uExitCode*/, 0, &dwTID);
2291
 
        }
2292
 
        
2293
 
        if (hRT == NULL)
2294
 
            dwErr = GetLastError();
2295
 
    }
2296
 
    else
2297
 
    {
2298
 
        dwErr = ERROR_PROCESS_ABORTED;
2299
 
    }
2300
 
 
2301
 
    if (hRT)
2302
 
    {
2303
 
        if (WaitForSingleObject((bDup) ? hProcessDup : hProcess, 30000) == WAIT_OBJECT_0)
2304
 
            bSuccess = TRUE;
2305
 
        else
2306
 
        {
2307
 
            dwErr = ERROR_TIMEOUT;
2308
 
            bSuccess = FALSE;
2309
 
        }
2310
 
        CloseHandle(hRT);
2311
 
    }
2312
 
 
2313
 
    if (bDup)
2314
 
        CloseHandle(hProcessDup);
2315
 
 
2316
 
    if (!bSuccess)
2317
 
        SetLastError(dwErr);
2318
 
 
2319
 
    return bSuccess;
2320
 
}
2321
 
#endif
2322
 
 
2323
 
#undef FCNAME
2324
 
#define FCNAME "smpd_kill_process"
2325
 
int smpd_kill_process(smpd_process_t *process, int exit_code)
2326
 
{
2327
 
    int result = SMPD_SUCCESS;
2328
 
#ifdef HAVE_WINDOWS_H
2329
 
    smpd_enter_fn(FCNAME);
2330
 
 
2331
 
    smpd_process_from_registry(process);
2332
 
    if (!SafeTerminateProcess(process->wait.hProcess, exit_code)){
2333
 
        smpd_err_printf("unable terminate process safely. exit_code = %d\n", exit_code);
2334
 
            if (GetLastError() != ERROR_PROCESS_ABORTED){
2335
 
            if(!TerminateProcess(process->wait.hProcess, exit_code)){
2336
 
                if (GetLastError() != ERROR_PROCESS_ABORTED){
2337
 
                    result = SMPD_FAIL;
2338
 
                }
2339
 
            }
2340
 
            }
2341
 
    }
2342
 
    smpd_exit_fn(FCNAME);
2343
 
    return result;
2344
 
#else
2345
 
    int status;
2346
 
    smpd_enter_fn(FCNAME);
2347
 
 
2348
 
    smpd_dbg_printf("killing process %d\n", process->wait);
2349
 
    if(kill(process->wait, /*SIGTERM*/SIGKILL) == -1){
2350
 
        smpd_exit_fn(FCNAME);
2351
 
        return SMPD_FAIL;
2352
 
    }
2353
 
    smpd_exit_fn(FCNAME);
2354
 
    return SMPD_SUCCESS;
2355
 
#endif
2356
 
}
2357
 
 
2358
 
#undef FCNAME
2359
 
#define FCNAME "smpd_kill_all_processes"
2360
 
int smpd_kill_all_processes(void)
2361
 
{
2362
 
    smpd_process_t *iter;
2363
 
 
2364
 
    smpd_enter_fn(FCNAME);
2365
 
 
2366
 
    if (smpd_process.local_root)
2367
 
    {
2368
 
        /* the mpiexec process should not kill the smpd manager that it created for the -localroot option */
2369
 
        smpd_exit_fn(FCNAME);
2370
 
        return SMPD_SUCCESS;
2371
 
    }
2372
 
 
2373
 
    if (smpd_process.rsh_mpiexec)
2374
 
    {
2375
 
        int i;
2376
 
        int count = 0;
2377
 
        iter = smpd_process.process_list;
2378
 
        while (iter)
2379
 
        {
2380
 
            count++;
2381
 
            iter = iter->next;
2382
 
        }
2383
 
        if (count > 0)
2384
 
        {
2385
 
            smpd_pwait_t *wait_array;
2386
 
            wait_array = (smpd_pwait_t*)MPIU_Malloc(sizeof(smpd_pwait_t) * count);
2387
 
            for (i=0, iter = smpd_process.process_list; i<count; i++)
2388
 
            {
2389
 
                wait_array[i] = iter->wait;
2390
 
                iter = iter->next;
2391
 
            }
2392
 
            for (i=0; i<count; i++)
2393
 
            {
2394
 
#ifdef HAVE_WINDOWS_H
2395
 
                if (!SafeTerminateProcess(wait_array[i].hProcess, 123))
2396
 
                {
2397
 
                    if (GetLastError() != ERROR_PROCESS_ABORTED)
2398
 
                    {
2399
 
                        TerminateProcess(wait_array[i].hProcess, 255);
2400
 
                    }
2401
 
                }
2402
 
#else
2403
 
                kill(wait_array[i], /*SIGTERM*/SIGKILL);
2404
 
#endif
2405
 
            }
2406
 
        }
2407
 
    }
2408
 
    else
2409
 
    {
2410
 
        iter = smpd_process.process_list;
2411
 
        while (iter)
2412
 
        {
2413
 
#ifdef HAVE_WINDOWS_H
2414
 
            /*DWORD dwProcessId;*/
2415
 
            smpd_process_from_registry(iter);
2416
 
            /* For some reason break signals don't work on processes created by smpd_launch_process
2417
 
            printf("ctrl-c process: %s\n", iter->exe);fflush(stdout);
2418
 
            dwProcessId = GetProcessId(iter->wait.hProcess);
2419
 
            GenerateConsoleCtrlEvent(CTRL_C_EVENT, dwProcessId);
2420
 
            if (WaitForSingleObject(iter->wait.hProcess, 1000) != WAIT_OBJECT_0)
2421
 
            {
2422
 
            printf("breaking process: %s\n", iter->exe);fflush(stdout);
2423
 
            GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, dwProcessId);
2424
 
            if (WaitForSingleObject(iter->wait.hProcess, 1000) != WAIT_OBJECT_0)
2425
 
            {
2426
 
            */
2427
 
            if (!SafeTerminateProcess(iter->wait.hProcess, 123))
2428
 
            {
2429
 
                if (GetLastError() != ERROR_PROCESS_ABORTED)
2430
 
                {
2431
 
                    TerminateProcess(iter->wait.hProcess, 255);
2432
 
                }
2433
 
            }
2434
 
            /*
2435
 
            }
2436
 
            }
2437
 
            */
2438
 
#else
2439
 
            kill(iter->wait, /*SIGTERM*/SIGKILL);
2440
 
#endif
2441
 
            iter = iter->next;
2442
 
        }
2443
 
    }
2444
 
 
2445
 
    smpd_exit_fn(FCNAME);
2446
 
    return SMPD_SUCCESS;
2447
 
}
2448
 
 
2449
 
#undef FCNAME
2450
 
#define FCNAME "smpd_exit"
2451
 
int smpd_exit(int exitcode)
2452
 
{
2453
 
    smpd_enter_fn(FCNAME);
2454
 
    smpd_kill_all_processes();
2455
 
#ifdef HAVE_WINDOWS_H
2456
 
    smpd_finalize_drive_maps();
2457
 
#endif
2458
 
    smpd_finalize_printf();
2459
 
    PMPI_Finalize();
2460
 
    /* If we're exiting due to a user abort, use the exit code supplied by the abort call */
2461
 
    if (smpd_process.use_abort_exit_code)
2462
 
        exitcode = smpd_process.abort_exit_code;
2463
 
#ifdef HAVE_WINDOWS_H
2464
 
    if (smpd_process.hCloseStdinThreadEvent)
2465
 
    {
2466
 
        CloseHandle(smpd_process.hCloseStdinThreadEvent);
2467
 
    }
2468
 
    /* This is necessary because exit() can deadlock flushing file buffers while the stdin thread is running */
2469
 
    ExitProcess(exitcode);
2470
 
#else
2471
 
    exit(exitcode);
2472
 
    smpd_exit_fn(FCNAME);
2473
 
    return SMPD_FAIL;
2474
 
#endif
2475
 
}