diff options
Diffstat (limited to 'src/util/os_priority.c')
-rw-r--r-- | src/util/os_priority.c | 112 |
1 files changed, 97 insertions, 15 deletions
diff --git a/src/util/os_priority.c b/src/util/os_priority.c index c9174dee9..3a10599b5 100644 --- a/src/util/os_priority.c +++ b/src/util/os_priority.c | |||
@@ -768,6 +768,10 @@ CreateCustomEnvTable (char **vars) | |||
768 | * Start a process. | 768 | * Start a process. |
769 | * | 769 | * |
770 | * @param pipe_control should a pipe be used to send signals to the child? | 770 | * @param pipe_control should a pipe be used to send signals to the child? |
771 | * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags controlling which | ||
772 | * std handles of the parent are inherited by the child. | ||
773 | * pipe_stdin and pipe_stdout take priority over std_inheritance | ||
774 | * (when they are non-NULL). | ||
771 | * @param pipe_stdin pipe to use to send input to child process (or NULL) | 775 | * @param pipe_stdin pipe to use to send input to child process (or NULL) |
772 | * @param pipe_stdout pipe to use to get output from child process (or NULL) | 776 | * @param pipe_stdout pipe to use to get output from child process (or NULL) |
773 | * @param lsocks array of listen sockets to dup systemd-style (or NULL); | 777 | * @param lsocks array of listen sockets to dup systemd-style (or NULL); |
@@ -778,6 +782,7 @@ CreateCustomEnvTable (char **vars) | |||
778 | */ | 782 | */ |
779 | static struct GNUNET_OS_Process * | 783 | static struct GNUNET_OS_Process * |
780 | start_process (int pipe_control, | 784 | start_process (int pipe_control, |
785 | enum GNUNET_OS_InheritStdioFlags std_inheritance, | ||
781 | struct GNUNET_DISK_PipeHandle *pipe_stdin, | 786 | struct GNUNET_DISK_PipeHandle *pipe_stdin, |
782 | struct GNUNET_DISK_PipeHandle *pipe_stdout, | 787 | struct GNUNET_DISK_PipeHandle *pipe_stdout, |
783 | const SOCKTYPE *lsocks, | 788 | const SOCKTYPE *lsocks, |
@@ -870,6 +875,10 @@ start_process (int pipe_control, | |||
870 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2"); | 875 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2"); |
871 | GNUNET_break (0 == close (fd_stdout_write)); | 876 | GNUNET_break (0 == close (fd_stdout_write)); |
872 | } | 877 | } |
878 | else if (!(std_inheritance & GNUNET_OS_INHERIT_STD_OUT)) | ||
879 | { | ||
880 | close (1); | ||
881 | } | ||
873 | if (pipe_stdin != NULL) | 882 | if (pipe_stdin != NULL) |
874 | { | 883 | { |
875 | 884 | ||
@@ -878,6 +887,14 @@ start_process (int pipe_control, | |||
878 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2"); | 887 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2"); |
879 | GNUNET_break (0 == close (fd_stdin_read)); | 888 | GNUNET_break (0 == close (fd_stdin_read)); |
880 | } | 889 | } |
890 | else if (!(std_inheritance & GNUNET_OS_INHERIT_STD_IN)) | ||
891 | { | ||
892 | close (0); | ||
893 | } | ||
894 | if (!(std_inheritance & GNUNET_OS_INHERIT_STD_ERR)) | ||
895 | { | ||
896 | close (2); | ||
897 | } | ||
881 | if (lscp != NULL) | 898 | if (lscp != NULL) |
882 | { | 899 | { |
883 | /* read systemd documentation... */ | 900 | /* read systemd documentation... */ |
@@ -961,6 +978,10 @@ start_process (int pipe_control, | |||
961 | long lRet; | 978 | long lRet; |
962 | HANDLE stdin_handle; | 979 | HANDLE stdin_handle; |
963 | HANDLE stdout_handle; | 980 | HANDLE stdout_handle; |
981 | HANDLE stdih, stdoh, stdeh; | ||
982 | DWORD stdif, stdof, stdef; | ||
983 | BOOL bresult; | ||
984 | DWORD error_code; | ||
964 | 985 | ||
965 | if (GNUNET_SYSERR == GNUNET_OS_check_helper_binary (filename)) | 986 | if (GNUNET_SYSERR == GNUNET_OS_check_helper_binary (filename)) |
966 | return NULL; /* not executable */ | 987 | return NULL; /* not executable */ |
@@ -1083,9 +1104,11 @@ start_process (int pipe_control, | |||
1083 | 1104 | ||
1084 | memset (&start, 0, sizeof (start)); | 1105 | memset (&start, 0, sizeof (start)); |
1085 | start.cb = sizeof (start); | 1106 | start.cb = sizeof (start); |
1086 | if ((pipe_stdin != NULL) || (pipe_stdout != NULL)) | 1107 | if ((pipe_stdin != NULL) || (pipe_stdout != NULL) || (std_inheritance != 0)) |
1087 | start.dwFlags |= STARTF_USESTDHANDLES; | 1108 | start.dwFlags |= STARTF_USESTDHANDLES; |
1088 | 1109 | ||
1110 | stdih = GetStdHandle (STD_INPUT_HANDLE); | ||
1111 | GetHandleInformation (stdih, &stdif); | ||
1089 | if (pipe_stdin != NULL) | 1112 | if (pipe_stdin != NULL) |
1090 | { | 1113 | { |
1091 | GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle | 1114 | GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle |
@@ -1093,7 +1116,21 @@ start_process (int pipe_control, | |||
1093 | &stdin_handle, sizeof (HANDLE)); | 1116 | &stdin_handle, sizeof (HANDLE)); |
1094 | start.hStdInput = stdin_handle; | 1117 | start.hStdInput = stdin_handle; |
1095 | } | 1118 | } |
1119 | if (stdih) | ||
1120 | { | ||
1121 | if (std_inheritance & GNUNET_OS_INHERIT_STD_IN) | ||
1122 | { | ||
1123 | SetHandleInformation (stdih, HANDLE_FLAG_INHERIT, 1); | ||
1124 | if (pipe_stdin == NULL) | ||
1125 | start.hStdInput = stdih; | ||
1126 | } | ||
1127 | else | ||
1128 | SetHandleInformation (stdih, HANDLE_FLAG_INHERIT, 0); | ||
1129 | } | ||
1130 | |||
1096 | 1131 | ||
1132 | stdoh = GetStdHandle (STD_OUTPUT_HANDLE); | ||
1133 | GetHandleInformation (stdoh, &stdof); | ||
1097 | if (pipe_stdout != NULL) | 1134 | if (pipe_stdout != NULL) |
1098 | { | 1135 | { |
1099 | GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle | 1136 | GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle |
@@ -1102,6 +1139,30 @@ start_process (int pipe_control, | |||
1102 | &stdout_handle, sizeof (HANDLE)); | 1139 | &stdout_handle, sizeof (HANDLE)); |
1103 | start.hStdOutput = stdout_handle; | 1140 | start.hStdOutput = stdout_handle; |
1104 | } | 1141 | } |
1142 | if (stdoh) | ||
1143 | { | ||
1144 | if (std_inheritance & GNUNET_OS_INHERIT_STD_OUT) | ||
1145 | { | ||
1146 | SetHandleInformation (stdoh, HANDLE_FLAG_INHERIT, 1); | ||
1147 | if (pipe_stdout == NULL) | ||
1148 | start.hStdOutput = stdoh; | ||
1149 | } | ||
1150 | else | ||
1151 | SetHandleInformation (stdoh, HANDLE_FLAG_INHERIT, 0); | ||
1152 | } | ||
1153 | |||
1154 | stdeh = GetStdHandle (STD_ERROR_HANDLE); | ||
1155 | GetHandleInformation (stdeh, &stdef); | ||
1156 | if (stdeh) | ||
1157 | { | ||
1158 | if (std_inheritance & GNUNET_OS_INHERIT_STD_ERR) | ||
1159 | { | ||
1160 | SetHandleInformation (stdeh, HANDLE_FLAG_INHERIT, 1); | ||
1161 | start.hStdError = stdeh; | ||
1162 | } | ||
1163 | else | ||
1164 | SetHandleInformation (stdeh, HANDLE_FLAG_INHERIT, 0); | ||
1165 | } | ||
1105 | 1166 | ||
1106 | if (GNUNET_YES == pipe_control) | 1167 | if (GNUNET_YES == pipe_control) |
1107 | { | 1168 | { |
@@ -1179,24 +1240,36 @@ start_process (int pipe_control, | |||
1179 | return NULL; | 1240 | return NULL; |
1180 | } | 1241 | } |
1181 | 1242 | ||
1182 | if (!CreateProcessW (wpath, wcmd, NULL, NULL, TRUE, | 1243 | bresult = CreateProcessW (wpath, wcmd, NULL, NULL, TRUE, |
1183 | DETACHED_PROCESS | CREATE_SUSPENDED, env_block, NULL, &start, &proc)) | 1244 | DETACHED_PROCESS | CREATE_SUSPENDED, env_block, NULL, &start, &proc); |
1245 | error_code = GetLastError (); | ||
1246 | |||
1247 | if ((NULL == pipe_stdin) && (stdih)) | ||
1248 | SetHandleInformation (stdih, HANDLE_FLAG_INHERIT, stdif); | ||
1249 | |||
1250 | |||
1251 | if ((NULL == pipe_stdout) && (stdoh)) | ||
1252 | SetHandleInformation (stdoh, HANDLE_FLAG_INHERIT, stdof); | ||
1253 | |||
1254 | if (stdeh) | ||
1255 | SetHandleInformation (stdeh, HANDLE_FLAG_INHERIT, stdef); | ||
1256 | |||
1257 | GNUNET_free (env_block); | ||
1258 | GNUNET_free (cmd); | ||
1259 | free (wpath); | ||
1260 | free (wcmd); | ||
1261 | |||
1262 | if (!bresult) | ||
1184 | { | 1263 | { |
1185 | SetErrnoFromWinError (GetLastError ()); | 1264 | SetErrnoFromWinError (error_code); |
1186 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "CreateProcess"); | 1265 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "CreateProcess"); |
1187 | if (NULL != control_pipe) | 1266 | if (NULL != control_pipe) |
1188 | GNUNET_DISK_file_close (control_pipe); | 1267 | GNUNET_DISK_file_close (control_pipe); |
1189 | if (NULL != lsocks) | 1268 | if (NULL != lsocks) |
1190 | GNUNET_DISK_pipe_close (lsocks_pipe); | 1269 | GNUNET_DISK_pipe_close (lsocks_pipe); |
1191 | GNUNET_free (env_block); | ||
1192 | GNUNET_free (cmd); | ||
1193 | free (wpath); | ||
1194 | free (wcmd); | ||
1195 | return NULL; | 1270 | return NULL; |
1196 | } | 1271 | } |
1197 | 1272 | ||
1198 | GNUNET_free (env_block); | ||
1199 | |||
1200 | gnunet_proc = GNUNET_malloc (sizeof (struct GNUNET_OS_Process)); | 1273 | gnunet_proc = GNUNET_malloc (sizeof (struct GNUNET_OS_Process)); |
1201 | gnunet_proc->pid = proc.dwProcessId; | 1274 | gnunet_proc->pid = proc.dwProcessId; |
1202 | gnunet_proc->handle = proc.hProcess; | 1275 | gnunet_proc->handle = proc.hProcess; |
@@ -1206,9 +1279,6 @@ start_process (int pipe_control, | |||
1206 | 1279 | ||
1207 | ResumeThread (proc.hThread); | 1280 | ResumeThread (proc.hThread); |
1208 | CloseHandle (proc.hThread); | 1281 | CloseHandle (proc.hThread); |
1209 | GNUNET_free (cmd); | ||
1210 | free (wpath); | ||
1211 | free (wcmd); | ||
1212 | 1282 | ||
1213 | if (lsocks == NULL || lsocks[0] == INVALID_SOCKET) | 1283 | if (lsocks == NULL || lsocks[0] == INVALID_SOCKET) |
1214 | return gnunet_proc; | 1284 | return gnunet_proc; |
@@ -1300,6 +1370,7 @@ start_process (int pipe_control, | |||
1300 | * Start a process. | 1370 | * Start a process. |
1301 | * | 1371 | * |
1302 | * @param pipe_control should a pipe be used to send signals to the child? | 1372 | * @param pipe_control should a pipe be used to send signals to the child? |
1373 | * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags | ||
1303 | * @param pipe_stdin pipe to use to send input to child process (or NULL) | 1374 | * @param pipe_stdin pipe to use to send input to child process (or NULL) |
1304 | * @param pipe_stdout pipe to use to get output from child process (or NULL) | 1375 | * @param pipe_stdout pipe to use to get output from child process (or NULL) |
1305 | * @param filename name of the binary | 1376 | * @param filename name of the binary |
@@ -1308,12 +1379,14 @@ start_process (int pipe_control, | |||
1308 | */ | 1379 | */ |
1309 | struct GNUNET_OS_Process * | 1380 | struct GNUNET_OS_Process * |
1310 | GNUNET_OS_start_process_vap (int pipe_control, | 1381 | GNUNET_OS_start_process_vap (int pipe_control, |
1382 | enum GNUNET_OS_InheritStdioFlags std_inheritance, | ||
1311 | struct GNUNET_DISK_PipeHandle *pipe_stdin, | 1383 | struct GNUNET_DISK_PipeHandle *pipe_stdin, |
1312 | struct GNUNET_DISK_PipeHandle *pipe_stdout, | 1384 | struct GNUNET_DISK_PipeHandle *pipe_stdout, |
1313 | const char *filename, | 1385 | const char *filename, |
1314 | char *const argv[]) | 1386 | char *const argv[]) |
1315 | { | 1387 | { |
1316 | return start_process (pipe_control, | 1388 | return start_process (pipe_control, |
1389 | std_inheritance, | ||
1317 | pipe_stdin, | 1390 | pipe_stdin, |
1318 | pipe_stdout, | 1391 | pipe_stdout, |
1319 | NULL, | 1392 | NULL, |
@@ -1326,6 +1399,7 @@ GNUNET_OS_start_process_vap (int pipe_control, | |||
1326 | * Start a process. | 1399 | * Start a process. |
1327 | * | 1400 | * |
1328 | * @param pipe_control should a pipe be used to send signals to the child? | 1401 | * @param pipe_control should a pipe be used to send signals to the child? |
1402 | * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags | ||
1329 | * @param pipe_stdin pipe to use to send input to child process (or NULL) | 1403 | * @param pipe_stdin pipe to use to send input to child process (or NULL) |
1330 | * @param pipe_stdout pipe to use to get output from child process (or NULL) | 1404 | * @param pipe_stdout pipe to use to get output from child process (or NULL) |
1331 | * @param filename name of the binary | 1405 | * @param filename name of the binary |
@@ -1334,6 +1408,7 @@ GNUNET_OS_start_process_vap (int pipe_control, | |||
1334 | */ | 1408 | */ |
1335 | struct GNUNET_OS_Process * | 1409 | struct GNUNET_OS_Process * |
1336 | GNUNET_OS_start_process_va (int pipe_control, | 1410 | GNUNET_OS_start_process_va (int pipe_control, |
1411 | enum GNUNET_OS_InheritStdioFlags std_inheritance, | ||
1337 | struct GNUNET_DISK_PipeHandle *pipe_stdin, | 1412 | struct GNUNET_DISK_PipeHandle *pipe_stdin, |
1338 | struct GNUNET_DISK_PipeHandle *pipe_stdout, | 1413 | struct GNUNET_DISK_PipeHandle *pipe_stdout, |
1339 | const char *filename, va_list va) | 1414 | const char *filename, va_list va) |
@@ -1355,6 +1430,7 @@ GNUNET_OS_start_process_va (int pipe_control, | |||
1355 | argc++; | 1430 | argc++; |
1356 | va_end (ap); | 1431 | va_end (ap); |
1357 | ret = GNUNET_OS_start_process_vap (pipe_control, | 1432 | ret = GNUNET_OS_start_process_vap (pipe_control, |
1433 | std_inheritance, | ||
1358 | pipe_stdin, | 1434 | pipe_stdin, |
1359 | pipe_stdout, | 1435 | pipe_stdout, |
1360 | filename, | 1436 | filename, |
@@ -1369,6 +1445,7 @@ GNUNET_OS_start_process_va (int pipe_control, | |||
1369 | * Start a process. | 1445 | * Start a process. |
1370 | * | 1446 | * |
1371 | * @param pipe_control should a pipe be used to send signals to the child? | 1447 | * @param pipe_control should a pipe be used to send signals to the child? |
1448 | * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags | ||
1372 | * @param pipe_stdin pipe to use to send input to child process (or NULL) | 1449 | * @param pipe_stdin pipe to use to send input to child process (or NULL) |
1373 | * @param pipe_stdout pipe to use to get output from child process (or NULL) | 1450 | * @param pipe_stdout pipe to use to get output from child process (or NULL) |
1374 | * @param filename name of the binary | 1451 | * @param filename name of the binary |
@@ -1379,6 +1456,7 @@ GNUNET_OS_start_process_va (int pipe_control, | |||
1379 | */ | 1456 | */ |
1380 | struct GNUNET_OS_Process * | 1457 | struct GNUNET_OS_Process * |
1381 | GNUNET_OS_start_process (int pipe_control, | 1458 | GNUNET_OS_start_process (int pipe_control, |
1459 | enum GNUNET_OS_InheritStdioFlags std_inheritance, | ||
1382 | struct GNUNET_DISK_PipeHandle *pipe_stdin, | 1460 | struct GNUNET_DISK_PipeHandle *pipe_stdin, |
1383 | struct GNUNET_DISK_PipeHandle *pipe_stdout, | 1461 | struct GNUNET_DISK_PipeHandle *pipe_stdout, |
1384 | const char *filename, ...) | 1462 | const char *filename, ...) |
@@ -1387,7 +1465,8 @@ GNUNET_OS_start_process (int pipe_control, | |||
1387 | va_list ap; | 1465 | va_list ap; |
1388 | 1466 | ||
1389 | va_start (ap, filename); | 1467 | va_start (ap, filename); |
1390 | ret = GNUNET_OS_start_process_va (pipe_control, pipe_stdin, pipe_stdout, filename, ap); | 1468 | ret = GNUNET_OS_start_process_va (pipe_control, std_inheritance, pipe_stdin, |
1469 | pipe_stdout, filename, ap); | ||
1391 | va_end (ap); | 1470 | va_end (ap); |
1392 | return ret; | 1471 | return ret; |
1393 | } | 1472 | } |
@@ -1405,11 +1484,13 @@ GNUNET_OS_start_process (int pipe_control, | |||
1405 | */ | 1484 | */ |
1406 | struct GNUNET_OS_Process * | 1485 | struct GNUNET_OS_Process * |
1407 | GNUNET_OS_start_process_v (int pipe_control, | 1486 | GNUNET_OS_start_process_v (int pipe_control, |
1487 | enum GNUNET_OS_InheritStdioFlags std_inheritance, | ||
1408 | const SOCKTYPE *lsocks, | 1488 | const SOCKTYPE *lsocks, |
1409 | const char *filename, | 1489 | const char *filename, |
1410 | char *const argv[]) | 1490 | char *const argv[]) |
1411 | { | 1491 | { |
1412 | return start_process (pipe_control, | 1492 | return start_process (pipe_control, |
1493 | std_inheritance, | ||
1413 | NULL, | 1494 | NULL, |
1414 | NULL, | 1495 | NULL, |
1415 | lsocks, | 1496 | lsocks, |
@@ -1723,7 +1804,8 @@ GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc, void *proc_cls, | |||
1723 | if (NULL == opipe) | 1804 | if (NULL == opipe) |
1724 | return NULL; | 1805 | return NULL; |
1725 | va_start (ap, binary); | 1806 | va_start (ap, binary); |
1726 | eip = GNUNET_OS_start_process_va (GNUNET_NO, NULL, opipe, binary, ap); | 1807 | /* redirect stdout, don't inherit stderr/stdin */ |
1808 | eip = GNUNET_OS_start_process_va (GNUNET_NO, 0, NULL, opipe, binary, ap); | ||
1727 | va_end (ap); | 1809 | va_end (ap); |
1728 | if (NULL == eip) | 1810 | if (NULL == eip) |
1729 | { | 1811 | { |