rpm: use "create+rename" method of replacing existing files
Users were reporting getting errors like "ls: error while loading shared libraries: libc.so.6: ELF load command past end of file" while rpm was unpacking glibc tarball. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
10f5f9b10d
commit
2aec773688
@ -106,15 +106,28 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
|
|||||||
switch (file_header->mode & S_IFMT) {
|
switch (file_header->mode & S_IFMT) {
|
||||||
case S_IFREG: {
|
case S_IFREG: {
|
||||||
/* Regular file */
|
/* Regular file */
|
||||||
|
char *dst_name;
|
||||||
int flags = O_WRONLY | O_CREAT | O_EXCL;
|
int flags = O_WRONLY | O_CREAT | O_EXCL;
|
||||||
if (archive_handle->ah_flags & ARCHIVE_O_TRUNC)
|
if (archive_handle->ah_flags & ARCHIVE_O_TRUNC)
|
||||||
flags = O_WRONLY | O_CREAT | O_TRUNC;
|
flags = O_WRONLY | O_CREAT | O_TRUNC;
|
||||||
dst_fd = xopen3(file_header->name,
|
dst_name = file_header->name;
|
||||||
|
#ifdef ARCHIVE_REPLACE_VIA_RENAME
|
||||||
|
if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME)
|
||||||
|
/* rpm-style temp file name */
|
||||||
|
dst_name = xasprintf("%s;%x", dst_name, (int)getpid());
|
||||||
|
#endif
|
||||||
|
dst_fd = xopen3(dst_name,
|
||||||
flags,
|
flags,
|
||||||
file_header->mode
|
file_header->mode
|
||||||
);
|
);
|
||||||
bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size);
|
bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size);
|
||||||
close(dst_fd);
|
close(dst_fd);
|
||||||
|
#ifdef ARCHIVE_REPLACE_VIA_RENAME
|
||||||
|
if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) {
|
||||||
|
xrename(dst_name, file_header->name);
|
||||||
|
free(dst_name);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case S_IFDIR:
|
case S_IFDIR:
|
||||||
|
@ -242,8 +242,8 @@ static void extract_cpio(int fd, const char *source_rpm)
|
|||||||
/* compat: overwrite existing files.
|
/* compat: overwrite existing files.
|
||||||
* try "rpm -i foo.src.rpm" few times in a row -
|
* try "rpm -i foo.src.rpm" few times in a row -
|
||||||
* standard rpm will not complain.
|
* standard rpm will not complain.
|
||||||
* (TODO? real rpm creates "file;1234" and then renames it) */
|
*/
|
||||||
| ARCHIVE_UNLINK_OLD;
|
| ARCHIVE_REPLACE_VIA_RENAME;
|
||||||
archive_handle->src_fd = fd;
|
archive_handle->src_fd = fd;
|
||||||
/*archive_handle->offset = 0; - init_handle() did it */
|
/*archive_handle->offset = 0; - init_handle() did it */
|
||||||
|
|
||||||
|
@ -122,6 +122,9 @@ typedef struct archive_handle_t {
|
|||||||
#define ARCHIVE_NUMERIC_OWNER (1 << 7)
|
#define ARCHIVE_NUMERIC_OWNER (1 << 7)
|
||||||
#define ARCHIVE_O_TRUNC (1 << 8)
|
#define ARCHIVE_O_TRUNC (1 << 8)
|
||||||
#define ARCHIVE_REMEMBER_NAMES (1 << 9)
|
#define ARCHIVE_REMEMBER_NAMES (1 << 9)
|
||||||
|
#if ENABLE_RPM
|
||||||
|
#define ARCHIVE_REPLACE_VIA_RENAME (1 << 10)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* POSIX tar Header Block, from POSIX 1003.1-1990 */
|
/* POSIX tar Header Block, from POSIX 1003.1-1990 */
|
||||||
|
Loading…
Reference in New Issue
Block a user