| @@ -2291,26 +2291,31 @@ create_filesystem_object(struct archive_ | | | @@ -2291,26 +2291,31 @@ create_filesystem_object(struct archive_ |
2291 | if (r != ARCHIVE_OK) { | | 2291 | if (r != ARCHIVE_OK) { |
2292 | archive_set_error(&a->archive, error_number, "%s", | | 2292 | archive_set_error(&a->archive, error_number, "%s", |
2293 | error_string.s); | | 2293 | error_string.s); |
2294 | free(linkname_copy); | | 2294 | free(linkname_copy); |
2295 | archive_string_free(&error_string); | | 2295 | archive_string_free(&error_string); |
2296 | /* | | 2296 | /* |
2297 | * EPERM is more appropriate than error_number for our | | 2297 | * EPERM is more appropriate than error_number for our |
2298 | * callers | | 2298 | * callers |
2299 | */ | | 2299 | */ |
2300 | return (EPERM); | | 2300 | return (EPERM); |
2301 | } | | 2301 | } |
2302 | free(linkname_copy); | | 2302 | free(linkname_copy); |
2303 | archive_string_free(&error_string); | | 2303 | archive_string_free(&error_string); |
| | | 2304 | /* |
| | | 2305 | * Unlinking and linking here is really not atomic, |
| | | 2306 | * but doing it right, would require us to construct |
| | | 2307 | * an mktemplink() function, and then use rename(2). |
| | | 2308 | */ |
2304 | if (a->flags & ARCHIVE_EXTRACT_ATOMIC) | | 2309 | if (a->flags & ARCHIVE_EXTRACT_ATOMIC) |
2305 | unlink(a->name); | | 2310 | unlink(a->name); |
2306 | r = link(linkname, a->name) ? errno : 0; | | 2311 | r = link(linkname, a->name) ? errno : 0; |
2307 | /* | | 2312 | /* |
2308 | * New cpio and pax formats allow hardlink entries | | 2313 | * New cpio and pax formats allow hardlink entries |
2309 | * to carry data, so we may have to open the file | | 2314 | * to carry data, so we may have to open the file |
2310 | * for hardlink entries. | | 2315 | * for hardlink entries. |
2311 | * | | 2316 | * |
2312 | * If the hardlink was successfully created and | | 2317 | * If the hardlink was successfully created and |
2313 | * the archive doesn't have carry data for it, | | 2318 | * the archive doesn't have carry data for it, |
2314 | * consider it to be non-authoritative for meta data. | | 2319 | * consider it to be non-authoritative for meta data. |
2315 | * This is consistent with GNU tar and BSD pax. | | 2320 | * This is consistent with GNU tar and BSD pax. |
2316 | * If the hardlink does carry data, let the last | | 2321 | * If the hardlink does carry data, let the last |
| @@ -2331,27 +2336,35 @@ create_filesystem_object(struct archive_ | | | @@ -2331,27 +2336,35 @@ create_filesystem_object(struct archive_ |
2331 | a->fd = open(a->name, O_WRONLY | O_TRUNC | | | 2336 | a->fd = open(a->name, O_WRONLY | O_TRUNC | |
2332 | O_BINARY | O_CLOEXEC | O_NOFOLLOW); | | 2337 | O_BINARY | O_CLOEXEC | O_NOFOLLOW); |
2333 | __archive_ensure_cloexec_flag(a->fd); | | 2338 | __archive_ensure_cloexec_flag(a->fd); |
2334 | if (a->fd < 0) | | 2339 | if (a->fd < 0) |
2335 | r = errno; | | 2340 | r = errno; |
2336 | } | | 2341 | } |
2337 | } | | 2342 | } |
2338 | return (r); | | 2343 | return (r); |
2339 | #endif | | 2344 | #endif |
2340 | } | | 2345 | } |
2341 | linkname = archive_entry_symlink(a->entry); | | 2346 | linkname = archive_entry_symlink(a->entry); |
2342 | if (linkname != NULL) { | | 2347 | if (linkname != NULL) { |
2343 | #if HAVE_SYMLINK | | 2348 | #if HAVE_SYMLINK |
2344 | int error = symlink(linkname, a->name) ? errno : 0; | | 2349 | int error; |
| | | 2350 | /* |
| | | 2351 | * Unlinking and linking here is really not atomic, |
| | | 2352 | * but doing it right, would require us to construct |
| | | 2353 | * an mktempsymlink() function, and then use rename(2). |
| | | 2354 | */ |
| | | 2355 | if (a->flags & ARCHIVE_EXTRACT_ATOMIC) |
| | | 2356 | unlink(a->name); |
| | | 2357 | error = symlink(linkname, a->name) ? errno : 0; |
2345 | if (error == 0) { | | 2358 | if (error == 0) { |
2346 | #ifdef HAVE_LSTAT | | 2359 | #ifdef HAVE_LSTAT |
2347 | r = lstat(a->name, &st); | | 2360 | r = lstat(a->name, &st); |
2348 | #else | | 2361 | #else |
2349 | r = la_stat(a->name, &st); | | 2362 | r = la_stat(a->name, &st); |
2350 | #endif | | 2363 | #endif |
2351 | if (r == -1) | | 2364 | if (r == -1) |
2352 | return errno; | | 2365 | return errno; |
2353 | error = symlink_add(a, &st); | | 2366 | error = symlink_add(a, &st); |
2354 | } | | 2367 | } |
2355 | return error; | | 2368 | return error; |
2356 | #else | | 2369 | #else |
2357 | return (EPERM); | | 2370 | return (EPERM); |