diff options
author | Mohamad Ayyash <mkayyash@google.com> | 2016-03-31 18:12:57 -0700 |
---|---|---|
committer | Mohamad Ayyash <mkayyash@google.com> | 2016-04-04 12:43:37 -0700 |
commit | 933026301cb9d41b4b8b8273d892ea71c1c3d04b (patch) | |
tree | 54c706e42ef217c39b44ab7692de082ea031c80b | |
parent | 531e36ae0ef363fdddd519322763cbb35b109f4d (diff) | |
download | squashfs-tools-933026301cb9d41b4b8b8273d892ea71c1c3d04b.tar.gz |
Make squashfs work on BSD and macOS
Based on https://github.com/vasi/squashfs-tools
Change-Id: Ia2b04541652ef4f0cf8d6ff1daf106d6db32e278
Signed-off-by: Mohamad Ayyash <mkayyash@google.com>
-rw-r--r-- | squashfs-tools/Android.mk | 2 | ||||
-rw-r--r-- | squashfs-tools/action.c | 9 | ||||
-rw-r--r-- | squashfs-tools/info.c | 25 | ||||
-rw-r--r-- | squashfs-tools/mksquashfs.c | 83 | ||||
-rw-r--r-- | squashfs-tools/mksquashfs.h | 1 | ||||
-rw-r--r-- | squashfs-tools/pseudo.c | 1 | ||||
-rw-r--r-- | squashfs-tools/read_xattrs.c | 4 | ||||
-rw-r--r-- | squashfs-tools/unsquashfs.c | 6 | ||||
-rw-r--r-- | squashfs-tools/unsquashfs.h | 4 | ||||
-rw-r--r-- | squashfs-tools/unsquashfs_info.c | 25 | ||||
-rw-r--r-- | squashfs-tools/unsquashfs_xattr.c | 5 | ||||
-rw-r--r-- | squashfs-tools/xattr.c | 15 |
12 files changed, 115 insertions, 65 deletions
diff --git a/squashfs-tools/Android.mk b/squashfs-tools/Android.mk index 4d7f6bc..31d2356 100644 --- a/squashfs-tools/Android.mk +++ b/squashfs-tools/Android.mk @@ -5,7 +5,7 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) # squashfs-tools depends on Linux Kernel specific headers (e.g. sysinfo.h). -LOCAL_MODULE_HOST_OS := linux +LOCAL_MODULE_HOST_OS := linux darwin # The LOCAL_MODULE name is referenced by the code. Don't change it. LOCAL_MODULE := mksquashfs diff --git a/squashfs-tools/action.c b/squashfs-tools/action.c index 35889a4..7e43f17 100644 --- a/squashfs-tools/action.c +++ b/squashfs-tools/action.c @@ -39,6 +39,10 @@ #include <limits.h> #include <errno.h> +#ifndef FNM_EXTMATCH /* glibc extension */ + #define FNM_EXTMATCH 0 +#endif + #include "squashfs_fs.h" #include "mksquashfs.h" #include "action.h" @@ -2284,9 +2288,12 @@ static char *get_start(char *s, int n) static int subpathname_fn(struct atom *atom, struct action_data *action_data) { - return fnmatch(atom->argv[0], get_start(strdupa(action_data->subpath), + char *path = strdup(action_data->subpath); + int is_match = fnmatch(atom->argv[0], get_start(path, count_components(atom->argv[0])), FNM_PATHNAME|FNM_PERIOD|FNM_EXTMATCH) == 0; + free(path); + return is_match; } /* diff --git a/squashfs-tools/info.c b/squashfs-tools/info.c index 7968c77..60a3f5a 100644 --- a/squashfs-tools/info.c +++ b/squashfs-tools/info.c @@ -134,31 +134,22 @@ void dump_state() void *info_thrd(void *arg) { sigset_t sigmask; - struct timespec timespec = { .tv_sec = 1, .tv_nsec = 0 }; - int sig, waiting = 0; + int sig, err, waiting = 0; sigemptyset(&sigmask); sigaddset(&sigmask, SIGQUIT); sigaddset(&sigmask, SIGHUP); + sigaddset(&sigmask, SIGALRM); while(1) { - if(waiting) - sig = sigtimedwait(&sigmask, NULL, ×pec); - else - sig = sigwaitinfo(&sigmask, NULL); + err = sigwait(&sigmask, &sig); - if(sig == -1) { + if(err == -1) { switch(errno) { - case EAGAIN: - /* interval timed out */ - waiting = 0; - /* FALLTHROUGH */ case EINTR: - /* if waiting, the wait will be longer, but - that's OK */ continue; default: - BAD_ERROR("sigtimedwait/sigwaitinfo failed " + BAD_ERROR("sigwait failed " "because %s\n", strerror(errno)); } } @@ -169,8 +160,12 @@ void *info_thrd(void *arg) /* set one second interval period, if ^\ received within then, dump queue and cache status */ waiting = 1; - } else + alarm(1); + } else if (sig == SIGQUIT) { dump_state(); + } else if (sig == SIGALRM) { + waiting = 0; + } } } diff --git a/squashfs-tools/mksquashfs.c b/squashfs-tools/mksquashfs.c index 6c81710..2c1492a 100644 --- a/squashfs-tools/mksquashfs.c +++ b/squashfs-tools/mksquashfs.c @@ -51,6 +51,10 @@ #include <limits.h> #include <ctype.h> +#ifndef FNM_EXTMATCH /* glibc extension */ + #define FNM_EXTMATCH 0 +#endif + #ifndef linux #define __BYTE_ORDER BYTE_ORDER #define __BIG_ENDIAN BIG_ENDIAN @@ -838,13 +842,13 @@ char *subpathname(struct dir_ent *dir_ent) } -inline unsigned int get_inode_no(struct inode_info *inode) +static inline unsigned int get_inode_no(struct inode_info *inode) { return inode->inode_number; } -inline unsigned int get_parent_no(struct dir_info *dir) +static inline unsigned int get_parent_no(struct dir_info *dir) { return dir->depth ? get_inode_no(dir->dir_ent->inode) : inode_no; } @@ -2037,7 +2041,7 @@ struct file_info *duplicate(long long file_size, long long bytes, } -inline int is_fragment(struct inode_info *inode) +static inline int is_fragment(struct inode_info *inode) { off_t file_size = inode->buf.st_size; @@ -3000,19 +3004,19 @@ struct inode_info *lookup_inode3(struct stat *buf, int pseudo, int id, } -struct inode_info *lookup_inode2(struct stat *buf, int pseudo, int id) +static inline struct inode_info *lookup_inode2(struct stat *buf, int pseudo, int id) { return lookup_inode3(buf, pseudo, id, NULL, 0); } -inline struct inode_info *lookup_inode(struct stat *buf) +static inline struct inode_info *lookup_inode(struct stat *buf) { return lookup_inode2(buf, 0, 0); } -inline void alloc_inode_no(struct inode_info *inode, unsigned int use_this) +static inline void alloc_inode_no(struct inode_info *inode, unsigned int use_this) { if (inode->inode_number == 0) { inode->inode_number = use_this ? : inode_no ++; @@ -3023,7 +3027,7 @@ inline void alloc_inode_no(struct inode_info *inode, unsigned int use_this) } -inline struct dir_ent *create_dir_entry(char *name, char *source_name, +static inline struct dir_ent *create_dir_entry(char *name, char *source_name, char *nonstandard_pathname, struct dir_info *dir) { struct dir_ent *dir_ent = malloc(sizeof(struct dir_ent)); @@ -3046,7 +3050,7 @@ inline struct dir_ent *create_dir_entry(char *name, char *source_name, } -inline void add_dir_entry(struct dir_ent *dir_ent, struct dir_info *sub_dir, +static inline void add_dir_entry(struct dir_ent *dir_ent, struct dir_info *sub_dir, struct inode_info *inode_info) { struct dir_info *dir = dir_ent->our_dir; @@ -3082,18 +3086,7 @@ inline void add_dir_entry(struct dir_ent *dir_ent, struct dir_info *sub_dir, dir->count++; } -/* ANDROID CHANGES START*/ -#ifdef ANDROID -/* Weird linker bug that complains those inline functions are undefined. */ -extern inline void add_dir_entry(struct dir_ent *dir_ent, struct dir_info *sub_dir, - struct inode_info *inode_info); -extern inline void add_dir_entry2(char *name, char *source_name, - char *nonstandard_pathname, struct dir_info *sub_dir, - struct inode_info *inode_info, struct dir_info *dir); -#endif -/* ANDROID CHANGES END */ - -inline void add_dir_entry2(char *name, char *source_name, +static inline void add_dir_entry2(char *name, char *source_name, char *nonstandard_pathname, struct dir_info *sub_dir, struct inode_info *inode_info, struct dir_info *dir) { @@ -3105,7 +3098,7 @@ inline void add_dir_entry2(char *name, char *source_name, } -inline void free_dir_entry(struct dir_ent *dir_ent) +static inline void free_dir_entry(struct dir_ent *dir_ent) { if(dir_ent->name) free(dir_ent->name); @@ -3126,7 +3119,7 @@ inline void free_dir_entry(struct dir_ent *dir_ent) } -inline void add_excluded(struct dir_info *dir) +static inline void add_excluded(struct dir_info *dir) { dir->excluded ++; } @@ -4258,6 +4251,7 @@ void initialise_threads(int readq, int fragq, int bwriteq, int fwriteq, sigemptyset(&sigmask); sigaddset(&sigmask, SIGQUIT); sigaddset(&sigmask, SIGHUP); + sigaddset(&sigmask, SIGALRM); if(pthread_sigmask(SIG_BLOCK, &sigmask, NULL) == -1) BAD_ERROR("Failed to set signal mask in intialise_threads\n"); @@ -5041,20 +5035,47 @@ int parse_num(char *arg, int *res) int get_physical_memory() { - /* - * Long longs are used here because with PAE, a 32-bit - * machine can have more than 4GB of physical memory - * - * sysconf(_SC_PHYS_PAGES) relies on /proc being mounted. - * If it isn't fail. - */ + int phys_mem; +#ifndef linux + #ifdef HW_MEMSIZE + #define SYSCTL_PHYSMEM HW_MEMSIZE + #elif defined(HW_PHYSMEM64) + #define SYSCTL_PHYSMEM HW_PHYSMEM64 + #else + #define SYSCTL_PHYSMEM HW_PHYSMEM + #endif + + int mib[2]; + uint64_t sysctl_physmem = 0; + size_t sysctl_len = sizeof(sysctl_physmem); + + mib[0] = CTL_HW; + mib[1] = SYSCTL_PHYSMEM; + + if(sysctl(mib, 2, &sysctl_physmem, &sysctl_len, NULL, 0) == 0) { + /* some systems use 32-bit values, work with what we're given */ + if (sysctl_len == 4) + sysctl_physmem = *(uint32_t*)&sysctl_physmem; + phys_mem = sysctl_physmem >> 20; + } else { + ERROR_START("Failed to get amount of available " + "memory."); + ERROR_EXIT(" Defaulting to least viable amount\n"); + phys_mem = SQUASHFS_LOWMEM; + } + #undef SYSCTL_PHYSMEM +#else + /* Long longs are used here because with PAE, a 32-bit + machine can have more than 4GB of physical memory */ + long long num_pages = sysconf(_SC_PHYS_PAGES); long long page_size = sysconf(_SC_PAGESIZE); - int phys_mem = num_pages * page_size >> 20; - + phys_mem = num_pages * page_size >> 20; if(num_pages == -1 || page_size == -1) return 0; +#endif + if(phys_mem < SQUASHFS_LOWMEM) BAD_ERROR("Mksquashfs requires more physical memory than is " "available!\n"); diff --git a/squashfs-tools/mksquashfs.h b/squashfs-tools/mksquashfs.h index 0a091cb..bfbf0bf 100644 --- a/squashfs-tools/mksquashfs.h +++ b/squashfs-tools/mksquashfs.h @@ -29,6 +29,7 @@ #include <stdint.h> #endif /* ANDROID CHANGES END */ +#include <pthread.h> struct dir_info { char *pathname; diff --git a/squashfs-tools/pseudo.c b/squashfs-tools/pseudo.c index da798f7..e12d399 100644 --- a/squashfs-tools/pseudo.c +++ b/squashfs-tools/pseudo.c @@ -30,6 +30,7 @@ #include <errno.h> #include <string.h> #include <stdlib.h> +#include <sys/stat.h> #include <sys/types.h> #include <sys/wait.h> #include <ctype.h> diff --git a/squashfs-tools/read_xattrs.c b/squashfs-tools/read_xattrs.c index 42106f5..837d3fb 100644 --- a/squashfs-tools/read_xattrs.c +++ b/squashfs-tools/read_xattrs.c @@ -39,13 +39,13 @@ #include <endian.h> #endif +#include <stdlib.h> + #include "squashfs_fs.h" #include "squashfs_swap.h" #include "xattr.h" #include "error.h" -#include <stdlib.h> - extern int read_fs_bytes(int, long long, int, void *); extern int read_block(int, long long, long long *, int, void *); diff --git a/squashfs-tools/unsquashfs.c b/squashfs-tools/unsquashfs.c index 1323dd6..7f46968 100644 --- a/squashfs-tools/unsquashfs.c +++ b/squashfs-tools/unsquashfs.c @@ -31,7 +31,12 @@ #include "unsquashfs_info.h" #include "stdarg.h" +#ifndef linux +#include <sys/sysctl.h> +#else #include <sys/sysinfo.h> +#endif + #include <sys/types.h> #include <sys/time.h> #include <sys/resource.h> @@ -2174,6 +2179,7 @@ void initialise_threads(int fragment_buffer_size, int data_buffer_size) sigemptyset(&sigmask); sigaddset(&sigmask, SIGQUIT); sigaddset(&sigmask, SIGHUP); + sigaddset(&sigmask, SIGALRM); if(pthread_sigmask(SIG_BLOCK, &sigmask, NULL) == -1) EXIT_UNSQUASH("Failed to set signal mask in initialise_threads" "\n"); diff --git a/squashfs-tools/unsquashfs.h b/squashfs-tools/unsquashfs.h index ecd0bb4..4836b8d 100644 --- a/squashfs-tools/unsquashfs.h +++ b/squashfs-tools/unsquashfs.h @@ -47,6 +47,10 @@ #include <sys/ioctl.h> #include <sys/time.h> +#ifndef FNM_EXTMATCH /* glibc extension */ + #define FNM_EXTMATCH 0 +#endif + #ifndef linux #define __BYTE_ORDER BYTE_ORDER #define __BIG_ENDIAN BIG_ENDIAN diff --git a/squashfs-tools/unsquashfs_info.c b/squashfs-tools/unsquashfs_info.c index c8e2b9b..7d4f7af 100644 --- a/squashfs-tools/unsquashfs_info.c +++ b/squashfs-tools/unsquashfs_info.c @@ -97,31 +97,22 @@ void dump_state() void *info_thrd(void *arg) { sigset_t sigmask; - struct timespec timespec = { .tv_sec = 1, .tv_nsec = 0 }; - int sig, waiting = 0; + int sig, err, waiting = 0; sigemptyset(&sigmask); sigaddset(&sigmask, SIGQUIT); sigaddset(&sigmask, SIGHUP); + sigaddset(&sigmask, SIGALRM); while(1) { - if(waiting) - sig = sigtimedwait(&sigmask, NULL, ×pec); - else - sig = sigwaitinfo(&sigmask, NULL); + err = sigwait(&sigmask, &sig); - if(sig == -1) { + if(err == -1) { switch(errno) { - case EAGAIN: - /* interval timed out */ - waiting = 0; - /* FALLTHROUGH */ case EINTR: - /* if waiting, the wait will be longer, but - that's OK */ continue; default: - BAD_ERROR("sigtimedwait/sigwaitinfo failed " + BAD_ERROR("sigwait failed " "because %s\n", strerror(errno)); } } @@ -133,8 +124,12 @@ void *info_thrd(void *arg) /* set one second interval period, if ^\ received within then, dump queue and cache status */ waiting = 1; - } else + alarm(1); + } else if (sig == SIGQUIT) { dump_state(); + } else if (sig == SIGALRM) { + waiting = 0; + } } } diff --git a/squashfs-tools/unsquashfs_xattr.c b/squashfs-tools/unsquashfs_xattr.c index 59f4aae..13f0e35 100644 --- a/squashfs-tools/unsquashfs_xattr.c +++ b/squashfs-tools/unsquashfs_xattr.c @@ -27,6 +27,11 @@ #include <sys/xattr.h> +#ifdef XATTR_NOFOLLOW /* Apple's xattrs */ + #define lsetxattr(path_, name_, val_, sz_, flags_) \ + setxattr(path_, name_, val_, sz_, 0, flags_ | XATTR_NOFOLLOW) +#endif + #define NOSPACE_MAX 10 extern int root_process; diff --git a/squashfs-tools/xattr.c b/squashfs-tools/xattr.c index fa24fae..c6dba62 100644 --- a/squashfs-tools/xattr.c +++ b/squashfs-tools/xattr.c @@ -22,6 +22,14 @@ * xattr.c */ +#ifndef linux +#define __BYTE_ORDER BYTE_ORDER +#define __BIG_ENDIAN BIG_ENDIAN +#define __LITTLE_ENDIAN LITTLE_ENDIAN +#else +#include <endian.h> +#endif + #define TRUE 1 #define FALSE 0 @@ -36,6 +44,13 @@ #include <stdlib.h> #include <sys/xattr.h> +#ifdef XATTR_NOFOLLOW /* Apple's xattrs */ + #define llistxattr(path_, buf_, sz_) \ + listxattr(path_, buf_, sz_, XATTR_NOFOLLOW) + #define lgetxattr(path_, name_, val_, sz_) \ + getxattr(path_, name_, val_, sz_, 0, XATTR_NOFOLLOW) +#endif + #include "squashfs_fs.h" #include "squashfs_swap.h" #include "mksquashfs.h" |