| 381 | } |
| 382 | |
| 383 | static pid_t ProcessSpawn(const std::vector<String>& arguments, const Dictionary::Ptr& extraEnvironment, bool adjustPriority, int fds[3]) |
| 384 | { |
| 385 | Dictionary::Ptr request = new Dictionary({ |
| 386 | { "command", "spawn" }, |
| 387 | { "arguments", Array::FromVector(arguments) }, |
| 388 | { "extraEnvironment", extraEnvironment }, |
| 389 | { "adjustPriority", adjustPriority } |
| 390 | }); |
| 391 | |
| 392 | String jrequest = JsonEncode(request); |
| 393 | size_t length = jrequest.GetLength(); |
| 394 | |
| 395 | std::unique_lock<std::mutex> lock(l_ProcessControlMutex); |
| 396 | |
| 397 | struct msghdr msg; |
| 398 | memset(&msg, 0, sizeof(msg)); |
| 399 | |
| 400 | struct iovec io; |
| 401 | io.iov_base = &length; |
| 402 | io.iov_len = sizeof(length); |
| 403 | |
| 404 | msg.msg_iov = &io; |
| 405 | msg.msg_iovlen = 1; |
| 406 | |
| 407 | char cbuf[CMSG_SPACE(sizeof(int) * 3)]; |
| 408 | msg.msg_control = cbuf; |
| 409 | msg.msg_controllen = sizeof(cbuf); |
| 410 | |
| 411 | struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); |
| 412 | cmsg->cmsg_level = SOL_SOCKET; |
| 413 | cmsg->cmsg_type = SCM_RIGHTS; |
| 414 | cmsg->cmsg_len = CMSG_LEN(sizeof(int) * 3); |
| 415 | |
| 416 | memcpy(CMSG_DATA(cmsg), fds, sizeof(int) * 3); |
| 417 | |
| 418 | msg.msg_controllen = cmsg->cmsg_len; |
| 419 | |
| 420 | do { |
| 421 | while (sendmsg(l_ProcessControlFD, &msg, 0) < 0) { |
| 422 | StartSpawnProcessHelper(); |
| 423 | } |
| 424 | } while (send(l_ProcessControlFD, jrequest.CStr(), jrequest.GetLength(), 0) < 0); |
| 425 | |
| 426 | char buf[4096]; |
| 427 | |
| 428 | ssize_t rc = recv(l_ProcessControlFD, buf, sizeof(buf), 0); |
| 429 | |
| 430 | if (rc <= 0) |
| 431 | return -1; |
| 432 | |
| 433 | String jresponse = String(buf, buf + rc); |
| 434 | |
| 435 | Dictionary::Ptr response = JsonDecode(jresponse); |
| 436 | |
| 437 | if (response->Get("rc") == -1) |
| 438 | errno = response->Get("errno"); |
| 439 | |
| 440 | return response->Get("rc"); |