@samitouri / QOSAMI-WSL / commits / 3be5af4b

cleanup: use wil::unique_fd in CreateProcessParse (#13002)

* cleanup: use wil::unique_fd in CreateProcessParse * pr feedback --------- Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>

Ben Hillis committed Jun 18, 2025 at 14:55 UTC 3be5af4b382b656ea2571faf1589031871842fb8
1 file changed +87 -280
src/linux/init/init.cpp
+87 -280
@@ -74,10 +74,9 @@ typedef struct _CREATE_PROCESS_PARSED_COMMON
74 typedef struct _CREATE_PROCESS_PARSED
75 {
76 CREATE_PROCESS_PARSED_COMMON Common;
77 - int EventFd;
78 - int StdFd[LX_INIT_STD_FD_COUNT];
79 - int TtyFd;
80 - int ServiceFd;
77 + wil::unique_fd EventFd;
78 + wil::unique_fd StdFd[LX_INIT_STD_FD_COUNT];
79 + wil::unique_fd ServiceFd;
80 } CREATE_PROCESS_PARSED, *PCREATE_PROCESS_PARSED;
81
82 struct sigaction g_SavedSignalActions[_NSIG];
@@ -100,19 +99,15 @@ constexpr passwd c_defaultPasswordEntry = {
99
100 int CaptureCrash(int Argc, char** Argv);
101
103 -void CreateProcess(PCREATE_PROCESS_PARSED Parsed, const wsl::linux::WslDistributionConfig& Config);
102 +void CreateProcess(PCREATE_PROCESS_PARSED Parsed, int TtyFd, const wsl::linux::WslDistributionConfig& Config);
103
104 void CreateProcessCommon(PCREATE_PROCESS_PARSED_COMMON Common, int TtyFd, int ServiceSocketFd, const wsl::linux::WslDistributionConfig&);
105
107 -int CreateProcessParse(PCREATE_PROCESS_PARSED CreateProcessParsed, gsl::span<gsl::byte> Buffer, int MessageFd, int TtyFd);
106 +CREATE_PROCESS_PARSED CreateProcessParse(gsl::span<gsl::byte> Buffer, int MessageFd, const wsl::linux::WslDistributionConfig& Config);
107
108 int CreateProcessParseCommon(PCREATE_PROCESS_PARSED_COMMON Parsed, gsl::span<gsl::byte> Buffer, const wsl::linux::WslDistributionConfig& Config);
109
111 -void CreateProcessParseFree(PCREATE_PROCESS_PARSED CreateProcessParsed);
112 -
113 -void CreateProcessParseInitialize(PCREATE_PROCESS_PARSED CreateProcessParsed);
114 -
115 -int CreateProcessReplyToServer(PCREATE_PROCESS_PARSED CreateProcessParsed, pid_t CreateProcessPid, int MessageFd);
110 +int CreateProcessReplyToServer(PCREATE_PROCESS_PARSED Parsed, pid_t CreateProcessPid, int MessageFd);
111
112 void CreateWslSystemdUnits(const wsl::linux::WslDistributionConfig& Config);
113
@@ -144,7 +139,7 @@ void HardenMirroredNetworkingSettingsAgainstSystemd();
139
140 void PostProcessImportedDistribution(wsl::shared::MessageWriter<LX_MINI_INIT_IMPORT_RESULT>& Message, const char* ExtractedPath);
141
147 -int SessionLeaderCreateProcess(gsl::span<gsl::byte> Buffer, int MessageFd, int TtyFd);
142 +void SessionLeaderCreateProcess(gsl::span<gsl::byte> Buffer, int MessageFd, int TtyFd);
143
144 void SessionLeaderEntry(int MessageFd, int TtyFd, const wsl::linux::WslDistributionConfig& Config);
145
@@ -447,7 +442,7 @@ try
442 }
443 CATCH_RETURN_ERRNO()
444
450 -void CreateProcess(PCREATE_PROCESS_PARSED Parsed, const wsl::linux::WslDistributionConfig& Config)
445 +void CreateProcess(PCREATE_PROCESS_PARSED Parsed, int TtyFd, const wsl::linux::WslDistributionConfig& Config)
446
447 /*++
448
@@ -457,7 +452,7 @@ Routine Description:
452
453 Arguments:
454
460 - Parsed - Supplies a pointer to a create process parsed.
455 + Parsed - Supplies a pointer to a create process parsed structure.
456
457 Config - Supplies the distribution configuration.
458
@@ -479,23 +474,23 @@ Return Value:
474
475 for (StdFdIndex = 0; StdFdIndex < LX_INIT_STD_FD_COUNT; StdFdIndex += 1)
476 {
482 - if (dup2(Parsed->StdFd[StdFdIndex], StdFdIndex) < 0)
477 + //
478 + // If a standard file descriptor is not set, use the TTY file descriptor.
479 + //
480 +
481 + if (dup2(Parsed->StdFd[StdFdIndex] ? Parsed->StdFd[StdFdIndex].get() : TtyFd, StdFdIndex) < 0)
482 {
483 FATAL_ERROR("dup2 failed {}", errno);
484 }
485
487 - if (Parsed->StdFd[StdFdIndex] != Parsed->TtyFd)
488 - {
489 - CLOSE(Parsed->StdFd[StdFdIndex]);
490 - Parsed->StdFd[StdFdIndex] = -1;
491 - }
486 + Parsed->StdFd[StdFdIndex].reset();
487 }
488
489 //
490 // Read the eventfd data from the wsl service.
491 //
492
498 - BytesRead = TEMP_FAILURE_RETRY(read(Parsed->EventFd, &EventFdData, sizeof(EventFdData)));
493 + BytesRead = TEMP_FAILURE_RETRY(read(Parsed->EventFd.get(), &EventFdData, sizeof(EventFdData)));
494 if (BytesRead != sizeof(EventFdData))
495 {
496 FATAL_ERROR("Failed to read (size {}) EventFd {}", BytesRead, errno);
@@ -505,8 +500,7 @@ Return Value:
500 // Launch the process.
501 //
502
508 - CreateProcessCommon(&Parsed->Common, Parsed->TtyFd, Parsed->ServiceFd, Config);
509 - Parsed->TtyFd = -1;
503 + CreateProcessCommon(&Parsed->Common, TtyFd, Parsed->ServiceFd.get(), Config);
504 return;
505 }
506
@@ -811,7 +805,7 @@ catch (...)
805 FATAL_ERROR("Create process failed");
806 }
807
814 -int CreateProcessParse(PCREATE_PROCESS_PARSED CreateProcessParsed, gsl::span<gsl::byte> Buffer, int MessageFd, int TtyFd, const wsl::linux::WslDistributionConfig& Config)
808 +CREATE_PROCESS_PARSED CreateProcessParse(gsl::span<gsl::byte> Buffer, int MessageFd, const wsl::linux::WslDistributionConfig& Config)
809
810 /*++
811
@@ -821,87 +815,56 @@ Routine Description:
815
816 Arguments:
817
824 - CreateProcessParsed - Supplies a buffer to store the create process
825 - parameters.
826 -
818 Buffer - Supplies the create process message.
819
820 MessageFd - Supplies a message port file descriptor.
821
831 - TtyFd - Supplies an optional Tty file descriptor to inherit from the parent.
832 -
822 Config - Supplies the distribution configuration.
823
824 Return Value:
825
837 - 0 on success, -1 on failure.
826 + The create process parameters.
827
828 --*/
829
830 {
842 - int EventFd;
843 - unsigned short Index;
844 - int Result;
845 - int StdFd[LX_INIT_STD_FD_COUNT];
846 - LXBUS_IPC_MESSAGE_UNMARSHAL_FORK_TOKEN_PARAMETERS UnmarshalForkToken;
847 - LXBUS_IPC_MESSAGE_UNMARSHAL_HANDLE_PARAMETERS UnmarshalHandle;
848 - LXBUS_IPC_MESSAGE_UNMARSHAL_SERVER_PARAMETERS UnmarshalServer;
849 -
850 - EventFd = -1;
851 - memset(StdFd, -1, sizeof(StdFd));
852 -
831 //
832 // Validate the message size.
833 //
834
857 - auto* CreateProcess = gslhelpers::try_get_struct<LX_INIT_CREATE_PROCESS>(Buffer);
858 - if (!CreateProcess)
859 - {
860 - FATAL_ERROR("Unexpected create process size {}", Buffer.size());
861 - }
835 + auto* Message = gslhelpers::try_get_struct<LX_INIT_CREATE_PROCESS>(Buffer);
836 + THROW_ERRNO_IF(EINVAL, !Message);
837
838 //
839 // Parse common create process information.
840 //
841
867 - Result = CreateProcessParseCommon(&CreateProcessParsed->Common, Buffer.subspan(offsetof(LX_INIT_CREATE_PROCESS, Common)), Config);
868 - if (Result < 0)
869 - {
870 - goto CreateProcessParseEnd;
871 - }
842 + CREATE_PROCESS_PARSED Parsed{};
843 + int Result = CreateProcessParseCommon(&Parsed.Common, Buffer.subspan(offsetof(LX_INIT_CREATE_PROCESS, Common)), Config);
844 + THROW_ERRNO_IF(EINVAL, Result < 0);
845
846 //
847 // Create the eventfd.
848 //
849
877 - EventFd = eventfd(0, EFD_CLOEXEC);
878 - if (EventFd < 0)
879 - {
880 - FATAL_ERROR("eventfd failed {}", errno);
881 - }
850 + Parsed.EventFd = eventfd(0, EFD_CLOEXEC);
851 + THROW_LAST_ERROR_IF(!Parsed.EventFd);
852
853 //
854 // Set up the standard handles for the process.
855 //
856 //
857
888 - for (Index = 0; Index < LX_INIT_STD_FD_COUNT; Index += 1)
858 + for (unsigned short Index = 0; Index < LX_INIT_STD_FD_COUNT; Index += 1)
859 {
890 - if (CreateProcess->StdFdIds[Index] == LX_INIT_CREATE_PROCESS_USE_CONSOLE)
891 - {
892 - StdFd[Index] = TtyFd;
893 - }
894 - else
860 + if (Message->StdFdIds[Index] != LX_INIT_CREATE_PROCESS_USE_CONSOLE)
861 {
896 - memset(&UnmarshalHandle, 0, sizeof(UnmarshalHandle));
897 - UnmarshalHandle.Input.HandleId = CreateProcess->StdFdIds[Index];
862 + LXBUS_IPC_MESSAGE_UNMARSHAL_HANDLE_PARAMETERS UnmarshalHandle{};
863 + UnmarshalHandle.Input.HandleId = Message->StdFdIds[Index];
864 Result = TEMP_FAILURE_RETRY(ioctl(MessageFd, LXBUS_IPC_MESSAGE_IOCTL_UNMARSHAL_HANDLE, &UnmarshalHandle));
899 - if (Result < 0)
900 - {
901 - FATAL_ERROR("Failed to unmarshal handle {}", errno);
902 - }
865 + THROW_LAST_ERROR_IF(Result < 0);
866
904 - StdFd[Index] = UnmarshalHandle.Output.FileDescriptor;
867 + Parsed.StdFd[Index] = UnmarshalHandle.Output.FileDescriptor;
868 }
869 }
870
@@ -909,75 +872,38 @@ Return Value:
872 // Unmarshal the fork token.
873 //
874
912 - memset(&UnmarshalForkToken, 0, sizeof(UnmarshalForkToken));
913 - UnmarshalForkToken.Input.ForkTokenId = CreateProcess->ForkTokenId;
875 + LXBUS_IPC_MESSAGE_UNMARSHAL_FORK_TOKEN_PARAMETERS UnmarshalForkToken{};
876 + UnmarshalForkToken.Input.ForkTokenId = Message->ForkTokenId;
877 Result = TEMP_FAILURE_RETRY(ioctl(MessageFd, LXBUS_IPC_MESSAGE_IOCTL_UNMARSHAL_FORK_TOKEN, &UnmarshalForkToken));
915 - if (Result < 0)
916 - {
917 - FATAL_ERROR("Failed to unmarshal fork token {}", errno);
918 - }
878 + THROW_LAST_ERROR_IF(Result < 0);
879
880 //
881 // Unmarshal the ipc server.
882 //
883
924 - if (CreateProcess->IpcServerId != LXBUS_IPC_SERVER_ID_INVALID)
884 + if (Message->IpcServerId != LXBUS_IPC_SERVER_ID_INVALID)
885 {
926 - memset(&UnmarshalServer, 0, sizeof(UnmarshalServer));
927 - UnmarshalServer.Input.ServerId = CreateProcess->IpcServerId;
886 + LXBUS_IPC_MESSAGE_UNMARSHAL_SERVER_PARAMETERS UnmarshalServer{};
887 + UnmarshalServer.Input.ServerId = Message->IpcServerId;
888 Result = TEMP_FAILURE_RETRY(ioctl(MessageFd, LXBUS_IPC_MESSAGE_IOCTL_UNMARSHAL_SERVER, &UnmarshalServer));
929 - if (Result < 0)
930 - {
931 - FATAL_ERROR("Failed to unmarshal ipc server {}", errno);
932 - }
889 + THROW_LAST_ERROR_IF(Result < 0);
890
934 - if (CreateProcessParsed->Common.AllowOOBE)
891 + if (Parsed.Common.AllowOOBE)
892 {
893 wil::unique_fd LxBusFd{TEMP_FAILURE_RETRY(open(LXBUS_DEVICE_NAME, O_RDWR))};
937 - if (!LxBusFd)
938 - {
939 - FATAL_ERROR("Failed to open LxBus device {}", errno);
940 - }
894 + THROW_LAST_ERROR_IF(!LxBusFd);
895
896 LXBUS_CONNECT_SERVER_PARAMETERS ConnectParams{};
897 ConnectParams.Input.Flags = LXBUS_IPC_CONNECT_FLAG_UNNAMED_SERVER;
898 ConnectParams.Input.TimeoutMs = LXBUS_IPC_INFINITE_TIMEOUT;
945 - int Result = TEMP_FAILURE_RETRY(ioctl(LxBusFd.get(), LXBUS_IOCTL_CONNECT_SERVER, &ConnectParams));
946 - if (Result < 0)
947 - {
948 - FATAL_ERROR("Failed to connect to LxBus server {}", errno);
949 - }
950 -
951 - CreateProcessParsed->ServiceFd = ConnectParams.Output.MessagePort;
952 - }
953 - }
954 -
955 - //
956 - // Populate the input parameter.
957 - //
958 -
959 - CreateProcessParsed->EventFd = EventFd;
960 - EventFd = -1;
961 - memcpy(CreateProcessParsed->StdFd, StdFd, sizeof(StdFd));
962 - memset(StdFd, -1, sizeof(StdFd));
963 - CreateProcessParsed->TtyFd = TtyFd;
964 - Result = 0;
965 -
966 -CreateProcessParseEnd:
967 - if (EventFd != -1)
968 - {
969 - CLOSE(EventFd);
970 - }
899 + Result = TEMP_FAILURE_RETRY(ioctl(LxBusFd.get(), LXBUS_IOCTL_CONNECT_SERVER, &ConnectParams));
900 + THROW_LAST_ERROR_IF(Result < 0);
901
972 - for (Index = 0; Index < LX_INIT_STD_FD_COUNT; Index += 1)
973 - {
974 - if ((StdFd[Index] != -1) && (StdFd[Index] != TtyFd))
975 - {
976 - CLOSE(StdFd[Index]);
902 + Parsed.ServiceFd = ConnectParams.Output.MessagePort;
903 }
904 }
905
980 - return Result;
906 + return Parsed;
907 }
908
909 int CreateProcessParseCommon(PCREATE_PROCESS_PARSED_COMMON Parsed, gsl::span<gsl::byte> Buffer, const wsl::linux::WslDistributionConfig& Config)
@@ -1088,76 +1014,7 @@ try
1014 }
1015 CATCH_RETURN_ERRNO()
1016
1091 -void CreateProcessParseFree(PCREATE_PROCESS_PARSED CreateProcessParsed)
1092 -
1093 -/*++
1094 -
1095 -Routine Description:
1096 -
1097 - This routine frees a parsed create process message.
1098 -
1099 -Arguments:
1100 -
1101 - CreateProcessParsed - Supplies a parsed create process parameters to free.
1102 -
1103 -Return Value:
1104 -
1105 - None.
1106 -
1107 ---*/
1108 -
1109 -{
1110 - // TODO: Use unique_fds.
1111 -
1112 - if (CreateProcessParsed->EventFd != -1)
1113 - {
1114 - CLOSE(CreateProcessParsed->EventFd);
1115 - CreateProcessParsed->EventFd = -1;
1116 - }
1117 -
1118 - for (int StdFdIndex = 0; StdFdIndex < LX_INIT_STD_FD_COUNT; StdFdIndex += 1)
1119 - {
1120 - if ((CreateProcessParsed->StdFd[StdFdIndex] != -1) && (CreateProcessParsed->StdFd[StdFdIndex] != CreateProcessParsed->TtyFd))
1121 - {
1122 - CLOSE(CreateProcessParsed->StdFd[StdFdIndex]);
1123 - CreateProcessParsed->StdFd[StdFdIndex] = -1;
1124 - }
1125 - }
1126 -
1127 - if (CreateProcessParsed->ServiceFd != -1)
1128 - {
1129 - CLOSE(CreateProcessParsed->ServiceFd);
1130 - CreateProcessParsed->ServiceFd = -1;
1131 - }
1132 -}
1133 -
1134 -void CreateProcessParseInitialize(PCREATE_PROCESS_PARSED CreateProcessParsed)
1135 -
1136 -/*++
1137 -
1138 -Routine Description:
1139 -
1140 - This routine initializes a parsed create process message.
1141 -
1142 -Arguments:
1143 -
1144 - CreateProcessParsed - Supplies a parsed create process parameters to
1145 - initialize.
1146 -
1147 -Return Value:
1148 -
1149 - None.
1150 -
1151 ---*/
1152 -
1153 -{
1154 - memset(CreateProcessParsed, 0, sizeof(*CreateProcessParsed));
1155 - memset(CreateProcessParsed->StdFd, -1, sizeof(CreateProcessParsed->StdFd));
1156 - CreateProcessParsed->TtyFd = -1;
1157 - CreateProcessParsed->EventFd = -1;
1158 -}
1159 -
1160 -int CreateProcessReplyToServer(PCREATE_PROCESS_PARSED CreateProcessParsed, pid_t CreateProcessPid, int MessageFd)
1017 +int CreateProcessReplyToServer(PCREATE_PROCESS_PARSED Parsed, pid_t CreateProcessPid, int MessageFd)
1018
1019 /*++
1020
@@ -1167,10 +1024,12 @@ Routine Description:
1024
1025 Arguments:
1026
1170 - MessageFd - Supplies a message port file descriptor.
1027 + Parsed - Supplies a pointer to a create process parsed structure.
1028
1029 CreateProcessPid - Supplies the pid of a newly created child process.
1030
1031 + MessageFd - Supplies a message port file descriptor.
1032 +
1033 Return Value:
1034
1035 0 on success, -1 on failure.
@@ -1180,32 +1039,31 @@ Return Value:
1039 --*/
1040
1041 {
1183 - ssize_t Bytes;
1184 - uint64_t EventFdData;
1185 - LXBUS_IPC_MESSAGE_MARSHAL_PROCESS_PARAMETERS MarshalProcess;
1186 - int Result;
1042 + auto terminateChild = wil::scope_exit([CreateProcessPid]() {
1043 + if (kill(CreateProcessPid, SIGKILL) < 0)
1044 + {
1045 + FATAL_ERROR("Failed to kill child process {}", errno);
1046 + }
1047 + });
1048
1049 //
1050 // Marshal the pid of the new child process and send a message
1051 // indicating that the child was created.
1052 //
1053
1193 - memset(&MarshalProcess, 0, sizeof(MarshalProcess));
1054 + LXBUS_IPC_MESSAGE_MARSHAL_PROCESS_PARAMETERS MarshalProcess{};
1055 MarshalProcess.Input.Process = CreateProcessPid;
1195 - Result = TEMP_FAILURE_RETRY(ioctl(MessageFd, LXBUS_IPC_MESSAGE_IOCTL_MARSHAL_PROCESS, &MarshalProcess));
1196 -
1197 - if (Result < 0)
1056 + if (TEMP_FAILURE_RETRY(ioctl(MessageFd, LXBUS_IPC_MESSAGE_IOCTL_MARSHAL_PROCESS, &MarshalProcess)) < 0)
1057 {
1058 LOG_ERROR("Failed to marshal pid {}", errno);
1200 - goto CreateProcessReplyToServerExit;
1059 + return -1;
1060 }
1061
1203 - Bytes = UtilWriteBuffer(MessageFd, &MarshalProcess.Output.ProcessId, sizeof(MarshalProcess.Output.ProcessId));
1062 + auto Bytes = UtilWriteBuffer(MessageFd, &MarshalProcess.Output.ProcessId, sizeof(MarshalProcess.Output.ProcessId));
1063 if (Bytes < 0)
1064 {
1206 - Result = -1;
1065 LOG_ERROR("Failed to write ProcessId {}", errno);
1208 - goto CreateProcessReplyToServerExit;
1066 + return -1;
1067 }
1068
1069 //
@@ -1214,42 +1072,28 @@ Return Value:
1072 //
1073
1074 Bytes = TEMP_FAILURE_RETRY(read(MessageFd, &MarshalProcess.Output.ProcessId, sizeof(MarshalProcess.Output.ProcessId)));
1217 -
1075 if (Bytes != sizeof(MarshalProcess.Output.ProcessId))
1076 {
1220 - Result = -1;
1077 LOG_ERROR("Failed to read (size {}) ProcessId {}", Bytes, errno);
1222 - goto CreateProcessReplyToServerExit;
1078 + return -1;
1079 }
1080
1081 if (MarshalProcess.Output.ProcessId == 0)
1082 {
1227 - Result = -1;
1083 LOG_ERROR("Server replied with failure");
1229 - goto CreateProcessReplyToServerExit;
1084 + return -1;
1085 }
1086
1232 - EventFdData = 1;
1233 - Bytes = UtilWriteBuffer(CreateProcessParsed->EventFd, &EventFdData, sizeof(EventFdData));
1087 + uint64_t EventFdData = 1;
1088 + Bytes = UtilWriteBuffer(Parsed->EventFd.get(), &EventFdData, sizeof(EventFdData));
1089 if (Bytes < 0)
1090 {
1236 - Result = -1;
1091 LOG_ERROR("Failed to write EventFd {}", errno);
1238 - goto CreateProcessReplyToServerExit;
1239 - }
1240 -
1241 - Result = 0;
1242 -
1243 -CreateProcessReplyToServerExit:
1244 - if (Result < 0)
1245 - {
1246 - if (kill(CreateProcessPid, SIGKILL) < 0)
1247 - {
1248 - FATAL_ERROR("Failed to kill child process {}", errno);
1249 - }
1092 + return -1;
1093 }
1094
1252 - return Result;
1095 + terminateChild.release();
1096 + return 0;
1097 }
1098
1099 int InitCreateSessionLeader(gsl::span<gsl::byte> Buffer, wsl::shared::SocketChannel& Channel, int LxBusFd, wsl::linux::WslDistributionConfig& Config)
@@ -1332,7 +1176,7 @@ try
1176 }
1177
1178 SessionLeader = UtilCreateChildProcess(
1335 - "SessionLeader", [SessionLeaderFd = std::move(SessionLeaderFd), TtyFd = std::move(TtyFd), &Channel, &Config]() {
1179 + "SessionLeader", [SessionLeaderFd = std::move(SessionLeaderFd), TtyFd = std::move(TtyFd), &Channel, &Config]() mutable {
1180 umask(Config.Umask);
1181 Channel.Close();
1182
@@ -2909,7 +2753,7 @@ try
2753 }
2754 CATCH_LOG();
2755
2912 -int SessionLeaderCreateProcess(gsl::span<gsl::byte> Buffer, int MessageFd, int TtyFd, const wsl::linux::WslDistributionConfig& Config)
2756 +void SessionLeaderCreateProcess(gsl::span<gsl::byte> Buffer, int MessageFd, int TtyFd, const wsl::linux::WslDistributionConfig& Config)
2757
2758 /*++
2759
@@ -2929,31 +2773,18 @@ Arguments:
2773
2774 Return Value:
2775
2932 - 0 on success, -1 on failure.
2776 + None.
2777
2778 --*/
2779
2780 {
2937 - CREATE_PROCESS_PARSED CreateProcessParsed;
2938 - pid_t CreateProcessPid;
2939 - int Result;
2940 -
2781 //
2782 // Parse the create process message buffer and create the new child process.
2783 //
2784
2945 - CreateProcessParseInitialize(&CreateProcessParsed);
2946 - Result = CreateProcessParse(&CreateProcessParsed, Buffer, MessageFd, TtyFd, Config);
2947 - if (Result < 0)
2948 - {
2949 - FATAL_ERROR("CreateProcessParse failed");
2950 - }
2951 -
2952 - CreateProcessPid = fork();
2953 - if (CreateProcessPid < 0)
2954 - {
2955 - FATAL_ERROR("fork failed for child process {}", errno);
2956 - }
2785 + CREATE_PROCESS_PARSED Parsed = CreateProcessParse(Buffer, MessageFd, Config);
2786 + auto CreateProcessPid = fork();
2787 + THROW_LAST_ERROR_IF(CreateProcessPid < 0);
2788
2789 if (CreateProcessPid > 0)
2790 {
@@ -2967,21 +2798,12 @@ Return Value:
2798 }
2799
2800 //
2970 - // If the fork was successful, reply with the new child pid.
2801 + // Reply with pid of the child process.
2802 //
2803
2973 - Result = CreateProcessReplyToServer(&CreateProcessParsed, CreateProcessPid, MessageFd);
2974 - if (Result < 0)
2975 - {
2976 - FATAL_ERROR("CreateProcessReplyToServer failed");
2977 - }
2804 + THROW_LAST_ERROR_IF(CreateProcessReplyToServer(&Parsed, CreateProcessPid, MessageFd) < 0);
2805
2979 - //
2980 - // Done.
2981 - //
2982 -
2983 - Result = 0;
2984 - goto SessionLeaderCreateProcessEnd;
2806 + return;
2807 }
2808
2809 //
@@ -2991,7 +2813,7 @@ Return Value:
2813 // If a separate foreground process group does not exist, create one here.
2814 //
2815
2994 - Result = 0;
2816 + int Result = 0;
2817 if (g_SessionGroup != -1)
2818 {
2819 //
@@ -3007,11 +2829,7 @@ Return Value:
2829 // Create a new process group.
2830 //
2831
3010 - Result = setpgid(0, 0);
3011 - if (Result < 0)
3012 - {
3013 - FATAL_ERROR("setpgid failed {}", errno);
3014 - }
2832 + THROW_LAST_ERROR_IF(setpgid(0, 0) < 0);
2833 }
2834
2835 //
@@ -3032,8 +2850,7 @@ Return Value:
2850 // stopping the process (waiting for SIGCONT to continue).
2851 //
2852
3035 - Result = tcsetpgrp(CreateProcessParsed.TtyFd, getpgid(0));
3036 - if (Result < 0)
2853 + if (tcsetpgrp(TtyFd, getpgid(0)) < 0)
2854 {
2855 LOG_ERROR("tcsetpgrp failed {}", errno);
2856 }
@@ -3043,17 +2860,13 @@ Return Value:
2860 //
2861
2862 //
3046 - // Resources are not released for the child process because it will call
3047 - // execv.
2863 + // Resources are not released for the child process because it will call execv.
2864 //
2865 // N.B. CreateProcess does not return.
2866 //
2867
3052 - CreateProcess(&CreateProcessParsed, Config);
3053 -
3054 -SessionLeaderCreateProcessEnd:
3055 - CreateProcessParseFree(&CreateProcessParsed);
3056 - return Result;
2868 + CreateProcess(&Parsed, TtyFd, Config);
2869 + FATAL_ERROR("CreateProcess not expected to return");
2870 }
2871
2872 void SessionLeaderSigchldHandler(__attribute__((unused)) int Signal, __attribute__((unused)) siginfo_t* SigInfo, __attribute__((unused)) void* UContext)
@@ -3245,22 +3058,16 @@ Return Value:
3058 FATAL_ERROR("Invalid message size {}", Message.size());
3059 }
3060
3248 - switch (Header->MessageType)
3061 + if (Header->MessageType == LxInitMessageCreateProcess)
3062 + {
3063 + SessionLeaderCreateProcess(Message, MessageFd, TtyFd, Config);
3064 + }
3065 + else
3066 {
3250 - case LxInitMessageCreateProcess:
3251 - if (SessionLeaderCreateProcess(Message, MessageFd, TtyFd, Config) < 0)
3252 - {
3253 - FATAL_ERROR("SessionLeaderCreateProcess failed");
3254 - }
3255 -
3256 - break;
3257 -
3258 - default:
3067 FATAL_ERROR("Unexpected message {}", Header->MessageType);
3068 }
3069 }
3070
3263 - CLOSE(MessageFd);
3071 FATAL_ERROR("Session leader not expected to exit");
3072 return;
3073 }