| 172 | } |
| 173 | |
| 174 | void FileDescriptorInfo::ReopenOrDetach(fail_fn_t fail_fn, bool prefer_detach_to_dev_null) const { |
| 175 | if (is_sock) { |
| 176 | // Sockets are always "detached" by replacing their FD with /dev/null. |
| 177 | LOGD("Detaching socket FD %d to /dev/null", fd); |
| 178 | return Detach(fail_fn); |
| 179 | } |
| 180 | |
| 181 | // For non-sockets: |
| 182 | if (prefer_detach_to_dev_null) { |
| 183 | LOGD("Detaching non-socket FD %d (path: %s) to /dev/null due to preference.", fd, file_path.c_str()); |
| 184 | return Detach(fail_fn); |
| 185 | } |
| 186 | |
| 187 | // Original logic for reopening regular files if not detaching. |
| 188 | LOGD("Reopening non-socket FD %d (path: %s) normally.", fd, file_path.c_str()); |
| 189 | // NOTE: This might happen if the file was unlinked after being opened. |
| 190 | // It's a common pattern in the case of temporary files and the like but |
| 191 | // we should not allow such usage from the zygote. |
| 192 | const int new_fd = TEMP_FAILURE_RETRY(open(file_path.c_str(), open_flags)); |
| 193 | if (new_fd == -1) { |
| 194 | fail_fn(android::base::StringPrintf("Failed open(%s, %i): %s", |
| 195 | file_path.c_str(), |
| 196 | open_flags, |
| 197 | strerror(errno))); |
| 198 | return; |
| 199 | } |
| 200 | if (TEMP_FAILURE_RETRY(fcntl(new_fd, F_SETFD, fd_flags)) == -1) { |
| 201 | close(new_fd); |
| 202 | fail_fn(android::base::StringPrintf("Failed fcntl(%d, F_SETFD, %d) (%s): %s", |
| 203 | new_fd, |
| 204 | fd_flags, |
| 205 | file_path.c_str(), |
| 206 | strerror(errno))); |
| 207 | return; |
| 208 | } |
| 209 | if (TEMP_FAILURE_RETRY(fcntl(new_fd, F_SETFL, fs_flags)) == -1) { |
| 210 | close(new_fd); |
| 211 | fail_fn(android::base::StringPrintf("Failed fcntl(%d, F_SETFL, %d) (%s): %s", |
| 212 | new_fd, |
| 213 | fs_flags, |
| 214 | file_path.c_str(), |
| 215 | strerror(errno))); |
| 216 | return; |
| 217 | } |
| 218 | if (offset != -1 && TEMP_FAILURE_RETRY(lseek64(new_fd, offset, SEEK_SET)) == -1) { |
| 219 | close(new_fd); |
| 220 | fail_fn(android::base::StringPrintf("Failed lseek64(%d, %jd, SEEK_SET) (%s): %s", |
| 221 | new_fd, |
| 222 | (intmax_t)offset, |
| 223 | file_path.c_str(), |
| 224 | strerror(errno))); |
| 225 | return; |
| 226 | } |
| 227 | int dup_flags = (fd_flags & FD_CLOEXEC) ? O_CLOEXEC : 0; |
| 228 | if (TEMP_FAILURE_RETRY(dup3(new_fd, fd, dup_flags)) == -1) { |
| 229 | close(new_fd); |
| 230 | fail_fn(android::base::StringPrintf("Failed dup3(%d, %d, %d) (%s): %s", |
| 231 | new_fd, // Corrected order: new_fd, fd |
no test coverage detected