diff --git a/native/src/base/files.cpp b/native/src/base/files.cpp index 0a7233ce0..0896df136 100644 --- a/native/src/base/files.cpp +++ b/native/src/base/files.cpp @@ -23,19 +23,21 @@ int fd_pathat(int dirfd, const char *name, char *path, size_t size) { return 0; } -int mkdirs(string path, mode_t mode) { +int mkdirs(const char *path, mode_t mode) { + char buf[4096]; + strlcpy(buf, path, sizeof(buf)); errno = 0; - for (char *p = path.data() + 1; *p; ++p) { + for (char *p = &buf[1]; *p; ++p) { if (*p == '/') { *p = '\0'; - if (mkdir(path.data(), mode) == -1) { + if (mkdir(buf, mode) == -1) { if (errno != EEXIST) return -1; } *p = '/'; } } - if (mkdir(path.data(), mode) == -1) { + if (mkdir(buf, mode) == -1) { if (errno != EEXIST) return -1; } diff --git a/native/src/base/files.hpp b/native/src/base/files.hpp index cb62f8fd6..787c489ae 100644 --- a/native/src/base/files.hpp +++ b/native/src/base/files.hpp @@ -60,7 +60,7 @@ struct mmap_data : public byte_data { ssize_t fd_path(int fd, char *path, size_t size); int fd_pathat(int dirfd, const char *name, char *path, size_t size); -int mkdirs(std::string path, mode_t mode); +int mkdirs(const char *path, mode_t mode); void rm_rf(const char *path); void mv_path(const char *src, const char *dest); void mv_dir(int src, int dest); diff --git a/native/src/boot/cpio.cpp b/native/src/boot/cpio.cpp index 5c63fd61f..e2f9696bb 100644 --- a/native/src/boot/cpio.cpp +++ b/native/src/boot/cpio.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -79,17 +80,21 @@ void cpio::extract_entry(const entry_map::value_type &e, const char *file) { fprintf(stderr, "Extract [%s] to [%s]\n", e.first.data(), file); unlink(file); rmdir(file); + // Make sure parent folders exist + char *parent = dirname(file); + xmkdirs(parent, 0755); if (S_ISDIR(e.second->mode)) { - ::mkdir(file, e.second->mode & 0777); + xmkdir(file, e.second->mode & 0777); } else if (S_ISREG(e.second->mode)) { - int fd = creat(file, e.second->mode & 0777); + int fd = xopen(file, O_CREAT | O_WRONLY | O_TRUNC, e.second->mode & 0777); xwrite(fd, e.second->data, e.second->filesize); fchown(fd, e.second->uid, e.second->gid); close(fd); - } else if (S_ISLNK(e.second->mode)) { - auto target = strndup((char *) e.second->data, e.second->filesize); + } else if (S_ISLNK(e.second->mode) && e.second->filesize < 4096) { + char target[4096]; + memcpy(target, e.second->data, e.second->filesize); + target[e.second->filesize] = '\0'; symlink(target, file); - free(target); } }