| 1112 | otherwise. */ |
| 1113 | |
| 1114 | static int |
| 1115 | pipe_child (pid_t *pid, int pipefds[2], int tempfd, bool decompress, |
| 1116 | size_t tries) |
| 1117 | { |
| 1118 | char const *resolved_compress_program; |
| 1119 | struct tempnode *saved_temphead; |
| 1120 | double wait_retry = 0.25; |
| 1121 | struct cs_status cs; |
| 1122 | int result; |
| 1123 | posix_spawnattr_t attr; |
| 1124 | posix_spawn_file_actions_t actions; |
| 1125 | |
| 1126 | /* Lookup the program before we spawn, so that we consistently |
| 1127 | handle access issues to COMPRESS_PROGRAM, because on some |
| 1128 | implementations/emulations of posix_spawn we get only a |
| 1129 | generic (fatal) error from the child in that case. */ |
| 1130 | resolved_compress_program = get_resolved_compress_program (); |
| 1131 | if (resolved_compress_program == NULL) |
| 1132 | return errno; |
| 1133 | |
| 1134 | if ((result = posix_spawnattr_init (&attr))) |
| 1135 | return result; |
| 1136 | if ((result = posix_spawnattr_setflags (&attr, POSIX_SPAWN_USEVFORK)) |
| 1137 | || (result = posix_spawn_file_actions_init (&actions))) |
| 1138 | { |
| 1139 | posix_spawnattr_destroy (&attr); |
| 1140 | return result; |
| 1141 | } |
| 1142 | |
| 1143 | if (pipe2 (pipefds, O_CLOEXEC) < 0) |
| 1144 | { |
| 1145 | int saved_errno = errno; |
| 1146 | posix_spawnattr_destroy (&attr); |
| 1147 | posix_spawn_file_actions_destroy (&actions); |
| 1148 | return saved_errno; |
| 1149 | } |
| 1150 | |
| 1151 | if ((result = posix_spawn_file_actions_addclose (&actions, STDIN_FILENO)) |
| 1152 | || (result = posix_spawn_file_actions_addclose (&actions, STDOUT_FILENO)) |
| 1153 | || (decompress |
| 1154 | ? ((result = posix_spawn_file_actions_addclose (&actions, |
| 1155 | pipefds[0])) |
| 1156 | || (result = posix_spawn_file_actions_move_fd (&actions, tempfd, |
| 1157 | STDIN_FILENO)) |
| 1158 | || (result = posix_spawn_file_actions_move_fd (&actions, |
| 1159 | pipefds[1], |
| 1160 | STDOUT_FILENO))) |
| 1161 | : ((result = posix_spawn_file_actions_addclose (&actions, |
| 1162 | pipefds[1])) |
| 1163 | || (result = posix_spawn_file_actions_move_fd (&actions, tempfd, |
| 1164 | STDOUT_FILENO)) |
| 1165 | || (result = posix_spawn_file_actions_move_fd (&actions, |
| 1166 | pipefds[0], |
| 1167 | STDIN_FILENO))))) |
| 1168 | { |
| 1169 | close (pipefds[0]); |
| 1170 | close (pipefds[1]); |
| 1171 | posix_spawnattr_destroy (&attr); |
no test coverage detected