aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohamad Ayyash <mkayyash@google.com>2016-03-31 18:12:57 -0700
committerMohamad Ayyash <mkayyash@google.com>2016-04-04 12:43:37 -0700
commit933026301cb9d41b4b8b8273d892ea71c1c3d04b (patch)
tree54c706e42ef217c39b44ab7692de082ea031c80b
parent531e36ae0ef363fdddd519322763cbb35b109f4d (diff)
downloadsquashfs-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.mk2
-rw-r--r--squashfs-tools/action.c9
-rw-r--r--squashfs-tools/info.c25
-rw-r--r--squashfs-tools/mksquashfs.c83
-rw-r--r--squashfs-tools/mksquashfs.h1
-rw-r--r--squashfs-tools/pseudo.c1
-rw-r--r--squashfs-tools/read_xattrs.c4
-rw-r--r--squashfs-tools/unsquashfs.c6
-rw-r--r--squashfs-tools/unsquashfs.h4
-rw-r--r--squashfs-tools/unsquashfs_info.c25
-rw-r--r--squashfs-tools/unsquashfs_xattr.c5
-rw-r--r--squashfs-tools/xattr.c15
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, &timespec);
- 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, &timespec);
- 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"