1
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
3
* (C) 2001 by Argonne National Laboratory.
4
* See COPYRIGHT in top-level directory.
7
#ifdef HAVE_SYS_TYPES_H
10
#ifdef HAVE_SYS_SOCKET_H
11
#include <sys/socket.h>
13
#ifdef HAVE_SYS_STAT_H
14
/* This is needed for umask */
30
#define MAX_ERROR_LENGTH 512
33
#define FCNAME "smpd_clear_process_registry"
34
int smpd_clear_process_registry()
39
DWORD dwNumSubKeys, dwMaxSubKeyLen;
41
char err_msg[MAX_ERROR_LENGTH] = "";
43
smpd_enter_fn(FCNAME);
45
result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SMPD_REGISTRY_KEY "\\process", 0, KEY_ALL_ACCESS, &tkey);
46
if (result != ERROR_SUCCESS)
48
if (result != ERROR_PATH_NOT_FOUND)
50
smpd_err_printf("Unable to open the " SMPD_REGISTRY_KEY "\\process registry key, error %d\n", result);
57
result = RegQueryInfoKey(tkey, NULL, NULL, NULL, &dwNumSubKeys, &dwMaxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL);
58
if (result != ERROR_SUCCESS)
64
if (dwMaxSubKeyLen > 256)
66
smpd_err_printf("Error: Invalid process subkeys, max length is too large: %d\n", dwMaxSubKeyLen);
71
if (dwNumSubKeys == 0)
73
result = RegCloseKey(tkey);
74
if (result != ERROR_SUCCESS)
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);
81
result = RegDeleteKey(HKEY_LOCAL_MACHINE, SMPD_REGISTRY_KEY "\\process");
82
if (result != ERROR_SUCCESS)
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);
92
/* count backwards so keys can be removed */
93
for (i=dwNumSubKeys-1; i>=0; i--)
96
result = RegEnumKeyEx(tkey, i, pid_str, &dwLen, NULL, NULL, NULL, NULL);
97
if (result != ERROR_SUCCESS)
99
smpd_err_printf("Error: Unable to enumerate the %d subkey in the " SMPD_REGISTRY_KEY "\\process registry key\n", i);
101
smpd_exit_fn(FCNAME);
104
result = RegDeleteKey(tkey, pid_str);
105
if (result != ERROR_SUCCESS)
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);
113
result = RegCloseKey(tkey);
114
if (result != ERROR_SUCCESS)
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);
121
result = RegDeleteKey(HKEY_LOCAL_MACHINE, SMPD_REGISTRY_KEY "\\process");
122
if (result != ERROR_SUCCESS)
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);
129
smpd_exit_fn(FCNAME);
134
#define FCNAME "smpd_validate_process_registry"
135
int smpd_validate_process_registry()
141
DWORD dwNumSubKeys, dwMaxSubKeyLen;
145
char err_msg[MAX_ERROR_LENGTH] = "";
147
smpd_enter_fn(FCNAME);
149
result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SMPD_REGISTRY_KEY "\\process", 0, KEY_ALL_ACCESS, &tkey);
150
if (result != ERROR_SUCCESS)
152
if (result != ERROR_PATH_NOT_FOUND)
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);
162
result = RegQueryInfoKey(tkey, NULL, NULL, NULL, &dwNumSubKeys, &dwMaxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL);
163
if (result != ERROR_SUCCESS)
166
smpd_exit_fn(FCNAME);
169
if (dwMaxSubKeyLen > 100)
171
smpd_err_printf("Error: Invalid process subkeys, max length is too large: %d\n", dwMaxSubKeyLen);
173
smpd_exit_fn(FCNAME);
176
if (dwNumSubKeys == 0)
179
smpd_exit_fn(FCNAME);
182
/* count backwards so keys can be removed */
183
for (i=dwNumSubKeys-1; i>=0; i--)
186
result = RegEnumKeyEx(tkey, i, pid_str, &dwLen, NULL, NULL, NULL, NULL);
187
if (result != ERROR_SUCCESS)
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);
192
smpd_exit_fn(FCNAME);
196
printf("pid = %d\n", pid);fflush(stdout);
197
hTemp = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
200
error = GetLastError();
201
if (error == ERROR_INVALID_PARAMETER)
203
RegDeleteKey(tkey, pid_str);
208
printf("error = %d\n", error);
217
result = RegCloseKey(tkey);
218
if (result != ERROR_SUCCESS)
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);
225
smpd_exit_fn(FCNAME);
230
#define FCNAME "smpd_process_to_registry"
231
int smpd_process_to_registry(smpd_process_t *process, char *actual_exe)
236
char err_msg[MAX_ERROR_LENGTH] = "";
238
smpd_enter_fn(FCNAME);
242
smpd_dbg_printf("NULL process passed to smpd_process_to_registry.\n");
246
len = snprintf(name, 1024, SMPD_REGISTRY_KEY "\\process\\%d", process->pid);
247
if (len < 0 || len > 1023)
249
smpd_dbg_printf("unable to create a string of the registry key.\n");
253
result = RegCreateKeyEx(HKEY_LOCAL_MACHINE, name,
254
0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &tkey, NULL);
255
if (result != ERROR_SUCCESS)
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);
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)
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);
270
smpd_exit_fn(FCNAME);
274
result = RegCloseKey(tkey);
275
if (result != ERROR_SUCCESS)
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);
282
smpd_exit_fn(FCNAME);
287
#define FCNAME "smpd_process_from_registry"
288
int smpd_process_from_registry(smpd_process_t *process)
292
char err_msg[MAX_ERROR_LENGTH] = "";
294
smpd_enter_fn(FCNAME);
298
smpd_exit_fn(FCNAME);
302
len = snprintf(name, 1024, SMPD_REGISTRY_KEY "\\process\\%d", process->pid);
303
if (len < 0 || len > 1023)
305
smpd_exit_fn(FCNAME);
309
result = RegDeleteKey(HKEY_LOCAL_MACHINE, name);
310
if (result != ERROR_SUCCESS)
312
if (result == ERROR_FILE_NOT_FOUND || result == ERROR_PATH_NOT_FOUND)
314
/* Key already deleted, return success */
315
smpd_exit_fn(FCNAME);
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);
324
smpd_exit_fn(FCNAME);
329
#define FCNAME "smpd_get_user_handle"
330
int smpd_get_user_handle(char *account, char *domain, char *password, HANDLE *handle_ptr)
336
smpd_enter_fn(FCNAME);
340
smpd_dbg_printf("LogonUser(%s\\%s)\n", domain, account);
344
smpd_dbg_printf("LogonUser(%s)\n", account);
352
LOGON32_LOGON_INTERACTIVE,
353
LOGON32_PROVIDER_DEFAULT,
356
error = GetLastError();
357
if (error == ERROR_NO_LOGON_SERVERS)
363
*handle_ptr = INVALID_HANDLE_VALUE;
364
smpd_exit_fn(FCNAME);
371
*handle_ptr = INVALID_HANDLE_VALUE;
372
smpd_exit_fn(FCNAME);
378
smpd_exit_fn(FCNAME);
383
#define FCNAME "smpd_get_user_name"
384
int smpd_get_user_name(char *account, char *domain, char *full_domain)
387
char name[SMPD_MAX_ACCOUNT_LENGTH];
394
if (full_domain != NULL)
398
if (GetUserNameEx(NameSamCompatible, name, &len))
400
for (i=0; i<strlen(name); i++)
402
name[i] = (char)(tolower(name[i]));
404
separator = strchr(name, '\\');
411
strcpy(domain, name);
412
strcpy(account, separator);
415
if (full_domain != NULL)
418
if (GetUserNameEx(NameDnsDomain, name, &len))
420
for (i=0; i<strlen(name); i++)
422
name[i] = (char)(tolower(name[i]));
424
separator = strchr(name, '\\');
428
strcpy(full_domain, name);
433
smpd_exit_fn(FCNAME);
438
#define FCNAME "SetEnvironmentVariables"
439
static void SetEnvironmentVariables(char *bEnv)
441
char name[SMPD_MAX_ENV_LENGTH], equals[3], value[SMPD_MAX_ENV_LENGTH];
443
smpd_enter_fn(FCNAME);
449
if (MPIU_Str_get_string(&bEnv, name, SMPD_MAX_ENV_LENGTH) != MPIU_STR_SUCCESS)
453
if (MPIU_Str_get_string(&bEnv, equals, 3) != MPIU_STR_SUCCESS)
455
if (equals[0] == '\0')
457
if (MPIU_Str_get_string(&bEnv, value, SMPD_MAX_ENV_LENGTH) != MPIU_STR_SUCCESS)
459
smpd_dbg_printf("setting environment variable: <%s> = <%s>\n", name, value);
460
SetEnvironmentVariable(name, value);
462
smpd_exit_fn(FCNAME);
466
#define FCNAME "RemoveEnvironmentVariables"
467
static void RemoveEnvironmentVariables(char *bEnv)
469
char name[SMPD_MAX_ENV_LENGTH], equals[3], value[SMPD_MAX_ENV_LENGTH];
471
smpd_enter_fn(FCNAME);
477
if (MPIU_Str_get_string(&bEnv, name, SMPD_MAX_ENV_LENGTH) != MPIU_STR_SUCCESS)
481
if (MPIU_Str_get_string(&bEnv, equals, 3) != MPIU_STR_SUCCESS)
483
if (equals[0] == '\0')
485
if (MPIU_Str_get_string(&bEnv, value, SMPD_MAX_ENV_LENGTH) != MPIU_STR_SUCCESS)
487
/*smpd_dbg_printf("removing environment variable <%s>\n", name);*/
488
SetEnvironmentVariable(name, NULL);
490
smpd_exit_fn(FCNAME);
494
#define FCNAME "smpd_priority_class_to_win_class"
495
int smpd_priority_class_to_win_class(int *priorityClass)
497
smpd_enter_fn(FCNAME);
498
switch (*priorityClass)
501
*priorityClass = IDLE_PRIORITY_CLASS;
504
*priorityClass = BELOW_NORMAL_PRIORITY_CLASS;
507
*priorityClass = NORMAL_PRIORITY_CLASS;
510
*priorityClass = ABOVE_NORMAL_PRIORITY_CLASS;
513
*priorityClass = HIGH_PRIORITY_CLASS;
516
*priorityClass = NORMAL_PRIORITY_CLASS;
519
smpd_exit_fn(FCNAME);
524
#define FCNAME "smpd_priority_to_win_priority"
525
int smpd_priority_to_win_priority(int *priority)
527
smpd_enter_fn(FCNAME);
531
*priority = THREAD_PRIORITY_IDLE;
534
*priority = THREAD_PRIORITY_LOWEST;
537
*priority = THREAD_PRIORITY_BELOW_NORMAL;
540
*priority = THREAD_PRIORITY_NORMAL;
543
*priority = THREAD_PRIORITY_ABOVE_NORMAL;
546
*priority = THREAD_PRIORITY_HIGHEST;
549
*priority = THREAD_PRIORITY_NORMAL;
552
smpd_exit_fn(FCNAME);
558
typedef struct smpd_piothread_arg_t
563
} smpd_piothread_arg_t;
565
typedef struct smpd_pinthread_arg_t
570
} smpd_pinthread_arg_t;
573
#define FCNAME "smpd_easy_send"
574
static int smpd_easy_send(SOCKET sock, char *buffer, int length)
577
int num_sent, num_left;
579
smpd_exit_fn(FCNAME);
583
while ((num_sent = send(sock, buffer, num_left, 0)) == SOCKET_ERROR)
585
error = WSAGetLastError();
586
if (error == WSAEWOULDBLOCK)
591
if (error == WSAENOBUFS)
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)
596
smpd_exit_fn(FCNAME);
599
if (smpd_easy_send(sock, buffer+(num_left/2), num_left - (num_left/2)) == SOCKET_ERROR)
601
smpd_exit_fn(FCNAME);
604
smpd_exit_fn(FCNAME);
607
WSASetLastError(error);
608
smpd_exit_fn(FCNAME);
611
num_left = num_left - num_sent;
612
buffer = buffer + num_sent;
614
smpd_exit_fn(FCNAME);
618
int smpd_piothread(smpd_piothread_arg_t *p)
635
smpd_dbg_printf("*** entering smpd_piothread pid:%d sock:%d ***\n", pid, hOut);
639
if (!ReadFile(hIn, buffer, 8192, &num_read, NULL))
641
error = GetLastError();
642
/* If there was an error but some bytes were read, send those bytes before exiting */
645
if (smpd_easy_send(hOut, buffer, num_read) == SOCKET_ERROR)
647
smpd_dbg_printf("smpd_easy_send of %d bytes failed.\n", num_read);
651
smpd_dbg_printf("ReadFile failed, error %d\n", error);
656
smpd_dbg_printf("ReadFile returned %d bytes\n", num_read);
659
/*smpd_dbg_printf("*** smpd_piothread read %d bytes ***\n", num_read);*/
660
if (smpd_easy_send(hOut, buffer, num_read) == SOCKET_ERROR)
662
smpd_dbg_printf("smpd_easy_send of %d bytes failed.\n", num_read);
665
/*smpd_dbg_printf("*** smpd_piothread wrote %d bytes ***\n", num_read);*/
667
smpd_dbg_printf("*** smpd_piothread finishing pid:%d ***\n", pid);
669
FlushFileBuffers((HANDLE)hOut);
670
if (shutdown(hOut, SD_BOTH) == SOCKET_ERROR)
672
smpd_err_printf("shutdown failed, sock %d, error %d\n", hOut, WSAGetLastError());
674
if (closesocket(hOut) == SOCKET_ERROR)
676
smpd_err_printf("closesocket failed, sock %d, error %d\n", hOut, WSAGetLastError());
679
if (shutdown(hOut, SD_SEND) == SOCKET_ERROR)
681
smpd_err_printf("shutdown failed, sock %d, error %d\n", hOut, WSAGetLastError());
684
recv(hOut, &bogus_char, 1, 0);
685
if (closesocket(hOut) == SOCKET_ERROR)
687
smpd_err_printf("closesocket failed, sock %d, error %d\n", hOut, WSAGetLastError());
690
smpd_dbg_printf("closing output socket took %.3f seconds\n", t2-t1);
692
/*smpd_dbg_printf("*** exiting smpd_piothread ***\n");*/
696
/* one line at a time version */
697
int smpd_pinthread(smpd_pinthread_arg_t *p)
699
char str [SMPD_MAX_CMD_LENGTH];
718
smpd_dbg_printf("*** entering smpd_pinthread pid:%d sock:%d ***\n", pid, hIn);
722
num_read = recv(hIn, &str[index], 1, 0);
723
if (num_read == SOCKET_ERROR || num_read == 0)
725
if (num_read == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK)
727
u_long optval = (u_long)TRUE;
728
ioctlsocket(hIn, FIONBIO, &optval);
733
/* write any buffered data before exiting */
734
if (!WriteFile(hOut, str, index, &num_written, NULL))
736
smpd_dbg_printf("WriteFile failed, error %d\n", GetLastError());
742
smpd_dbg_printf("recv from stdin socket failed, error %d.\n", WSAGetLastError());
746
if (str[index] == '\n' || index == SMPD_MAX_CMD_LENGTH-1)
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))
751
smpd_dbg_printf("WriteFile failed, error %d\n", GetLastError());
755
smpd_dbg_printf("wrote: ");
756
for (i=0; i<=index; i++)
758
smpd_dbg_printf("(%d)'%c'", (int)str[i], str[i]);
760
smpd_dbg_printf("\n");
766
smpd_dbg_printf("read character(%d)'%c'\n", (int)str[index], str[index]);
770
smpd_dbg_printf("*** smpd_pinthread finishing pid:%d ***\n", pid);
771
FlushFileBuffers(hOut);
772
if (shutdown(hIn, SD_BOTH) == SOCKET_ERROR)
774
smpd_err_printf("shutdown failed, sock %d, error %d\n", hIn, WSAGetLastError());
776
if (closesocket(hIn) == SOCKET_ERROR)
778
smpd_err_printf("closesocket failed, sock %d, error %d\n", hIn, WSAGetLastError());
781
if (shutdown(hIn, SD_SEND) == SOCKET_ERROR)
783
smpd_err_printf("shutdown failed, sock %d, error %d\n", hIn, WSAGetLastError());
786
recv(hIn, &bogus_char, 1, 0);
787
if (closesocket(hIn) == SOCKET_ERROR)
789
smpd_err_printf("closesocket failed, sock %d, error %d\n", hIn, WSAGetLastError());
792
smpd_dbg_printf("closing input socket took %.3f seconds\n", t2-t1);
795
/*smpd_dbg_printf("*** exiting smpd_pinthread ***\n");*/
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)
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;
813
PROCESS_INFORMATION psInfo = { 0 };
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];
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] = "";
832
smpd_enter_fn(FCNAME);
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;
837
/* resolve the executable name */
838
if (process->path[0] != '\0')
841
result = MPIU_Str_get_string(&args, temp_exe, SMPD_MAX_EXE_LENGTH);
842
if (result != MPIU_STR_SUCCESS)
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))
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';
854
actual_exe = exe_data;
858
actual_exe = process->exe;
863
actual_exe = process->exe;
866
smpd_priority_class_to_win_class(&priorityClass);
867
smpd_priority_to_win_priority(&priority);
869
/* Save stdin, stdout, and stderr */
870
result = WaitForSingleObject(smpd_process.hLaunchProcessMutex, INFINITE);
871
if (result == WAIT_FAILED)
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);
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)
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);
892
/* Create sockets for stdin, stdout, and stderr */
893
nError = smpd_make_socket_loop_choose(&hSockStdinR, SMPD_FALSE, &hSockStdinW, SMPD_TRUE);
896
smpd_err_printf("smpd_make_socket_loop failed, error %d\n", nError);
899
nError = smpd_make_socket_loop_choose(&hSockStdoutR, SMPD_TRUE, &hSockStdoutW, SMPD_FALSE);
902
smpd_err_printf("smpd_make_socket_loop failed, error %d\n", nError);
905
nError = smpd_make_socket_loop_choose(&hSockStderrR, SMPD_TRUE, &hSockStderrW, SMPD_FALSE);
908
smpd_err_printf("smpd_make_socket_loop failed, error %d\n", nError);
911
if (process->pmi != NULL)
913
if (smpd_process.use_inherited_handles)
915
nError = smpd_make_socket_loop(&hSockPmiR, &hSockPmiW);
918
smpd_err_printf("smpd_make_socket_loop failed, error %d\n", nError);
924
nError = SMPDU_Sock_listen(set, NULL, &listener_port, &sock_pmi_listener);
925
if (nError != SMPD_SUCCESS)
927
smpd_err_printf("SMPDU_Sock_listen failed,\nsock error: %s\n", get_sock_error_string(nError));
930
smpd_dbg_printf("pmi listening on port %d\n", listener_port);
932
nError = smpd_create_context(SMPD_CONTEXT_PMI_LISTENER, set, sock_pmi_listener, -1, &listener_context);
933
if (nError != SMPD_SUCCESS)
935
smpd_err_printf("unable to create a context for the pmi listener.\n");
938
nError = SMPDU_Sock_set_user_ptr(sock_pmi_listener, listener_context);
939
if (nError != SMPD_SUCCESS)
941
smpd_err_printf("SMPDU_Sock_set_user_ptr failed,\nsock error: %s\n", get_sock_error_string(nError));
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)
949
smpd_err_printf("SMPDU_Sock_get_host_description failed,\nsock error: %s\n", get_sock_error_string(nError));
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;
958
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
959
saAttr.lpSecurityDescriptor = NULL;
960
saAttr.bInheritHandle = TRUE;
962
/* Create the pipes for stdout, stderr */
963
if (!CreatePipe(&hPipeStdinR, &hPipeStdinW, &saAttr, 0))
965
smpd_err_printf("CreatePipe(stdin) failed, error %d\n", GetLastError());
968
if (!CreatePipe(&hPipeStdoutR, &hPipeStdoutW, &saAttr, 0))
970
smpd_err_printf("CreatePipe(stdout) failed, error %d\n", GetLastError());
973
if (!CreatePipe(&hPipeStderrR, &hPipeStderrW, &saAttr, 0))
975
smpd_err_printf("CreatePipe(stderr) failed, error %d\n", GetLastError());
979
/* Make the ends of the pipes that this process will use not inheritable */
981
if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hSockStdinW, GetCurrentProcess(), &hIn,
982
0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
984
nError = GetLastError();
985
smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
989
if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hPipeStdinW, GetCurrentProcess(), &hIn,
990
0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
992
nError = GetLastError();
993
smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
997
if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hSockStdoutR, GetCurrentProcess(), &hOut,
998
0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1000
nError = GetLastError();
1001
smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1004
if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hSockStderrR, GetCurrentProcess(), &hErr,
1005
0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1007
nError = GetLastError();
1008
smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1012
if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hPipeStdoutR, GetCurrentProcess(), &hOut,
1013
0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1015
nError = GetLastError();
1016
smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1019
if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hPipeStderrR, GetCurrentProcess(), &hErr,
1020
0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1022
nError = GetLastError();
1023
smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1026
if (process->pmi != NULL && smpd_process.use_inherited_handles)
1028
if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hSockPmiR, GetCurrentProcess(), (LPHANDLE)&hSockPmiR,
1029
0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1031
nError = GetLastError();
1032
smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
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))
1041
nError = GetLastError();
1042
smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1045
if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hSockStdoutR, GetCurrentProcess(), (LPHANDLE)&hSockStdoutR,
1046
0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1048
nError = GetLastError();
1049
smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1052
if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hSockStderrR, GetCurrentProcess(), (LPHANDLE)&hSockStderrR,
1053
0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1055
nError = GetLastError();
1056
smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1059
if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hSockStdinW, GetCurrentProcess(), (LPHANDLE)&hSockStdinW,
1060
0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1062
nError = GetLastError();
1063
smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1066
if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hSockStdoutW, GetCurrentProcess(), (LPHANDLE)&hSockStdoutW,
1067
0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1069
nError = GetLastError();
1070
smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1073
if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hSockStderrW, GetCurrentProcess(), (LPHANDLE)&hSockStderrW,
1074
0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
1076
nError = GetLastError();
1077
smpd_err_printf("DuplicateHandle failed, error %d\n", nError);
1081
/* make the ends used by the spawned process blocking */
1084
ioctlsocket(hSockStdinR, FIONBIO, &blocking_flag);
1088
ioctlsocket(hSockStdoutW, FIONBIO, &blocking_flag);
1090
ioctlsocket(hSockStderrW, FIONBIO, &blocking_flag);
1093
/* Set stdin, stdout, and stderr to the ends of the pipe the created process will use */
1095
if (!SetStdHandle(STD_INPUT_HANDLE, (HANDLE)hSockStdinR))
1097
nError = GetLastError();
1098
smpd_err_printf("SetStdHandle failed, error %d\n", nError);
1102
if (!SetStdHandle(STD_INPUT_HANDLE, (HANDLE)hPipeStdinR))
1104
nError = GetLastError();
1105
smpd_err_printf("SetStdHandle failed, error %d\n", nError);
1109
if (!SetStdHandle(STD_OUTPUT_HANDLE, (HANDLE)hSockStdoutW))
1111
nError = GetLastError();
1112
smpd_err_printf("SetStdHandle failed, error %d\n", nError);
1113
goto RESTORE_CLEANUP;
1115
if (!SetStdHandle(STD_ERROR_HANDLE, (HANDLE)hSockStderrW))
1117
nError = GetLastError();
1118
smpd_err_printf("SetStdHandle failed, error %d\n", nError);
1119
goto RESTORE_CLEANUP;
1122
if (!SetStdHandle(STD_OUTPUT_HANDLE, (HANDLE)hPipeStdoutW))
1124
nError = GetLastError();
1125
smpd_err_printf("SetStdHandle failed, error %d\n", nError);
1126
goto RESTORE_CLEANUP;
1128
if (!SetStdHandle(STD_ERROR_HANDLE, (HANDLE)hPipeStderrW))
1130
nError = GetLastError();
1131
smpd_err_printf("SetStdHandle failed, error %d\n", nError);
1132
goto RESTORE_CLEANUP;
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;
1141
saInfo.hStdOutput = (HANDLE)hSockStdoutW;
1142
saInfo.hStdError = (HANDLE)hSockStderrW;
1144
saInfo.hStdOutput = (HANDLE)hPipeStdoutW;
1145
saInfo.hStdError = (HANDLE)hPipeStderrW;
1146
saInfo.dwFlags = STARTF_USESTDHANDLES;
1148
SetEnvironmentVariables(process->env);
1149
if (process->pmi != NULL)
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)
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);
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);
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')
1186
sprintf(str, "%s", process->clique);
1187
smpd_dbg_printf("env: PMI_CLIQUE=%s\n", str);
1188
SetEnvironmentVariable("PMI_CLIQUE", str);
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);
1197
pEnv = GetEnvironmentStrings();
1199
GetCurrentDirectory(MAX_PATH, tSavedPath);
1200
SetCurrentDirectory(process->dir);
1203
CREATE_SUSPENDED | /*CREATE_NEW_CONSOLE*/ /*DETACHED_PROCESS*/ CREATE_NO_WINDOW | priorityClass;
1205
launch_flag = launch_flag | DEBUG_PROCESS;
1207
smpd_dbg_printf("CreateProcess(%s)\n", actual_exe);
1208
psInfo.hProcess = INVALID_HANDLE_VALUE;
1218
SetThreadPriority(psInfo.hThread, priority);
1219
process->pid = psInfo.dwProcessId;
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;
1231
#ifdef HAVE_WINDOWS_H
1232
if(smpd_process.set_affinity)
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);
1240
/* Get affinity mask decided by smpd - auto binding */
1241
mask = smpd_get_next_process_affinity_mask();
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);
1250
smpd_dbg_printf("Unable to set process/thread affinity (mask=%lu)\n", mask);
1255
FreeEnvironmentStrings((TCHAR*)pEnv);
1256
SetCurrentDirectory(tSavedPath);
1257
RemoveEnvironmentVariables(process->env);
1258
if (process->pmi != NULL)
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)
1266
SetEnvironmentVariable("PMI_SMPD_FD", NULL);
1270
SetEnvironmentVariable("PMI_HOST", NULL);
1271
SetEnvironmentVariable("PMI_PORT", NULL);
1273
SetEnvironmentVariable("PMI_SMPD_ID", NULL);
1274
SetEnvironmentVariable("PMI_SMPD_KEY", NULL);
1275
SetEnvironmentVariable("PMI_SPAWN", NULL);
1280
/* make sock structures out of the sockets */
1282
nError = SMPDU_Sock_native_to_sock(set, hIn, NULL, &sock_in);
1283
if (nError != SMPD_SUCCESS)
1285
smpd_err_printf("SMPDU_Sock_native_to_sock failed, error %s\n", get_sock_error_string(nError));
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)
1292
smpd_err_printf("SMPDU_Sock_native_to_sock failed, error %s\n", get_sock_error_string(nError));
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)
1298
smpd_err_printf("SMPDU_Sock_native_to_sock failed, error %s\n", get_sock_error_string(nError));
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)
1304
smpd_err_printf("SMPDU_Sock_native_to_sock failed, error %s\n", get_sock_error_string(nError));
1306
if (process->pmi != NULL && smpd_process.use_inherited_handles)
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)
1312
smpd_err_printf("SMPDU_Sock_native_to_sock failed, error %s\n", get_sock_error_string(nError));
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);
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);
1340
/* Restore stdin, stdout, stderr */
1341
SetStdHandle(STD_INPUT_HANDLE, hStdin);
1342
SetStdHandle(STD_OUTPUT_HANDLE, hStdout);
1343
SetStdHandle(STD_ERROR_HANDLE, hStderr);
1346
ReleaseMutex(smpd_process.hLaunchProcessMutex);
1347
/*CloseHandle((HANDLE)hSockStdinR);*/
1348
CloseHandle((HANDLE)hPipeStdinR);
1350
CloseHandle((HANDLE)hSockStdoutW);
1351
CloseHandle((HANDLE)hSockStderrW);
1353
CloseHandle((HANDLE)hPipeStdoutW);
1354
CloseHandle((HANDLE)hPipeStderrW);
1355
if (process->pmi != NULL && smpd_process.use_inherited_handles)
1356
CloseHandle((HANDLE)hSockPmiW);
1358
if (psInfo.hProcess != INVALID_HANDLE_VALUE)
1361
smpd_piothread_arg_t *arg_ptr;
1362
smpd_pinthread_arg_t *in_arg_ptr;
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);
1383
if (process->pmi != NULL && smpd_process.use_inherited_handles)
1384
process->context_refcount = 3;
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)
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);
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)
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);
1405
if (process->pmi != NULL && smpd_process.use_inherited_handles)
1407
result = smpd_post_read_command(process->pmi);
1408
if (result != SMPD_SUCCESS)
1410
smpd_err_printf("unable to post a read of the first command on the pmi control channel.\n");
1411
smpd_exit_fn(FCNAME);
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;
1423
smpd_exit_fn(FCNAME);
1428
#define FCNAME "smpd_parse_account_domain"
1429
void smpd_parse_account_domain(const char *domain_account, char *account, char *domain)
1434
smpd_enter_fn(FCNAME);
1436
if ((strchr(domain_account, '\\') == NULL) && (strchr(domain_account, '@') != NULL))
1438
pCh = domain_account;
1440
while ((*pCh != '@') && (*pCh != '\0'))
1450
strcpy(domain, pCh);
1459
pCh = domain_account;
1461
while ((*pCh != '\\') && (*pCh != '\0'))
1470
strcpy(account, pCh);
1475
strcpy(account, domain_account);
1480
smpd_exit_fn(FCNAME);
1488
static void set_environment_variables(char *bEnv)
1490
char name[1024]="", value[8192]="";
1494
while (*bEnv != '\0')
1507
smpd_dbg_printf("env: %s=%s\n", name, value);
1508
setenv(name, value, 1);
1519
if (name[0] != '\0')
1521
smpd_dbg_printf("env: %s=%s\n", name, value);
1522
setenv(name, value, 1);
1529
#define FCNAME "set_environment_variables"
1530
static void set_environment_variables(char *bEnv)
1532
char name[1024], equals[3], value[8192];
1534
smpd_enter_fn(FCNAME);
1540
if (MPIU_Str_get_string(&bEnv, name, 1024) != MPIU_STR_SUCCESS)
1542
if (name[0] == '\0')
1544
if (MPIU_Str_get_string(&bEnv, equals, 3) != MPIU_STR_SUCCESS)
1546
if (equals[0] == '\0')
1548
if (MPIU_Str_get_string(&bEnv, value, 8192) != MPIU_STR_SUCCESS)
1550
setenv(name, value, 1);
1552
smpd_exit_fn(FCNAME);
1556
#define FCNAME "get_env_size"
1557
static int get_env_size(char *bEnv, int *count)
1559
char name[1024], equals[3], value[8192];
1562
smpd_enter_fn(FCNAME);
1568
if (MPIU_Str_get_string(&bEnv, name, 1024) != MPIU_STR_SUCCESS)
1570
if (name[0] == '\0')
1572
if (MPIU_Str_get_string(&bEnv, equals, 3) != MPIU_STR_SUCCESS)
1574
if (equals[0] == '\0')
1576
if (MPIU_Str_get_string(&bEnv, value, 8192) != MPIU_STR_SUCCESS)
1578
*count = *count + 1;
1579
size = size + strlen(name) + strlen(value) + 2; /* length of 'name=value\0' */
1581
smpd_exit_fn(FCNAME);
1586
#define FCNAME "add_environment_variables"
1587
static void add_environment_variables(char *str, char **vars, char *bEnv)
1589
char name[1024], equals[3], value[8192];
1592
smpd_enter_fn(FCNAME);
1598
if (MPIU_Str_get_string(&bEnv, name, 1024) != MPIU_STR_SUCCESS)
1600
if (name[0] == '\0')
1602
if (MPIU_Str_get_string(&bEnv, equals, 3) != MPIU_STR_SUCCESS)
1604
if (equals[0] == '\0')
1606
if (MPIU_Str_get_string(&bEnv, value, 8192) != MPIU_STR_SUCCESS)
1609
str += sprintf(str, "%s=%s", name, value) + 1;
1612
smpd_exit_fn(FCNAME);
1616
#ifdef USE_PTHREAD_STDIN_REDIRECTION
1617
static void child_exited(int signo)
1621
smpd_process_t *iter;
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.
1630
if (signo == SIGCHLD)
1632
smpd_dbg_printf("SIGCHLD received\n");
1636
pid = waitpid(-1, &status, WNOHANG);
1640
smpd_dbg_printf("SIGCHILD pid = %d\n", pid);
1641
iter = smpd_process.process_list;
1643
while (iter != NULL)
1645
if (iter->wait == pid)
1647
if (WIFEXITED(status))
1649
iter->exitcode = WEXITSTATUS(status);
1653
iter->exitcode = -123;
1655
if (iter->out != NULL)
1657
if (iter->out->read_state == SMPD_READING_STDOUT)
1659
smpd_dbg_printf("closing stdout redirection\n");
1660
iter->out->state = SMPD_CLOSING;
1661
SMPDU_Sock_post_close(iter->out->sock);
1665
smpd_err_printf("iter->out->read_state = %d\n", iter->out->read_state);
1668
if (iter->err != NULL)
1670
if (iter->err->read_state == SMPD_READING_STDERR)
1672
smpd_dbg_printf("closing stderr redirection\n");
1673
iter->err->state = SMPD_CLOSING;
1674
SMPDU_Sock_post_close(iter->err->sock);
1678
smpd_err_printf("iter->err->read_state = %d\n", iter->err->read_state);
1690
smpd_dbg_printf("unexpected signal %d received\n", signo);
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)
1700
int stdin_pipe_fds[2], stdout_pipe_fds[2];
1701
int stderr_pipe_fds[2], pmi_pipe_fds[2];
1703
SMPDU_Sock_t sock_in, sock_out, sock_err, sock_pmi;
1704
char args[SMPD_MAX_EXE_LENGTH];
1710
int total, num_chars;
1711
char *actual_exe, exe_data[SMPD_MAX_EXE_LENGTH];
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;
1720
smpd_enter_fn(FCNAME);
1722
#ifdef USE_PTHREAD_STDIN_REDIRECTION
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.
1728
static int sighandler_setup = 0;
1729
if (!sighandler_setup)
1731
smpd_dbg_printf("setting child_exited signal handler\n");
1732
smpd_signal(SIGCHLD, child_exited);
1733
sighandler_setup = 1;
1738
/* resolve the executable name */
1739
if (process->path[0] != '\0')
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)
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))
1749
smpd_dbg_printf("found: '%s'\n", exe_data);
1750
if (strstr(exe_data, " "))
1752
smpd_err_printf("Currently unable to handle paths with spaces in them.\n");
1754
if (temp_str != NULL)
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';
1760
actual_exe = exe_data;
1764
actual_exe = process->exe;
1769
actual_exe = process->exe;
1772
/* create argv from the command */
1775
/*str_iter = process->exe;*/
1776
str_iter = actual_exe;
1777
while (str_iter && i<1024)
1779
result = MPIU_Str_get_string(&str_iter, &args[total],
1780
SMPD_MAX_EXE_LENGTH - total);
1781
argv[i] = &args[total];
1783
total += strlen(&args[total])+1; /* move over the null termination */
1787
/* create pipes for redirecting I/O */
1789
pipe(stdin_pipe_fds);
1790
pipe(stdout_pipe_fds);
1791
pipe(stderr_pipe_fds);
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)
1798
socketpair(AF_UNIX, SOCK_STREAM, 0, pmi_pipe_fds);
1804
smpd_err_printf("fork failed - error %d.\n", errno);
1805
smpd_exit_fn(FCNAME);
1812
smpd_dbg_printf("client is alive and about to exec '%s'\n", argv[0]);
1815
if (process->pmi != NULL)
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);
1848
set_environment_variables(process->env);
1852
env_size = get_env_size(process->env, &env_count) + 1024;
1854
pPutEnv = (char*)MPIU_Malloc(env_size * sizeof(char));
1855
pEnvArray = (char**)MPIU_Malloc(env_count * sizeof(char*));
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++)
1880
result = putenv(pEnvArray[i]);
1883
smpd_err_printf("putenv failed: %d\n", errno);
1886
if (pLastEnv != NULL)
1887
MPIU_Free(pLastEnv);
1889
result = dup2(stdin_pipe_fds[0], 0); /* dup a new stdin */
1892
smpd_err_printf("dup2 stdin failed: %d\n", errno);
1894
close(stdin_pipe_fds[0]);
1895
close(stdin_pipe_fds[1]);
1897
result = dup2(stdout_pipe_fds[1], 1); /* dup a new stdout */
1900
smpd_err_printf("dup2 stdout failed: %d\n", errno);
1902
close(stdout_pipe_fds[0]);
1903
close(stdout_pipe_fds[1]);
1905
result = dup2(stderr_pipe_fds[1], 2); /* dup a new stderr */
1908
smpd_err_printf("dup2 stderr failed: %d\n", errno);
1910
close(stderr_pipe_fds[0]);
1911
close(stderr_pipe_fds[1]);
1913
if (process->pmi != NULL)
1915
close(pmi_pipe_fds[0]); /* close the other end */
1918
/* change the working directory */
1920
if (process->dir[0] != '\0')
1921
result = chdir( process->dir );
1923
chdir( getenv( "HOME" ) );
1925
/* reset the file mode creation mask */
1928
result = execvp( argv[0], argv );
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));*/
1938
if (process->pmi != NULL)
1940
/* create the abort command */
1941
result = smpd_create_command("abort", smpd_process.id, 0, SMPD_FALSE, &cmd_ptr);
1942
if (result != SMPD_SUCCESS)
1944
smpd_err_printf("unable to create an abort command in response to failed launch command: '%s'\n", process->exe);
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)
1951
smpd_err_printf("unable to add the result field to the result command in response to launch command: '%s'\n", process->exe);
1954
if (process->err_msg[0] != '\0')
1956
result = smpd_add_command_arg(cmd_ptr, "error", process->err_msg);
1957
if (result != SMPD_SUCCESS)
1959
smpd_err_printf("unable to add the error field to the abort command in response to failed launch command: '%s'\n", process->exe);
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)
1969
smpd_err_printf("unable to write the abort command header in response to failed launch command: '%s'\n", process->exe);
1972
result = write(pmi_pipe_fds[1], cmd_ptr->cmd, cmd_ptr->length);
1973
if (result != cmd_ptr->length)
1975
smpd_err_printf("unable to write the abort command in response to failed launch command: '%s'\n", process->exe);
1979
/* send a closed message on the pmi socket? */
1985
/* parent process */
1987
close(stdin_pipe_fds[0]);
1988
close(stdout_pipe_fds[1]);
1989
close(stderr_pipe_fds[1]);
1990
if (process->pmi != NULL)
1992
close(pmi_pipe_fds[1]);
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)
1999
smpd_err_printf("SMPDU_Sock_native_to_sock failed, error %s\n", get_sock_error_string(result));
2001
result = SMPDU_Sock_native_to_sock(set, stdout_pipe_fds[0], NULL, &sock_out);
2002
if (result != SMPD_SUCCESS)
2004
smpd_err_printf("SMPDU_Sock_native_to_sock failed, error %s\n", get_sock_error_string(result));
2006
result = SMPDU_Sock_native_to_sock(set, stderr_pipe_fds[0], NULL, &sock_err);
2007
if (result != SMPD_SUCCESS)
2009
smpd_err_printf("SMPDU_Sock_native_to_sock failed, error %s\n", get_sock_error_string(result));
2011
if (process->pmi != NULL)
2013
result = SMPDU_Sock_native_to_sock(set, pmi_pipe_fds[0], NULL, &sock_pmi);
2014
if (result != SMPD_SUCCESS)
2016
smpd_err_printf("SMPDU_Sock_native_to_sock failed, error %s\n", get_sock_error_string(result));
2019
process->in->sock = sock_in;
2020
process->out->sock = sock_out;
2021
process->err->sock = sock_err;
2022
if (process->pmi != NULL)
2024
process->pmi->sock = sock_pmi;
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)
2030
smpd_err_printf("SMPDU_Sock_set_user_ptr failed, error %s\n", get_sock_error_string(result));
2032
result = SMPDU_Sock_set_user_ptr(sock_out, process->out);
2033
if (result != SMPD_SUCCESS)
2035
smpd_err_printf("SMPDU_Sock_set_user_ptr failed, error %s\n", get_sock_error_string(result));
2037
result = SMPDU_Sock_set_user_ptr(sock_err, process->err);
2038
if (result != SMPD_SUCCESS)
2040
smpd_err_printf("SMPDU_Sock_set_user_ptr failed, error %s\n", get_sock_error_string(result));
2042
if (process->pmi != NULL)
2044
result = SMPDU_Sock_set_user_ptr(sock_pmi, process->pmi);
2045
if (result != SMPD_SUCCESS)
2047
smpd_err_printf("SMPDU_Sock_set_user_ptr failed, error %s\n", get_sock_error_string(result));
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)
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);
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)
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);
2070
if (process->pmi != NULL)
2072
result = smpd_post_read_command(process->pmi);
2073
if (result != SMPD_SUCCESS)
2075
smpd_err_printf("unable to post a read of the first command on the pmi control context.\n");
2076
smpd_exit_fn(FCNAME);
2080
process->wait = process->in->wait = process->out->wait = process->err->wait = pid;
2082
smpd_exit_fn(FCNAME);
2083
return SMPD_SUCCESS;
2089
#define FCNAME "smpd_wait_process"
2090
int smpd_wait_process(smpd_pwait_t wait, int *exit_code_ptr)
2092
#ifdef HAVE_WINDOWS_H
2096
smpd_enter_fn(FCNAME);
2098
if (wait.hProcess == INVALID_HANDLE_VALUE || wait.hProcess == NULL)
2100
smpd_dbg_printf("No process to wait for.\n");
2101
*exit_code_ptr = -1;
2102
smpd_exit_fn(FCNAME);
2103
return SMPD_SUCCESS;
2105
if (WaitForSingleObject(wait.hProcess, INFINITE) != WAIT_OBJECT_0)
2107
smpd_err_printf("WaitForSingleObject failed, error %d\n", GetLastError());
2108
*exit_code_ptr = -1;
2109
smpd_exit_fn(FCNAME);
2112
result = GetExitCodeProcess(wait.hProcess, &exit_code);
2115
smpd_err_printf("GetExitCodeProcess failed, error %d\n", GetLastError());
2116
*exit_code_ptr = -1;
2117
smpd_exit_fn(FCNAME);
2120
CloseHandle(wait.hProcess);
2121
CloseHandle(wait.hThread);
2123
*exit_code_ptr = exit_code;
2125
smpd_exit_fn(FCNAME);
2126
return SMPD_SUCCESS;
2129
smpd_pwait_t result;
2130
smpd_enter_fn(FCNAME);
2132
smpd_dbg_printf("waiting for process %d\n", wait);
2134
while (result == -1)
2136
result = waitpid(wait, &status, WUNTRACED);
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.
2149
smpd_err_printf("waitpid(%d) returned ECHILD\n", wait);
2150
*exit_code_ptr = -10;
2152
smpd_exit_fn(FCNAME);
2153
return SMPD_SUCCESS;
2156
smpd_err_printf("waitpid(%d) returned EINVAL\n", wait);
2157
*exit_code_ptr = -11;
2158
smpd_exit_fn(FCNAME);
2159
return SMPD_SUCCESS;
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;
2170
if (WIFEXITED(status))
2172
*exit_code_ptr = WEXITSTATUS(status);
2176
smpd_err_printf("WIFEXITED(%d) failed, setting exit code to -1\n", wait);
2177
*exit_code_ptr = -1;
2178
if (WIFSIGNALED(status))
2180
*exit_code_ptr = -2;
2182
if (WIFSTOPPED(status))
2184
*exit_code_ptr = -3;
2187
if (WCOREDUMP(status))
2189
*exit_code_ptr = -4;
2194
smpd_exit_fn(FCNAME);
2195
return SMPD_SUCCESS;
2199
#define SMPD_MAX_SUSPEND_RETRY_COUNT 4
2202
#define FCNAME "smpd_suspend_process"
2203
int smpd_suspend_process(smpd_process_t *process)
2205
#ifdef HAVE_WINDOWS_H
2206
int result = SMPD_SUCCESS;
2208
smpd_enter_fn(FCNAME);
2211
if (SuspendThread(process->wait.hThread) == -1){
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");
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);
2225
smpd_err_printf("The thread is active but cannot be suspended\n");
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);
2237
/* Ignore error and proceed if we fail to suspend */
2238
result = SMPD_SUCCESS;
2240
}while(retry_cnt < SMPD_MAX_SUSPEND_RETRY_COUNT);
2242
smpd_exit_fn(FCNAME);
2244
return SMPD_SUCCESS;
2246
smpd_enter_fn(FCNAME);
2248
smpd_dbg_printf("stopping process %d\n", process->wait);
2249
kill(process->wait, SIGSTOP);
2251
smpd_exit_fn(FCNAME);
2252
return SMPD_SUCCESS;
2256
#ifdef HAVE_WINDOWS_H
2257
static BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode)
2259
DWORD dwTID, dwCode, dwErr = 0;
2260
HANDLE hProcessDup = INVALID_HANDLE_VALUE;
2262
HINSTANCE hKernel = GetModuleHandle("Kernel32");
2263
BOOL bSuccess = FALSE;
2265
BOOL bDup = DuplicateHandle(GetCurrentProcess(),
2267
GetCurrentProcess(),
2273
if (GetExitCodeProcess((bDup) ? hProcessDup : hProcess, &dwCode) &&
2274
(dwCode == STILL_ACTIVE))
2276
FARPROC pfnExitProc;
2278
pfnExitProc = GetProcAddress(hKernel, "ExitProcess");
2282
hRT = CreateRemoteThread((bDup) ? hProcessDup : hProcess,
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
2289
(LPTHREAD_START_ROUTINE)pfnExitProc,
2290
UintToPtr(uExitCode)/*(LPVOID)uExitCode*/, 0, &dwTID);
2294
dwErr = GetLastError();
2298
dwErr = ERROR_PROCESS_ABORTED;
2303
if (WaitForSingleObject((bDup) ? hProcessDup : hProcess, 30000) == WAIT_OBJECT_0)
2307
dwErr = ERROR_TIMEOUT;
2314
CloseHandle(hProcessDup);
2317
SetLastError(dwErr);
2324
#define FCNAME "smpd_kill_process"
2325
int smpd_kill_process(smpd_process_t *process, int exit_code)
2327
int result = SMPD_SUCCESS;
2328
#ifdef HAVE_WINDOWS_H
2329
smpd_enter_fn(FCNAME);
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){
2342
smpd_exit_fn(FCNAME);
2346
smpd_enter_fn(FCNAME);
2348
smpd_dbg_printf("killing process %d\n", process->wait);
2349
if(kill(process->wait, /*SIGTERM*/SIGKILL) == -1){
2350
smpd_exit_fn(FCNAME);
2353
smpd_exit_fn(FCNAME);
2354
return SMPD_SUCCESS;
2359
#define FCNAME "smpd_kill_all_processes"
2360
int smpd_kill_all_processes(void)
2362
smpd_process_t *iter;
2364
smpd_enter_fn(FCNAME);
2366
if (smpd_process.local_root)
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;
2373
if (smpd_process.rsh_mpiexec)
2377
iter = smpd_process.process_list;
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++)
2389
wait_array[i] = iter->wait;
2392
for (i=0; i<count; i++)
2394
#ifdef HAVE_WINDOWS_H
2395
if (!SafeTerminateProcess(wait_array[i].hProcess, 123))
2397
if (GetLastError() != ERROR_PROCESS_ABORTED)
2399
TerminateProcess(wait_array[i].hProcess, 255);
2403
kill(wait_array[i], /*SIGTERM*/SIGKILL);
2410
iter = smpd_process.process_list;
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)
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)
2427
if (!SafeTerminateProcess(iter->wait.hProcess, 123))
2429
if (GetLastError() != ERROR_PROCESS_ABORTED)
2431
TerminateProcess(iter->wait.hProcess, 255);
2439
kill(iter->wait, /*SIGTERM*/SIGKILL);
2445
smpd_exit_fn(FCNAME);
2446
return SMPD_SUCCESS;
2450
#define FCNAME "smpd_exit"
2451
int smpd_exit(int exitcode)
2453
smpd_enter_fn(FCNAME);
2454
smpd_kill_all_processes();
2455
#ifdef HAVE_WINDOWS_H
2456
smpd_finalize_drive_maps();
2458
smpd_finalize_printf();
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)
2466
CloseHandle(smpd_process.hCloseStdinThreadEvent);
2468
/* This is necessary because exit() can deadlock flushing file buffers while the stdin thread is running */
2469
ExitProcess(exitcode);
2472
smpd_exit_fn(FCNAME);