about summary refs log tree commit diff
path: root/pkgs/tools/filesystems/squashfs
diff options
context:
space:
mode:
authorMatthew Bauer <mjbauer95@gmail.com>2018-06-01 12:21:11 -0400
committerMatthew Bauer <mjbauer95@gmail.com>2018-06-01 15:47:27 -0400
commit6cd5863060a48b7d0331dd2f69a7cfd43417d4a3 (patch)
tree5bf5f960208ff0488ced71e87ae694af47053cd9 /pkgs/tools/filesystems/squashfs
parent33a418e2e6abe489c45d282a0d1d250ff08f8ac7 (diff)
downloadnixlib-6cd5863060a48b7d0331dd2f69a7cfd43417d4a3.tar
nixlib-6cd5863060a48b7d0331dd2f69a7cfd43417d4a3.tar.gz
nixlib-6cd5863060a48b7d0331dd2f69a7cfd43417d4a3.tar.bz2
nixlib-6cd5863060a48b7d0331dd2f69a7cfd43417d4a3.tar.lz
nixlib-6cd5863060a48b7d0331dd2f69a7cfd43417d4a3.tar.xz
nixlib-6cd5863060a48b7d0331dd2f69a7cfd43417d4a3.tar.zst
nixlib-6cd5863060a48b7d0331dd2f69a7cfd43417d4a3.zip
squashfs: support darwin
Diffstat (limited to 'pkgs/tools/filesystems/squashfs')
-rw-r--r--pkgs/tools/filesystems/squashfs/darwin.patch431
-rw-r--r--pkgs/tools/filesystems/squashfs/default.nix4
2 files changed, 433 insertions, 2 deletions
diff --git a/pkgs/tools/filesystems/squashfs/darwin.patch b/pkgs/tools/filesystems/squashfs/darwin.patch
new file mode 100644
index 000000000000..6022e65be479
--- /dev/null
+++ b/pkgs/tools/filesystems/squashfs/darwin.patch
@@ -0,0 +1,431 @@
+diff --git a/squashfs-tools/action.c b/squashfs-tools/action.c
+index 4b06ccb..26365e7 100644
+--- a/squashfs-tools/action.c
++++ b/squashfs-tools/action.c
+@@ -38,6 +38,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..c8e4c52 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("sigwaitfailed "
+ 					"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 d696a51..c86d1b3 100644
+--- a/squashfs-tools/mksquashfs.c
++++ b/squashfs-tools/mksquashfs.c
+@@ -50,6 +50,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
+@@ -831,13 +835,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;
+ }
+@@ -2030,7 +2034,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;
+ 
+@@ -2999,13 +3003,13 @@ struct inode_info *lookup_inode2(struct stat *buf, int pseudo, int id)
+ }
+ 
+ 
+-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 ++;
+@@ -3016,7 +3020,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));
+@@ -3034,7 +3038,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;
+@@ -3050,7 +3054,7 @@ inline void add_dir_entry(struct dir_ent *dir_ent, struct dir_info *sub_dir,
+ }
+ 
+ 
+-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)
+ {
+@@ -3062,7 +3066,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);
+@@ -3083,7 +3087,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 ++;
+ }
+@@ -4200,6 +4204,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");
+ 
+@@ -4987,6 +4992,36 @@ int parse_num(char *arg, int *res)
+ 
+ int get_physical_memory()
+ {
++	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
+@@ -4996,10 +5031,11 @@ int get_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 "
+diff --git a/squashfs-tools/mksquashfs.h b/squashfs-tools/mksquashfs.h
+index 55708a3..d44d1fd 100644
+--- a/squashfs-tools/mksquashfs.h
++++ b/squashfs-tools/mksquashfs.h
+@@ -24,6 +24,7 @@
+  * mksquashfs.h
+  *
+  */
++#include <pthread.h>
+ 
+ struct dir_info {
+ 	char			*pathname;
+diff --git a/squashfs-tools/pseudo.c b/squashfs-tools/pseudo.c
+index cb74cf6..fe2b4bc 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 <sys/stat.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 f190e96..927e441 100644
+--- a/squashfs-tools/unsquashfs.c
++++ b/squashfs-tools/unsquashfs.c
+@@ -32,7 +32,12 @@
+ #include "stdarg.h"
+ #include "fnmatch_compat.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>
+@@ -2185,6 +2190,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 0edbd25..cea9caa 100644
+--- a/squashfs-tools/unsquashfs.h
++++ b/squashfs-tools/unsquashfs.h
+@@ -46,6 +46,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 b46550c..5b32eca 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"
diff --git a/pkgs/tools/filesystems/squashfs/default.nix b/pkgs/tools/filesystems/squashfs/default.nix
index a7f4e85eb34f..d5bcd912c957 100644
--- a/pkgs/tools/filesystems/squashfs/default.nix
+++ b/pkgs/tools/filesystems/squashfs/default.nix
@@ -22,7 +22,7 @@ stdenv.mkDerivation rec {
     ./0001-If-SOURCE_DATE_EPOCH-is-set-override-timestamps-with.patch
     ./0002-If-SOURCE_DATE_EPOCH-is-set-also-clamp-content-times.patch
     ./0003-remove-frag-deflator-thread.patch
-  ];
+  ] ++ stdenv.lib.optional stdenv.isDarwin ./darwin.patch;
 
   buildInputs = [ zlib xz ]
     ++ stdenv.lib.optional lz4Support lz4;
@@ -37,7 +37,7 @@ stdenv.mkDerivation rec {
   meta = {
     homepage = http://squashfs.sourceforge.net/;
     description = "Tool for creating and unpacking squashfs filesystems";
-    platforms = stdenv.lib.platforms.linux;
+    platforms = stdenv.lib.platforms.unix;
     license = stdenv.lib.licenses.gpl2Plus;
     maintainers = with stdenv.lib.maintainers; [ ruuda ];
   };