aboutsummaryrefslogtreecommitdiff
path: root/src/util/os_priority.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-07-09 19:04:19 +0000
committerChristian Grothoff <christian@grothoff.org>2012-07-09 19:04:19 +0000
commit8f9464256fc06a884bf589b4004262a0549d11b3 (patch)
treea088b8acbebdefe2acf0b41cfed4418830275b78 /src/util/os_priority.c
parent817ee37a75fb8eb5887023d1a5152cb528ee2d5a (diff)
downloadgnunet-8f9464256fc06a884bf589b4004262a0549d11b3.tar.gz
gnunet-8f9464256fc06a884bf589b4004262a0549d11b3.zip
-LRN: Another take on std descriptor inheritance
Now descriptors are not inherited by default, you have to pass a set of flags to make it so. When pipes are given, flags have no effect. gnunet-arm now has two options to block stdout and stderr from being passed to gnunet-service-arm
Diffstat (limited to 'src/util/os_priority.c')
-rw-r--r--src/util/os_priority.c112
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 */
779static struct GNUNET_OS_Process * 783static struct GNUNET_OS_Process *
780start_process (int pipe_control, 784start_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 */
1309struct GNUNET_OS_Process * 1380struct GNUNET_OS_Process *
1310GNUNET_OS_start_process_vap (int pipe_control, 1381GNUNET_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 */
1335struct GNUNET_OS_Process * 1409struct GNUNET_OS_Process *
1336GNUNET_OS_start_process_va (int pipe_control, 1410GNUNET_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 */
1380struct GNUNET_OS_Process * 1457struct GNUNET_OS_Process *
1381GNUNET_OS_start_process (int pipe_control, 1458GNUNET_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 */
1406struct GNUNET_OS_Process * 1485struct GNUNET_OS_Process *
1407GNUNET_OS_start_process_v (int pipe_control, 1486GNUNET_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 {