summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorgrehan <grehan@FreeBSD.org>2011-09-15 22:14:35 +0000
committergrehan <grehan@FreeBSD.org>2011-09-15 22:14:35 +0000
commit2256cbe5692847d9defa97bdd74ce0aa9e74157d (patch)
tree42ba64b8c25f527cf3d9b56c4ce4c51c11d445d1 /lib
parent1823067d93fba5ecf7990fee39428954fa5cbf1b (diff)
parente6011fb6bc29d6740516409bd2963015c583c2e9 (diff)
downloadFreeBSD-src-2256cbe5692847d9defa97bdd74ce0aa9e74157d.zip
FreeBSD-src-2256cbe5692847d9defa97bdd74ce0aa9e74157d.tar.gz
IFC @ r225592
sys/dev/bvm/bvm_console.c - move up to the new alt-break order.
Diffstat (limited to 'lib')
-rw-r--r--lib/bind/config.h12
-rw-r--r--lib/libarchive/archive_read.c18
-rw-r--r--lib/libarchive/archive_read_support_compression_uu.c12
-rw-r--r--lib/libarchive/archive_read_support_format_cpio.c6
-rw-r--r--lib/libarchive/archive_read_support_format_iso9660.c506
-rw-r--r--lib/libarchive/archive_read_support_format_mtree.c11
-rw-r--r--lib/libarchive/archive_write_open_fd.c15
-rw-r--r--lib/libarchive/archive_write_open_file.c14
-rw-r--r--lib/libarchive/archive_write_open_filename.c14
-rw-r--r--lib/libarchive/archive_write_set_compression_xz.c4
-rw-r--r--lib/libarchive/archive_write_set_format_cpio.c2
-rw-r--r--lib/libarchive/archive_write_set_format_zip.c3
-rw-r--r--lib/libarchive/test/Makefile1
-rw-r--r--lib/libarchive/test/test_open_failure.c198
-rw-r--r--lib/libarchive/test/test_read_format_iso_2.iso.Z.uu37
-rw-r--r--lib/libarchive/test/test_read_format_iso_gz.c49
-rw-r--r--lib/libarchive/test/test_read_format_isojoliet_bz2.c7
-rw-r--r--lib/libarchive/test/test_read_format_isojoliet_long.c6
-rw-r--r--lib/libarchive/test/test_read_format_isojoliet_rr.c7
-rw-r--r--lib/libarchive/test/test_read_format_isorr_bz2.c10
-rw-r--r--lib/libarchive/test/test_read_format_isorr_new_bz2.c10
-rw-r--r--lib/libarchive/test/test_read_format_isozisofs_bz2.c12
-rw-r--r--lib/libarchive/test/test_read_format_mtree.c43
-rw-r--r--lib/libarchive/test/test_write_compress_lzma.c7
-rw-r--r--lib/libarchive/test/test_write_compress_xz.c6
-rw-r--r--lib/libbsnmp/libbsnmp/Makefile2
-rw-r--r--lib/libc/amd64/string/Makefile.inc2
-rw-r--r--lib/libc/amd64/string/stpcpy.S (renamed from lib/libc/amd64/string/strcpy.S)40
-rw-r--r--lib/libc/amd64/string/strcpy.c38
-rw-r--r--lib/libc/net/ethers.32
-rw-r--r--lib/libc/net/sctp_sys_calls.c3
-rw-r--r--lib/libc/stdlib/Makefile.inc4
-rw-r--r--lib/libc/sys/Makefile.inc8
-rw-r--r--lib/libc/sys/Symbol.map5
-rw-r--r--lib/libc/sys/cap_new.2474
-rw-r--r--lib/libc/sys/dup.28
-rw-r--r--lib/libc/sys/pdfork.2182
-rw-r--r--lib/libc/sys/sigwait.210
-rw-r--r--lib/libc/sys/sigwaitinfo.212
-rw-r--r--lib/libcam/Makefile2
-rw-r--r--lib/libdwarf/Makefile2
-rw-r--r--lib/libkvm/kvm_ia64.c88
-rw-r--r--lib/libkvm/kvm_proc.c4
-rw-r--r--lib/libmemstat/libmemstat.36
-rw-r--r--lib/libmemstat/memstat.c14
-rw-r--r--lib/libmemstat/memstat.h7
-rw-r--r--lib/libmemstat/memstat_internal.h13
-rw-r--r--lib/libmemstat/memstat_malloc.c36
-rw-r--r--lib/libmemstat/memstat_uma.c30
-rw-r--r--lib/libopie/Makefile2
-rw-r--r--lib/libpcap/Makefile2
-rw-r--r--lib/libproc/proc_create.c3
-rw-r--r--lib/libprocstat/libprocstat.c28
-rw-r--r--lib/libprocstat/libprocstat.h2
-rw-r--r--lib/librtld_db/Makefile2
-rw-r--r--lib/libtacplus/Makefile2
-rw-r--r--lib/libthread_db/arch/amd64/libpthread_md.c7
-rw-r--r--lib/libthread_db/arch/sparc64/libpthread_md.c35
-rw-r--r--lib/libthread_db/libthr_db.c16
-rw-r--r--lib/libufs/Makefile1
-rw-r--r--lib/libusb/Makefile1
-rw-r--r--lib/libusb/libusb.3408
-rw-r--r--lib/libusb/libusb.h9
-rw-r--r--lib/libusb/libusb10.c21
-rw-r--r--lib/libusbhid/parse.c12
-rw-r--r--lib/libz/Makefile20
66 files changed, 1939 insertions, 634 deletions
diff --git a/lib/bind/config.h b/lib/bind/config.h
index 003a756..ca364b5 100644
--- a/lib/bind/config.h
+++ b/lib/bind/config.h
@@ -187,9 +187,18 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to 1 if you have the <devpoll.h> header file. */
/* #undef HAVE_DEVPOLL_H */
+/* Define to 1 if you have the `dlclose' function. */
+#define HAVE_DLCLOSE 1
+
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
+/* Define to 1 if you have the `dlopen' function. */
+#define HAVE_DLOPEN 1
+
+/* Define to 1 if you have the `dlsym' function. */
+#define HAVE_DLSYM 1
+
/* Define to 1 if you have the `EVP_sha256' function. */
#define HAVE_EVP_SHA256 1
@@ -352,6 +361,9 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to the flags type used by getnameinfo(3). */
#define IRS_GETNAMEINFO_FLAGS_T int
+/* Define to allow building of objects for dlopen(). */
+#define ISC_DLZ_DLOPEN 1
+
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
diff --git a/lib/libarchive/archive_read.c b/lib/libarchive/archive_read.c
index 027ed60..7873d45 100644
--- a/lib/libarchive/archive_read.c
+++ b/lib/libarchive/archive_read.c
@@ -377,6 +377,12 @@ build_stream(struct archive_read *a)
/* If no bidder, we're done. */
if (best_bidder == NULL) {
+ /* Verify the final pipelin by asking it for some data. */
+ __archive_read_filter_ahead(a->filter, 1, &avail);
+ if (avail < 0) {
+ cleanup_filters(a);
+ return (ARCHIVE_FATAL);
+ }
a->archive.compression_name = a->filter->name;
a->archive.compression_code = a->filter->code;
return (ARCHIVE_OK);
@@ -389,17 +395,11 @@ build_stream(struct archive_read *a)
filter->bidder = best_bidder;
filter->archive = a;
filter->upstream = a->filter;
- r = (best_bidder->init)(filter);
- if (r != ARCHIVE_OK) {
- free(filter);
- return (r);
- }
a->filter = filter;
- /* Verify the filter by asking it for some data. */
- __archive_read_filter_ahead(filter, 1, &avail);
- if (avail < 0) {
+ r = (best_bidder->init)(a->filter);
+ if (r != ARCHIVE_OK) {
cleanup_filters(a);
- return (ARCHIVE_FATAL);
+ return (r);
}
}
}
diff --git a/lib/libarchive/archive_read_support_compression_uu.c b/lib/libarchive/archive_read_support_compression_uu.c
index c3c37d6..cb1dae5 100644
--- a/lib/libarchive/archive_read_support_compression_uu.c
+++ b/lib/libarchive/archive_read_support_compression_uu.c
@@ -381,7 +381,17 @@ ensure_in_buff_size(struct archive_read_filter *self,
unsigned char *ptr;
size_t newsize;
- newsize = uudecode->in_allocated << 1;
+ /*
+ * Calculate a new buffer size for in_buff.
+ * Increase its value until it has enough size we need.
+ */
+ newsize = uudecode->in_allocated;
+ do {
+ if (newsize < IN_BUFF_SIZE*32)
+ newsize <<= 1;
+ else
+ newsize += IN_BUFF_SIZE;
+ } while (size > newsize);
ptr = malloc(newsize);
if (ptr == NULL ||
newsize < uudecode->in_allocated) {
diff --git a/lib/libarchive/archive_read_support_format_cpio.c b/lib/libarchive/archive_read_support_format_cpio.c
index 7e52fbe..24f3d35 100644
--- a/lib/libarchive/archive_read_support_format_cpio.c
+++ b/lib/libarchive/archive_read_support_format_cpio.c
@@ -54,7 +54,7 @@ struct cpio_bin_header {
unsigned char c_mtime[4];
unsigned char c_namesize[2];
unsigned char c_filesize[4];
-};
+} __packed;
struct cpio_odc_header {
char c_magic[6];
@@ -68,7 +68,7 @@ struct cpio_odc_header {
char c_mtime[11];
char c_namesize[6];
char c_filesize[11];
-};
+} __packed;
struct cpio_newc_header {
char c_magic[6];
@@ -85,7 +85,7 @@ struct cpio_newc_header {
char c_rdevminor[8];
char c_namesize[8];
char c_crc[8];
-};
+} __packed;
struct links_entry {
struct links_entry *next;
diff --git a/lib/libarchive/archive_read_support_format_iso9660.c b/lib/libarchive/archive_read_support_format_iso9660.c
index 1f64003..0216461 100644
--- a/lib/libarchive/archive_read_support_format_iso9660.c
+++ b/lib/libarchive/archive_read_support_format_iso9660.c
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* Copyright (c) 2009 Andreas Henriksson <andreas@fatal.se>
- * Copyright (c) 2009 Michihiro NAKAJIMA
+ * Copyright (c) 2009-2011 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -261,13 +261,17 @@ struct file_info {
struct file_info *use_next;
struct file_info *parent;
struct file_info *next;
+ struct file_info *re_next;
int subdirs;
uint64_t key; /* Heap Key. */
uint64_t offset; /* Offset on disk. */
uint64_t size; /* File size in bytes. */
uint32_t ce_offset; /* Offset of CE. */
uint32_t ce_size; /* Size of CE. */
+ char rr_moved; /* Flag to rr_moved. */
+ char rr_moved_has_re_only;
char re; /* Having RRIP "RE" extension. */
+ char re_descendant;
uint64_t cl_offset; /* Having RRIP "CL" extension. */
int birthtime_is_set;
time_t birthtime; /* File created time. */
@@ -294,7 +298,10 @@ struct file_info {
struct content *first;
struct content **last;
} contents;
- char exposed;
+ struct {
+ struct file_info *first;
+ struct file_info **last;
+ } rede_files;
};
struct heap_queue {
@@ -317,8 +324,6 @@ struct iso9660 {
unsigned char suspOffset;
struct file_info *rr_moved;
- struct heap_queue re_dirs;
- struct heap_queue cl_files;
struct read_ce_queue {
struct read_ce_req {
uint64_t offset;/* Offset of CE on disk. */
@@ -337,6 +342,10 @@ struct iso9660 {
struct file_info *first;
struct file_info **last;
} cache_files;
+ struct {
+ struct file_info *first;
+ struct file_info **last;
+ } re_files;
uint64_t current_position;
ssize_t logical_block_size;
@@ -377,7 +386,8 @@ static int isJolietSVD(struct iso9660 *, const unsigned char *);
static int isSVD(struct iso9660 *, const unsigned char *);
static int isEVD(struct iso9660 *, const unsigned char *);
static int isPVD(struct iso9660 *, const unsigned char *);
-static struct file_info *next_cache_entry(struct iso9660 *iso9660);
+static int next_cache_entry(struct archive_read *, struct iso9660 *,
+ struct file_info **);
static int next_entry_seek(struct archive_read *a, struct iso9660 *iso9660,
struct file_info **pfile);
static struct file_info *
@@ -400,10 +410,12 @@ static void parse_rockridge_ZF1(struct file_info *,
static void register_file(struct iso9660 *, struct file_info *);
static void release_files(struct iso9660 *);
static unsigned toi(const void *p, int n);
+static inline void re_add_entry(struct iso9660 *, struct file_info *);
+static inline struct file_info * re_get_entry(struct iso9660 *);
+static inline int rede_add_entry(struct file_info *);
+static inline struct file_info * rede_get_entry(struct file_info *);
static inline void cache_add_entry(struct iso9660 *iso9660,
struct file_info *file);
-static inline void cache_add_to_next_of_parent(struct iso9660 *iso9660,
- struct file_info *file);
static inline struct file_info *cache_get_entry(struct iso9660 *iso9660);
static void heap_add_entry(struct heap_queue *heap,
struct file_info *file, uint64_t key);
@@ -430,6 +442,8 @@ archive_read_support_format_iso9660(struct archive *_a)
iso9660->magic = ISO9660_MAGIC;
iso9660->cache_files.first = NULL;
iso9660->cache_files.last = &(iso9660->cache_files.first);
+ iso9660->re_files.first = NULL;
+ iso9660->re_files.last = &(iso9660->re_files.first);
/* Enable to support Joliet extensions by default. */
iso9660->opt_support_joliet = 1;
/* Enable to support Rock Ridge extensions by default. */
@@ -709,16 +723,18 @@ isSVD(struct iso9660 *iso9660, const unsigned char *h)
/* Location of Occurrence of Type L Path Table must be
* available location,
- * > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
+ * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
location = archive_le32dec(h+SVD_type_L_path_table_offset);
- if (location <= SYSTEM_AREA_BLOCK+2 || location >= volume_block)
+ if (location < SYSTEM_AREA_BLOCK+2 || location >= volume_block)
return (0);
- /* Location of Occurrence of Type M Path Table must be
- * available location,
- * > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
+ /* The Type M Path Table must be at a valid location (WinISO
+ * and probably other programs omit this, so we allow zero)
+ *
+ * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
location = archive_be32dec(h+SVD_type_M_path_table_offset);
- if (location <= SYSTEM_AREA_BLOCK+2 || location >= volume_block)
+ if ((location > 0 && location < SYSTEM_AREA_BLOCK+2)
+ || location >= volume_block)
return (0);
/* Read Root Directory Record in Volume Descriptor. */
@@ -781,16 +797,17 @@ isEVD(struct iso9660 *iso9660, const unsigned char *h)
/* Location of Occurrence of Type L Path Table must be
* available location,
- * > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
+ * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
location = archive_le32dec(h+PVD_type_1_path_table_offset);
- if (location <= SYSTEM_AREA_BLOCK+2 || location >= volume_block)
+ if (location < SYSTEM_AREA_BLOCK+2 || location >= volume_block)
return (0);
/* Location of Occurrence of Type M Path Table must be
* available location,
- * > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
+ * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
location = archive_be32dec(h+PVD_type_m_path_table_offset);
- if (location <= SYSTEM_AREA_BLOCK+2 || location >= volume_block)
+ if ((location > 0 && location < SYSTEM_AREA_BLOCK+2)
+ || location >= volume_block)
return (0);
/* Reserved field must be 0. */
@@ -862,19 +879,24 @@ isPVD(struct iso9660 *iso9660, const unsigned char *h)
* available location,
* > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
location = archive_le32dec(h+PVD_type_1_path_table_offset);
- if (location <= SYSTEM_AREA_BLOCK+2 || location >= volume_block)
+ if (location < SYSTEM_AREA_BLOCK+2 || location >= volume_block)
return (0);
- /* Location of Occurrence of Type M Path Table must be
- * available location,
- * > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
+ /* The Type M Path Table must also be at a valid location
+ * (although ECMA 119 requires a Type M Path Table, WinISO and
+ * probably other programs omit it, so we permit a zero here)
+ *
+ * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
location = archive_be32dec(h+PVD_type_m_path_table_offset);
- if (location <= SYSTEM_AREA_BLOCK+2 || location >= volume_block)
+ if ((location > 0 && location < SYSTEM_AREA_BLOCK+2)
+ || location >= volume_block)
return (0);
/* Reserved field must be 0. */
+ /* FreeBSD: makefs erroneously created images with 0x20 */
for (i = 0; i < PVD_reserved4_size; ++i)
- if (h[PVD_reserved4_offset + i] != 0)
+ if (h[PVD_reserved4_offset + i] != 0 &&
+ h[PVD_reserved4_offset + i] != 32)
return (0);
/* Reserved field must be 0. */
@@ -967,42 +989,38 @@ read_children(struct archive_read *a, struct file_info *parent)
child = parse_file_info(a, parent, p);
if (child == NULL)
return (ARCHIVE_FATAL);
- if (child->cl_offset)
- heap_add_entry(&(iso9660->cl_files),
- child, child->cl_offset);
- else {
- if (child->multi_extent || multi != NULL) {
- struct content *con;
-
- if (multi == NULL) {
- multi = child;
- multi->contents.first = NULL;
- multi->contents.last =
- &(multi->contents.first);
- }
- con = malloc(sizeof(struct content));
- if (con == NULL) {
- archive_set_error(
- &a->archive, ENOMEM,
- "No memory for "
- "multi extent");
- return (ARCHIVE_FATAL);
- }
- con->offset = child->offset;
- con->size = child->size;
- con->next = NULL;
- *multi->contents.last = con;
- multi->contents.last = &(con->next);
- if (multi == child)
- add_entry(iso9660, child);
- else {
- multi->size += child->size;
- if (!child->multi_extent)
- multi = NULL;
- }
- } else
+ if (child->cl_offset == 0 &&
+ (child->multi_extent || multi != NULL)) {
+ struct content *con;
+
+ if (multi == NULL) {
+ multi = child;
+ multi->contents.first = NULL;
+ multi->contents.last =
+ &(multi->contents.first);
+ }
+ con = malloc(sizeof(struct content));
+ if (con == NULL) {
+ archive_set_error(
+ &a->archive, ENOMEM,
+ "No memory for "
+ "multi extent");
+ return (ARCHIVE_FATAL);
+ }
+ con->offset = child->offset;
+ con->size = child->size;
+ con->next = NULL;
+ *multi->contents.last = con;
+ multi->contents.last = &(con->next);
+ if (multi == child)
add_entry(iso9660, child);
- }
+ else {
+ multi->size += child->size;
+ if (!child->multi_extent)
+ multi = NULL;
+ }
+ } else
+ add_entry(iso9660, child);
}
}
@@ -1014,102 +1032,12 @@ read_children(struct archive_read *a, struct file_info *parent)
}
static int
-relocate_dir(struct iso9660 *iso9660, struct file_info *file)
-{
- struct file_info *re;
-
- re = heap_get_entry(&(iso9660->re_dirs));
- while (re != NULL && re->offset < file->cl_offset) {
- /* This case is wrong pattern.
- * But dont't reject this directory entry to be robust. */
- cache_add_entry(iso9660, re);
- re = heap_get_entry(&(iso9660->re_dirs));
- }
- if (re == NULL)
- /* This case is wrong pattern. */
- return (0);
- if (re->offset == file->cl_offset) {
- re->parent->subdirs--;
- re->parent = file->parent;
- re->parent->subdirs++;
- cache_add_to_next_of_parent(iso9660, re);
- return (1);
- } else
- /* This case is wrong pattern. */
- heap_add_entry(&(iso9660->re_dirs), re, re->offset);
- return (0);
-}
-
-static int
-read_entries(struct archive_read *a)
-{
- struct iso9660 *iso9660;
- struct file_info *file;
- int r;
-
- iso9660 = (struct iso9660 *)(a->format->data);
-
- while ((file = next_entry(iso9660)) != NULL &&
- (file->mode & AE_IFMT) == AE_IFDIR) {
- r = read_children(a, file);
- if (r != ARCHIVE_OK)
- return (r);
-
- if (iso9660->seenRockridge &&
- file->parent != NULL &&
- file->parent->parent == NULL &&
- iso9660->rr_moved == NULL &&
- (strcmp(file->name.s, "rr_moved") == 0 ||
- strcmp(file->name.s, ".rr_moved") == 0)) {
- iso9660->rr_moved = file;
- } else if (file->re)
- heap_add_entry(&(iso9660->re_dirs), file,
- file->offset);
- else
- cache_add_entry(iso9660, file);
- }
- if (file != NULL)
- add_entry(iso9660, file);
-
- if (iso9660->rr_moved != NULL) {
- /*
- * Relocate directory which rr_moved has.
- */
- while ((file = heap_get_entry(&(iso9660->cl_files))) != NULL)
- relocate_dir(iso9660, file);
-
- /* If rr_moved directory still has children,
- * Add rr_moved into pending_files to show
- */
- if (iso9660->rr_moved->subdirs) {
- cache_add_entry(iso9660, iso9660->rr_moved);
- /* If entries which have "RE" extension are still
- * remaining(this case is unlikely except ISO image
- * is broken), the entries won't be exposed. */
- while ((file = heap_get_entry(&(iso9660->re_dirs))) != NULL)
- cache_add_entry(iso9660, file);
- } else
- iso9660->rr_moved->parent->subdirs--;
- } else {
- /*
- * In case ISO image is broken. If the name of rr_moved
- * directory has been changed by damage, subdirectories
- * of rr_moved entry won't be exposed.
- */
- while ((file = heap_get_entry(&(iso9660->re_dirs))) != NULL)
- cache_add_entry(iso9660, file);
- }
-
- return (ARCHIVE_OK);
-}
-
-static int
archive_read_format_iso9660_read_header(struct archive_read *a,
struct archive_entry *entry)
{
struct iso9660 *iso9660;
struct file_info *file;
- int r, rd_r;
+ int r, rd_r = ARCHIVE_OK;
iso9660 = (struct iso9660 *)(a->format->data);
@@ -1199,11 +1127,7 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
a->archive.archive_format_name =
"ISO9660 with Rockridge extensions";
}
- rd_r = read_entries(a);
- if (rd_r == ARCHIVE_FATAL)
- return (ARCHIVE_FATAL);
- } else
- rd_r = ARCHIVE_OK;
+ }
/* Get the next entry that appears after the current offset. */
r = next_entry_seek(a, iso9660, &file);
@@ -1316,7 +1240,6 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
/* Directory data has been read completely. */
iso9660->entry_bytes_remaining = 0;
iso9660->entry_sparse_offset = 0;
- file->exposed = 1;
}
if (rd_r != ARCHIVE_OK)
@@ -1643,10 +1566,6 @@ archive_read_format_iso9660_cleanup(struct archive_read *a)
archive_string_free(&iso9660->previous_pathname);
if (iso9660->pending_files.files)
free(iso9660->pending_files.files);
- if (iso9660->re_dirs.files)
- free(iso9660->re_dirs.files);
- if (iso9660->cl_files.files)
- free(iso9660->cl_files.files);
#ifdef HAVE_ZLIB_H
free(iso9660->entry_zisofs.uncompressed_buffer);
free(iso9660->entry_zisofs.block_pointers);
@@ -1677,6 +1596,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
const unsigned char *rr_start, *rr_end;
const unsigned char *p;
size_t dr_len;
+ uint64_t fsize;
int32_t location;
int flags;
@@ -1685,6 +1605,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
dr_len = (size_t)isodirrec[DR_length_offset];
name_len = (size_t)isodirrec[DR_name_len_offset];
location = archive_le32dec(isodirrec + DR_extent_offset);
+ fsize = toi(isodirrec + DR_size_offset, DR_size_size);
/* Sanity check that dr_len needs at least 34. */
if (dr_len < 34) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@@ -1703,7 +1624,10 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
* link or file size is zero. As far as I know latest mkisofs
* do that.
*/
- if (location >= iso9660->volume_block) {
+ if (location > 0 &&
+ (location + ((fsize + iso9660->logical_block_size -1)
+ / iso9660->logical_block_size)) >
+ (unsigned int)iso9660->volume_block) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Invalid location of extent of file");
return (NULL);
@@ -1719,9 +1643,11 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
memset(file, 0, sizeof(*file));
file->parent = parent;
file->offset = iso9660->logical_block_size * (uint64_t)location;
- file->size = toi(isodirrec + DR_size_offset, DR_size_size);
+ file->size = fsize;
file->mtime = isodate7(isodirrec + DR_date_offset);
file->ctime = file->atime = file->mtime;
+ file->rede_files.first = NULL;
+ file->rede_files.last = &(file->rede_files.first);
p = isodirrec + DR_name_offset;
/* Rockridge extensions (if any) follow name. Compute this
@@ -1860,9 +1786,43 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
file->nlinks = 1;/* Reset nlink. we'll calculate it later. */
/* Tell file's parent how many children that parent has. */
- if (parent != NULL && (flags & 0x02) && file->cl_offset == 0)
+ if (parent != NULL && (flags & 0x02))
parent->subdirs++;
+ if (iso9660->seenRockridge) {
+ if (parent != NULL && parent->parent == NULL &&
+ (flags & 0x02) && iso9660->rr_moved == NULL &&
+ (strcmp(file->name.s, "rr_moved") == 0 ||
+ strcmp(file->name.s, ".rr_moved") == 0)) {
+ iso9660->rr_moved = file;
+ file->rr_moved = 1;
+ file->rr_moved_has_re_only = 1;
+ file->re = 0;
+ parent->subdirs--;
+ } else if (file->re) {
+ /* This file's parent is not rr_moved, clear invalid
+ * "RE" mark. */
+ if (parent == NULL || parent->rr_moved == 0)
+ file->re = 0;
+ else if ((flags & 0x02) == 0) {
+ file->rr_moved_has_re_only = 0;
+ file->re = 0;
+ }
+ } else if (parent != NULL && parent->rr_moved)
+ file->rr_moved_has_re_only = 0;
+ else if (parent != NULL && (flags & 0x02) &&
+ (parent->re || parent->re_descendant))
+ file->re_descendant = 1;
+ if (file->cl_offset != 0) {
+ parent->subdirs++;
+ /* Overwrite an offset and a number of this "CL" entry
+ * to appear before other dirs. "+1" to those is to
+ * make sure to appear after "RE" entry which this
+ * "CL" entry should be connected with. */
+ file->offset = file->number = file->cl_offset + 1;
+ }
+ }
+
#if DEBUG
/* DEBUGGING: Warn about attributes I don't yet fully support. */
if ((flags & ~0x02) != 0) {
@@ -2476,10 +2436,12 @@ next_entry_seek(struct archive_read *a, struct iso9660 *iso9660,
struct file_info **pfile)
{
struct file_info *file;
+ int r;
- *pfile = file = next_cache_entry(iso9660);
- if (file == NULL)
- return (ARCHIVE_EOF);
+ r = next_cache_entry(a, iso9660, pfile);
+ if (r != ARCHIVE_OK)
+ return (r);
+ file = *pfile;
/* Don't waste time seeking for zero-length bodies. */
if (file->size == 0)
@@ -2500,8 +2462,9 @@ next_entry_seek(struct archive_read *a, struct iso9660 *iso9660,
return (ARCHIVE_OK);
}
-static struct file_info *
-next_cache_entry(struct iso9660 *iso9660)
+static int
+next_cache_entry(struct archive_read *a, struct iso9660 *iso9660,
+ struct file_info **pfile)
{
struct file_info *file;
struct {
@@ -2513,21 +2476,131 @@ next_cache_entry(struct iso9660 *iso9660)
file = cache_get_entry(iso9660);
if (file != NULL) {
- while (file->parent != NULL && !file->parent->exposed) {
- /* If file's parent is not exposed, it's moved
- * to next entry of its parent. */
- cache_add_to_next_of_parent(iso9660, file);
- file = cache_get_entry(iso9660);
- }
- return (file);
+ *pfile = file;
+ return (ARCHIVE_OK);
}
- file = next_entry(iso9660);
- if (file == NULL)
- return (NULL);
+ for (;;) {
+ struct file_info *re, *d;
+
+ *pfile = file = next_entry(iso9660);
+ if (file == NULL) {
+ /*
+ * If directory entries all which are descendant of
+ * rr_moved are stil remaning, expose their.
+ */
+ if (iso9660->re_files.first != NULL &&
+ iso9660->rr_moved != NULL &&
+ iso9660->rr_moved->rr_moved_has_re_only)
+ /* Expose "rr_moved" entry. */
+ cache_add_entry(iso9660, iso9660->rr_moved);
+ while ((re = re_get_entry(iso9660)) != NULL) {
+ /* Expose its descendant dirs. */
+ while ((d = rede_get_entry(re)) != NULL)
+ cache_add_entry(iso9660, d);
+ }
+ if (iso9660->cache_files.first != NULL)
+ return (next_cache_entry(a, iso9660, pfile));
+ return (ARCHIVE_EOF);
+ }
+
+ if (file->cl_offset) {
+ struct file_info *first_re = NULL;
+ int nexted_re = 0;
+
+ /*
+ * Find "RE" dir for the current file, which
+ * has "CL" flag.
+ */
+ while ((re = re_get_entry(iso9660))
+ != first_re) {
+ if (first_re == NULL)
+ first_re = re;
+ if (re->offset == file->cl_offset) {
+ re->parent->subdirs--;
+ re->parent = file->parent;
+ re->re = 0;
+ if (re->parent->re_descendant) {
+ nexted_re = 1;
+ re->re_descendant = 1;
+ if (rede_add_entry(re) < 0)
+ goto fatal_rr;
+ /* Move a list of descendants
+ * to a new ancestor. */
+ while ((d = rede_get_entry(
+ re)) != NULL)
+ if (rede_add_entry(d)
+ < 0)
+ goto fatal_rr;
+ break;
+ }
+ /* Replace the current file
+ * with "RE" dir */
+ *pfile = file = re;
+ /* Expose its descendant */
+ while ((d = rede_get_entry(
+ file)) != NULL)
+ cache_add_entry(
+ iso9660, d);
+ break;
+ } else
+ re_add_entry(iso9660, re);
+ }
+ if (nexted_re) {
+ /*
+ * Do not expose this at this time
+ * because we have not gotten its full-path
+ * name yet.
+ */
+ continue;
+ }
+ } else if ((file->mode & AE_IFMT) == AE_IFDIR) {
+ int r;
+
+ /* Read file entries in this dir. */
+ r = read_children(a, file);
+ if (r != ARCHIVE_OK)
+ return (r);
+
+ /*
+ * Handle a special dir of Rockridge extensions,
+ * "rr_moved".
+ */
+ if (file->rr_moved) {
+ /*
+ * If this has only the subdirectories which
+ * have "RE" flags, do not expose at this time.
+ */
+ if (file->rr_moved_has_re_only)
+ continue;
+ /* Otherwise expose "rr_moved" entry. */
+ } else if (file->re) {
+ /*
+ * Do not expose this at this time
+ * because we have not gotten its full-path
+ * name yet.
+ */
+ re_add_entry(iso9660, file);
+ continue;
+ } else if (file->re_descendant) {
+ /*
+ * If the top level "RE" entry of this entry
+ * is not exposed, we, accordingly, should not
+ * expose this entry at this time because
+ * we cannot make its proper full-path name.
+ */
+ if (rede_add_entry(file) == 0)
+ continue;
+ /* Otherwise we can expose this entry because
+ * it seems its top level "RE" has already been
+ * exposed. */
+ }
+ }
+ break;
+ }
if ((file->mode & AE_IFMT) != AE_IFREG || file->number == -1)
- return (file);
+ return (ARCHIVE_OK);
count = 0;
number = file->number;
@@ -2560,8 +2633,10 @@ next_cache_entry(struct iso9660 *iso9660)
file = next_entry(iso9660);
}
- if (count == 0)
- return (file);
+ if (count == 0) {
+ *pfile = file;
+ return ((file == NULL)?ARCHIVE_EOF:ARCHIVE_OK);
+ }
if (file->number == -1) {
file->next = NULL;
*empty_files.last = file;
@@ -2586,24 +2661,75 @@ next_cache_entry(struct iso9660 *iso9660)
*iso9660->cache_files.last = empty_files.first;
iso9660->cache_files.last = empty_files.last;
}
- return (cache_get_entry(iso9660));
+ *pfile = cache_get_entry(iso9660);
+ return ((*pfile == NULL)?ARCHIVE_EOF:ARCHIVE_OK);
+
+fatal_rr:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Failed to connect 'CL' pointer to 'RE' rr_moved pointer of"
+ "Rockridge extensions");
+ return (ARCHIVE_FATAL);
}
static inline void
-cache_add_entry(struct iso9660 *iso9660, struct file_info *file)
+re_add_entry(struct iso9660 *iso9660, struct file_info *file)
{
- file->next = NULL;
- *iso9660->cache_files.last = file;
- iso9660->cache_files.last = &(file->next);
+ file->re_next = NULL;
+ *iso9660->re_files.last = file;
+ iso9660->re_files.last = &(file->re_next);
+}
+
+static inline struct file_info *
+re_get_entry(struct iso9660 *iso9660)
+{
+ struct file_info *file;
+
+ if ((file = iso9660->re_files.first) != NULL) {
+ iso9660->re_files.first = file->re_next;
+ if (iso9660->re_files.first == NULL)
+ iso9660->re_files.last =
+ &(iso9660->re_files.first);
+ }
+ return (file);
+}
+
+static inline int
+rede_add_entry(struct file_info *file)
+{
+ struct file_info *re;
+
+ re = file->parent;
+ while (re != NULL && !re->re)
+ re = re->parent;
+ if (re == NULL)
+ return (-1);
+
+ file->re_next = NULL;
+ *re->rede_files.last = file;
+ re->rede_files.last = &(file->re_next);
+ return (0);
+}
+
+static inline struct file_info *
+rede_get_entry(struct file_info *re)
+{
+ struct file_info *file;
+
+ if ((file = re->rede_files.first) != NULL) {
+ re->rede_files.first = file->re_next;
+ if (re->rede_files.first == NULL)
+ re->rede_files.last =
+ &(re->rede_files.first);
+ }
+ return (file);
}
static inline void
-cache_add_to_next_of_parent(struct iso9660 *iso9660, struct file_info *file)
+cache_add_entry(struct iso9660 *iso9660, struct file_info *file)
{
- file->next = file->parent->next;
- file->parent->next = file;
- if (iso9660->cache_files.last == &(file->parent->next))
- iso9660->cache_files.last = &(file->next);
+ file->next = NULL;
+ *iso9660->cache_files.last = file;
+ iso9660->cache_files.last = &(file->next);
}
static inline struct file_info *
diff --git a/lib/libarchive/archive_read_support_format_mtree.c b/lib/libarchive/archive_read_support_format_mtree.c
index bb231fa..7ae0b02 100644
--- a/lib/libarchive/archive_read_support_format_mtree.c
+++ b/lib/libarchive/archive_read_support_format_mtree.c
@@ -525,6 +525,7 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
/* Initialize reasonable defaults. */
mtree->filetype = AE_IFREG;
archive_entry_set_size(entry, 0);
+ archive_string_empty(&mtree->contents_name);
/* Parse options from this line. */
parsed_kws = 0;
@@ -613,9 +614,8 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
}
/*
- * If there is a contents file on disk, use that size;
- * otherwise leave it as-is (it might have been set from
- * the mtree size= keyword).
+ * Check for a mismatch between the type in the specification and
+ * the type of the contents object on disk.
*/
if (st != NULL) {
mismatched_type = 0;
@@ -660,6 +660,11 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
}
}
+ /*
+ * If there is a contents file on disk, pick some of the metadata
+ * from that file. For most of these, we only set it from the contents
+ * if it wasn't already parsed from the specification.
+ */
if (st != NULL) {
if ((parsed_kws & MTREE_HAS_DEVICE) == 0 &&
(archive_entry_filetype(entry) == AE_IFCHR ||
diff --git a/lib/libarchive/archive_write_open_fd.c b/lib/libarchive/archive_write_open_fd.c
index b0793a2..1d27ce3 100644
--- a/lib/libarchive/archive_write_open_fd.c
+++ b/lib/libarchive/archive_write_open_fd.c
@@ -51,7 +51,6 @@ __FBSDID("$FreeBSD$");
#include "archive.h"
struct write_fd_data {
- off_t offset;
int fd;
};
@@ -122,12 +121,16 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length
ssize_t bytesWritten;
mine = (struct write_fd_data *)client_data;
- bytesWritten = write(mine->fd, buff, length);
- if (bytesWritten <= 0) {
- archive_set_error(a, errno, "Write error");
- return (-1);
+ for (;;) {
+ bytesWritten = write(mine->fd, buff, length);
+ if (bytesWritten <= 0) {
+ if (errno == EINTR)
+ continue;
+ archive_set_error(a, errno, "Write error");
+ return (-1);
+ }
+ return (bytesWritten);
}
- return (bytesWritten);
}
static int
diff --git a/lib/libarchive/archive_write_open_file.c b/lib/libarchive/archive_write_open_file.c
index c99414f..68bf236 100644
--- a/lib/libarchive/archive_write_open_file.c
+++ b/lib/libarchive/archive_write_open_file.c
@@ -86,12 +86,16 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length
size_t bytesWritten;
mine = client_data;
- bytesWritten = fwrite(buff, 1, length, mine->f);
- if (bytesWritten < length) {
- archive_set_error(a, errno, "Write error");
- return (-1);
+ for (;;) {
+ bytesWritten = fwrite(buff, 1, length, mine->f);
+ if (bytesWritten <= 0) {
+ if (errno == EINTR)
+ continue;
+ archive_set_error(a, errno, "Write error");
+ return (-1);
+ }
+ return (bytesWritten);
}
- return (bytesWritten);
}
static int
diff --git a/lib/libarchive/archive_write_open_filename.c b/lib/libarchive/archive_write_open_filename.c
index 1db11f9..0c1e189 100644
--- a/lib/libarchive/archive_write_open_filename.c
+++ b/lib/libarchive/archive_write_open_filename.c
@@ -142,12 +142,16 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length
ssize_t bytesWritten;
mine = (struct write_file_data *)client_data;
- bytesWritten = write(mine->fd, buff, length);
- if (bytesWritten <= 0) {
- archive_set_error(a, errno, "Write error");
- return (-1);
+ for (;;) {
+ bytesWritten = write(mine->fd, buff, length);
+ if (bytesWritten <= 0) {
+ if (errno == EINTR)
+ continue;
+ archive_set_error(a, errno, "Write error");
+ return (-1);
+ }
+ return (bytesWritten);
}
- return (bytesWritten);
}
static int
diff --git a/lib/libarchive/archive_write_set_compression_xz.c b/lib/libarchive/archive_write_set_compression_xz.c
index 8173317..d97bca7 100644
--- a/lib/libarchive/archive_write_set_compression_xz.c
+++ b/lib/libarchive/archive_write_set_compression_xz.c
@@ -421,8 +421,8 @@ drive_compressor(struct archive_write *a, struct private_data *state, int finish
archive_set_error(&a->archive, ENOMEM,
"lzma compression error: "
"%ju MiB would have been needed",
- (lzma_memusage(&(state->stream)) + 1024 * 1024 -1)
- / (1024 * 1024));
+ (uintmax_t)((lzma_memusage(&(state->stream)) + 1024 * 1024 -1)
+ / (1024 * 1024)));
return (ARCHIVE_FATAL);
default:
/* Any other return value indicates an error. */
diff --git a/lib/libarchive/archive_write_set_format_cpio.c b/lib/libarchive/archive_write_set_format_cpio.c
index a0bccc5..798646a 100644
--- a/lib/libarchive/archive_write_set_format_cpio.c
+++ b/lib/libarchive/archive_write_set_format_cpio.c
@@ -74,7 +74,7 @@ struct cpio_header {
char c_mtime[11];
char c_namesize[6];
char c_filesize[11];
-};
+} __packed;
/*
* Set output format to 'cpio' format.
diff --git a/lib/libarchive/archive_write_set_format_zip.c b/lib/libarchive/archive_write_set_format_zip.c
index d4d4f87..1bbbb6a 100644
--- a/lib/libarchive/archive_write_set_format_zip.c
+++ b/lib/libarchive/archive_write_set_format_zip.c
@@ -502,6 +502,9 @@ archive_write_zip_finish(struct archive_write *a)
int entries;
int ret;
+ if (a->compressor.write == NULL)
+ return (ARCHIVE_OK);
+
zip = a->format_data;
l = zip->central_directory;
diff --git a/lib/libarchive/test/Makefile b/lib/libarchive/test/Makefile
index 3f747b6..ba72db7 100644
--- a/lib/libarchive/test/Makefile
+++ b/lib/libarchive/test/Makefile
@@ -25,6 +25,7 @@ TESTS= \
test_fuzz.c \
test_link_resolver.c \
test_open_fd.c \
+ test_open_failure.c \
test_open_file.c \
test_open_filename.c \
test_pax_filename_encoding.c \
diff --git a/lib/libarchive/test/test_open_failure.c b/lib/libarchive/test/test_open_failure.c
new file mode 100644
index 0000000..0a7632a
--- /dev/null
+++ b/lib/libarchive/test/test_open_failure.c
@@ -0,0 +1,198 @@
+/*-
+ * Copyright (c) 2003-2010 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+#define MAGIC 123456789
+struct my_data {
+ int magic;
+ int read_return;
+ int read_called;
+ int write_return;
+ int write_called;
+ int open_return;
+ int open_called;
+ int close_return;
+ int close_called;
+};
+
+static ssize_t
+my_read(struct archive *a, void *_private, const void **buff)
+{
+ struct my_data *private = (struct my_data *)_private;
+ assertEqualInt(MAGIC, private->magic);
+ ++private->read_called;
+ return (private->read_return);
+}
+
+static ssize_t
+my_write(struct archive *a, void *_private, const void *buff, size_t s)
+{
+ struct my_data *private = (struct my_data *)_private;
+ assertEqualInt(MAGIC, private->magic);
+ ++private->write_called;
+ return (private->write_return);
+}
+
+static int
+my_open(struct archive *a, void *_private)
+{
+ struct my_data *private = (struct my_data *)_private;
+ assertEqualInt(MAGIC, private->magic);
+ ++private->open_called;
+ return (private->open_return);
+}
+
+static int
+my_close(struct archive *a, void *_private)
+{
+ struct my_data *private = (struct my_data *)_private;
+ assertEqualInt(MAGIC, private->magic);
+ ++private->close_called;
+ return (private->close_return);
+}
+
+
+DEFINE_TEST(test_open_failure)
+{
+ struct archive *a;
+ struct my_data private;
+
+ memset(&private, 0, sizeof(private));
+ private.magic = MAGIC;
+ private.open_return = ARCHIVE_FATAL;
+ a = archive_read_new();
+ assert(a != NULL);
+ assertEqualInt(ARCHIVE_FATAL,
+ archive_read_open(a, &private, my_open, my_read, my_close));
+ assertEqualInt(1, private.open_called);
+ assertEqualInt(0, private.read_called);
+ assertEqualInt(1, private.close_called);
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(1, private.open_called);
+ assertEqualInt(0, private.read_called);
+ assertEqualInt(1, private.close_called);
+
+ memset(&private, 0, sizeof(private));
+ private.magic = MAGIC;
+ private.open_return = ARCHIVE_FAILED;
+ a = archive_read_new();
+ assert(a != NULL);
+ assertEqualInt(ARCHIVE_FAILED,
+ archive_read_open(a, &private, my_open, my_read, my_close));
+ assertEqualInt(1, private.open_called);
+ assertEqualInt(0, private.read_called);
+ assertEqualInt(1, private.close_called);
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(1, private.open_called);
+ assertEqualInt(0, private.read_called);
+ assertEqualInt(1, private.close_called);
+
+ memset(&private, 0, sizeof(private));
+ private.magic = MAGIC;
+ private.open_return = ARCHIVE_WARN;
+ a = archive_read_new();
+ assert(a != NULL);
+ assertEqualInt(ARCHIVE_WARN,
+ archive_read_open(a, &private, my_open, my_read, my_close));
+ assertEqualInt(1, private.open_called);
+ assertEqualInt(0, private.read_called);
+ assertEqualInt(1, private.close_called);
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(1, private.open_called);
+ assertEqualInt(0, private.read_called);
+ assertEqualInt(1, private.close_called);
+
+ memset(&private, 0, sizeof(private));
+ private.magic = MAGIC;
+ private.open_return = ARCHIVE_OK;
+ private.read_return = ARCHIVE_FATAL;
+ a = archive_read_new();
+ assert(a != NULL);
+ assertEqualInt(ARCHIVE_OK,
+ archive_read_support_compression_compress(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_support_format_tar(a));
+ assertEqualInt(ARCHIVE_FATAL,
+ archive_read_open(a, &private, my_open, my_read, my_close));
+ assertEqualInt(1, private.open_called);
+ assertEqualInt(1, private.read_called);
+ assertEqualInt(1, private.close_called);
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+ assertEqualInt(1, private.open_called);
+ assertEqualInt(1, private.read_called);
+ assertEqualInt(1, private.close_called);
+
+ memset(&private, 0, sizeof(private));
+ private.magic = MAGIC;
+ private.open_return = ARCHIVE_FATAL;
+ a = archive_write_new();
+ assert(a != NULL);
+ assertEqualInt(ARCHIVE_FATAL,
+ archive_write_open(a, &private, my_open, my_write, my_close));
+ assertEqualInt(1, private.open_called);
+ assertEqualInt(0, private.write_called);
+ // Broken in 2.8, fixed in 3.0
+ //assertEqualInt(1, private.close_called);
+ assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(1, private.open_called);
+ assertEqualInt(0, private.write_called);
+ assertEqualInt(1, private.close_called);
+
+ memset(&private, 0, sizeof(private));
+ private.magic = MAGIC;
+ private.open_return = ARCHIVE_FATAL;
+ a = archive_write_new();
+ assert(a != NULL);
+ archive_write_set_compression_compress(a);
+ archive_write_set_format_zip(a);
+ assertEqualInt(ARCHIVE_FATAL,
+ archive_write_open(a, &private, my_open, my_write, my_close));
+ assertEqualInt(1, private.open_called);
+ assertEqualInt(0, private.write_called);
+ // Broken in 2.8, fixed in 3.0
+ //assertEqualInt(1, private.close_called);
+ assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(1, private.open_called);
+ assertEqualInt(0, private.write_called);
+ assertEqualInt(1, private.close_called);
+
+ memset(&private, 0, sizeof(private));
+ private.magic = MAGIC;
+ private.open_return = ARCHIVE_FATAL;
+ a = archive_write_new();
+ assert(a != NULL);
+ archive_write_set_compression_gzip(a);
+ assertEqualInt(ARCHIVE_FATAL,
+ archive_write_open(a, &private, my_open, my_write, my_close));
+ assertEqualInt(1, private.open_called);
+ assertEqualInt(0, private.write_called);
+ // Broken in 2.8, fixed in 3.0
+ //assertEqualInt(1, private.close_called);
+ assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
+ assertEqualInt(1, private.open_called);
+ assertEqualInt(0, private.write_called);
+ assertEqualInt(1, private.close_called);
+
+}
diff --git a/lib/libarchive/test/test_read_format_iso_2.iso.Z.uu b/lib/libarchive/test/test_read_format_iso_2.iso.Z.uu
new file mode 100644
index 0000000..6851f31
--- /dev/null
+++ b/lib/libarchive/test/test_read_format_iso_2.iso.Z.uu
@@ -0,0 +1,37 @@
+$FreeBSD$
+
+begin 644 test_read_format_iso_2.iso.Z
+M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR
+MI,F3*%.J7,FRI<N7,&/*G$FSILV;.'/JW,FSI\^?0(,*'4JTJ-&C2),J7<JT
+MJ=.G4*-*G4JUJM6K6+-JW<JUJ]>O8,.*'4NVK-FS:-.J7<NVK=NW<./*G4NW
+MKMV[>//JW<NWK]^_@`,+'DRXL.'#B!,K7LRXL>/'D"-+GDRYLN7+F#-KWLRY
+ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\
+MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^
+MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$Z408<04Q`!PH,01BCA
+MA!16:.&%$!Z404$;>G0@``%\>"`""`#@04$>2)#0!`.)```%!<%8HD`EEF+C
+MC:4($)"(!V+HXX]`!BGDD$06:>212":IY)),-NGDDU!&*>645%9II8\R%!@#
+M##C$0(,,,6Q)PPP$DI-EF%QZ"::89,)`#H%PQBDGG&=NV>67:(Y9YH?_]>GG
+MGX7](R"!!@)JZ*&()JKHHL<="...`AU80:0`!`$B`!=0.@2CG';JZ:>@A@H8
+MGR]>:FI`DP9@*:F9!BCJJ[#&*NNLM#[EXJ,#R3A0C3C:J*.I(0)P:XP`S!@0
+MK[W^RF,`+DY*T*3&%@O`&P@X4($"!I"C[(ZJNI@I09E&6R*UUBJP@+:0@NAJ
+MK>RVZ^Z[\$;7;$'0[CIMM==FNZVZPI9*D*XT`M"KK^F&&(`)`%A0D`4&%&0`
+MN?F20RF(!`CAP@XQQ*OQQAQW['%S:)3!!AMO*/#QR2BGK/+*G7I;4+CV0FPN
+MNL`>..R_T@8\<(X%AX@P!@5AT#!!#^,[\\0!$$#$Q1FS[/334$<M-6$ACUSR
+MU%AGK?767'?M]==@ARWVV&27;?;9:*>M]MILM^WVVW#'+??<=-=M]]UXYZWW
+MWGSW[???@`<N^."$%V[XX8@GKOCBC#?N^..01R[YY)17;OGEF&>N^>:<=^[Y
+MYZ"'+OKHI)=N^NFHIZ[ZZJRW[OKKL,<N^^RTUV[[[;CGKOONO/?N^^_`!R_\
+M\,07;_SQR">O_/+,-^_\\]!'+_WTU%=O_?789Z_]]MQW[_WWX(<O_OCDEV_^
+M^>BGK_[Z[+?O_OOPQR___/37;__]^.>O__[\]^___P`,H``'2,`"&O"`"$R@
+M`A?(P`8Z\($0C*`$)TC!"EKP@AC,H`8WR,$.>O"#(`RA"$=(PA*:\(0H3*$*
+M5\C"%KKPA3",H0QG2,,:VO"&.,RA#G?(PQ[Z\(=`#*(0ATC$(AKQB$A,HA*7
+MR,0F.O&)4(RB%*=(Q2I:\8I8S*(6M\C%+GKQBV`,HQC'2,8RFO&,:$RC&M?(
+MQC:Z\8UPC*,<YTC'.MKQCGC,HQ[WR,<^^O&/@`RD(`=)R$(:\I"(3*0B%\G(
+M1CKRD9",I"0G2<E*6O*2F,RD)C?)R4YZ\I.@#*4H1TG*4IKRE*A,I2I7R<I6
+MNO*5L(RE+&=)RUK:\I:XS*4N=\G+7OKRE\`,IC"'2<QB&O.8R$RF,I?)S&8Z
+M\YG0C*8TITG-:EKSFMC,IC:WR<UN>O.;X`RG.,=)SG*:\YSH3*<ZU\G.=KKS
+MG?",ISSG2<]ZVO.>^,RG/O?)SW[Z\Y\`#:A`!TK0@AKTH`A-J$(7RM"&.O2A
+M$(VH1"=*T8I:]*(8S:A&-\K1CGKTHR`-J4A'2M*2FO2D*$VI2E?*TI:Z]*4P
+MC:E,9TK3FMKTICC-J4YWRM.>^O2G0`VJ4(=*U*(:]:A(3:I2E\K4ICKUJ5"-
+MJE2G2M6J6O6J6,VJ5K?*U:YZ]:M@#:M8QTK6LIKUK&A-JUK7RM:VNO6M<`TG
+`
+end
diff --git a/lib/libarchive/test/test_read_format_iso_gz.c b/lib/libarchive/test/test_read_format_iso_gz.c
index 2289379..d0d6b3c 100644
--- a/lib/libarchive/test/test_read_format_iso_gz.c
+++ b/lib/libarchive/test/test_read_format_iso_gz.c
@@ -25,7 +25,8 @@
#include "test.h"
__FBSDID("$FreeBSD$");
-DEFINE_TEST(test_read_format_iso_gz)
+static void
+test1(void)
{
struct archive_entry *ae;
struct archive *a;
@@ -49,4 +50,50 @@ DEFINE_TEST(test_read_format_iso_gz)
assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
}
+static
+void test2(void)
+{
+ struct archive_entry *ae;
+ struct archive *a;
+ const char *name = "test_read_format_iso_2.iso.Z";
+
+ extract_reference_file(name);
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, name, 512));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_next_header(a, &ae));
+ assertEqualString(".", archive_entry_pathname(ae));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_next_header(a, &ae));
+ assertEqualString("A", archive_entry_pathname(ae));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_next_header(a, &ae));
+ assertEqualString("A/B", archive_entry_pathname(ae));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_next_header(a, &ae));
+ assertEqualString("C", archive_entry_pathname(ae));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_next_header(a, &ae));
+ assertEqualString("C/D", archive_entry_pathname(ae));
+ assertEqualIntA(a, ARCHIVE_EOF,
+ archive_read_next_header(a, &ae));
+ assertEqualInt(archive_compression(a),
+ ARCHIVE_COMPRESSION_COMPRESS);
+ assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+}
+
+DEFINE_TEST(test_read_format_iso_gz)
+{
+ test1();
+ test2();
+}
+
diff --git a/lib/libarchive/test/test_read_format_isojoliet_bz2.c b/lib/libarchive/test/test_read_format_isojoliet_bz2.c
index b2f22a7..ca2da83 100644
--- a/lib/libarchive/test/test_read_format_isojoliet_bz2.c
+++ b/lib/libarchive/test/test_read_format_isojoliet_bz2.c
@@ -95,7 +95,7 @@ DEFINE_TEST(test_read_format_isojoliet_bz2)
/* A regular file with two names ("hardlink" gets returned
* first, so it's not marked as a hardlink). */
assertEqualInt(0, archive_read_next_header(a, &ae));
- assertEqualString("long-joliet-file-name.textfile",
+ assertEqualString("hardlink",
archive_entry_pathname(ae));
assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
assert(archive_entry_hardlink(ae) == NULL);
@@ -108,9 +108,10 @@ DEFINE_TEST(test_read_format_isojoliet_bz2)
/* Second name for the same regular file (this happens to be
* returned second, so does get marked as a hardlink). */
assertEqualInt(0, archive_read_next_header(a, &ae));
- assertEqualString("hardlink", archive_entry_pathname(ae));
- assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
assertEqualString("long-joliet-file-name.textfile",
+ archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualString("hardlink",
archive_entry_hardlink(ae));
assert(!archive_entry_size_is_set(ae));
diff --git a/lib/libarchive/test/test_read_format_isojoliet_long.c b/lib/libarchive/test/test_read_format_isojoliet_long.c
index acd220f..d1d38d7 100644
--- a/lib/libarchive/test/test_read_format_isojoliet_long.c
+++ b/lib/libarchive/test/test_read_format_isojoliet_long.c
@@ -111,7 +111,7 @@ DEFINE_TEST(test_read_format_isojoliet_long)
pathname[102] = '3';
pathname[103] = '\0';
assertEqualInt(0, archive_read_next_header(a, &ae));
- assertEqualString(pathname, archive_entry_pathname(ae));
+ assertEqualString("hardlink", archive_entry_pathname(ae));
assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
assert(archive_entry_hardlink(ae) == NULL);
assertEqualInt(6, archive_entry_size(ae));
@@ -123,9 +123,9 @@ DEFINE_TEST(test_read_format_isojoliet_long)
/* Second name for the same regular file (this happens to be
* returned second, so does get marked as a hardlink). */
assertEqualInt(0, archive_read_next_header(a, &ae));
- assertEqualString("hardlink", archive_entry_pathname(ae));
+ assertEqualString(pathname, archive_entry_pathname(ae));
assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
- assertEqualString(pathname, archive_entry_hardlink(ae));
+ assertEqualString("hardlink", archive_entry_hardlink(ae));
assert(!archive_entry_size_is_set(ae));
/* End of archive. */
diff --git a/lib/libarchive/test/test_read_format_isojoliet_rr.c b/lib/libarchive/test/test_read_format_isojoliet_rr.c
index 394df14..b971272 100644
--- a/lib/libarchive/test/test_read_format_isojoliet_rr.c
+++ b/lib/libarchive/test/test_read_format_isojoliet_rr.c
@@ -98,7 +98,7 @@ DEFINE_TEST(test_read_format_isojoliet_rr)
/* A regular file with two names ("hardlink" gets returned
* first, so it's not marked as a hardlink). */
assertEqualInt(0, archive_read_next_header(a, &ae));
- assertEqualString("long-joliet-file-name.textfile",
+ assertEqualString("hardlink",
archive_entry_pathname(ae));
assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
assert(archive_entry_hardlink(ae) == NULL);
@@ -120,9 +120,10 @@ DEFINE_TEST(test_read_format_isojoliet_rr)
/* Second name for the same regular file (this happens to be
* returned second, so does get marked as a hardlink). */
assertEqualInt(0, archive_read_next_header(a, &ae));
- assertEqualString("hardlink", archive_entry_pathname(ae));
- assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
assertEqualString("long-joliet-file-name.textfile",
+ archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
+ assertEqualString("hardlink",
archive_entry_hardlink(ae));
assert(!archive_entry_size_is_set(ae));
assertEqualInt(86401, archive_entry_mtime(ae));
diff --git a/lib/libarchive/test/test_read_format_isorr_bz2.c b/lib/libarchive/test/test_read_format_isorr_bz2.c
index 730c112..b7cd704 100644
--- a/lib/libarchive/test/test_read_format_isorr_bz2.c
+++ b/lib/libarchive/test/test_read_format_isorr_bz2.c
@@ -97,9 +97,9 @@ DEFINE_TEST(test_read_format_isorr_bz2)
assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
assertEqualInt(1, archive_entry_uid(ae));
assertEqualInt(2, archive_entry_gid(ae));
- } else if (strcmp("hardlink", archive_entry_pathname(ae)) == 0) {
+ } else if (strcmp("file", archive_entry_pathname(ae)) == 0) {
/* A regular file. */
- assertEqualString("hardlink", archive_entry_pathname(ae));
+ assertEqualString("file", archive_entry_pathname(ae));
assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
assertEqualInt(12345684, archive_entry_size(ae));
assertEqualInt(0,
@@ -111,16 +111,16 @@ DEFINE_TEST(test_read_format_isorr_bz2)
assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
assertEqualInt(1, archive_entry_uid(ae));
assertEqualInt(2, archive_entry_gid(ae));
- } else if (strcmp("file", archive_entry_pathname(ae)) == 0) {
+ } else if (strcmp("hardlink", archive_entry_pathname(ae)) == 0) {
/* A hardlink to the regular file. */
/* Note: If "hardlink" gets returned before "file",
* then "hardlink" will get returned as a regular file
* and "file" will get returned as the hardlink.
* This test should tolerate that, since it's a
* perfectly permissible thing for libarchive to do. */
- assertEqualString("file", archive_entry_pathname(ae));
+ assertEqualString("hardlink", archive_entry_pathname(ae));
assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
- assertEqualString("hardlink", archive_entry_hardlink(ae));
+ assertEqualString("file", archive_entry_hardlink(ae));
assertEqualInt(0, archive_entry_size_is_set(ae));
assertEqualInt(0, archive_entry_size(ae));
assertEqualInt(86401, archive_entry_mtime(ae));
diff --git a/lib/libarchive/test/test_read_format_isorr_new_bz2.c b/lib/libarchive/test/test_read_format_isorr_new_bz2.c
index 5fa2492..c8554a0 100644
--- a/lib/libarchive/test/test_read_format_isorr_new_bz2.c
+++ b/lib/libarchive/test/test_read_format_isorr_new_bz2.c
@@ -98,9 +98,9 @@ DEFINE_TEST(test_read_format_isorr_new_bz2)
assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
assertEqualInt(1, archive_entry_uid(ae));
assertEqualInt(2, archive_entry_gid(ae));
- } else if (strcmp("hardlink", archive_entry_pathname(ae)) == 0) {
+ } else if (strcmp("file", archive_entry_pathname(ae)) == 0) {
/* A regular file. */
- assertEqualString("hardlink", archive_entry_pathname(ae));
+ assertEqualString("file", archive_entry_pathname(ae));
assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
assertEqualInt(12345684, archive_entry_size(ae));
assertEqualInt(0,
@@ -112,16 +112,16 @@ DEFINE_TEST(test_read_format_isorr_new_bz2)
assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
assertEqualInt(1, archive_entry_uid(ae));
assertEqualInt(2, archive_entry_gid(ae));
- } else if (strcmp("file", archive_entry_pathname(ae)) == 0) {
+ } else if (strcmp("hardlink", archive_entry_pathname(ae)) == 0) {
/* A hardlink to the regular file. */
/* Note: If "hardlink" gets returned before "file",
* then "hardlink" will get returned as a regular file
* and "file" will get returned as the hardlink.
* This test should tolerate that, since it's a
* perfectly permissible thing for libarchive to do. */
- assertEqualString("file", archive_entry_pathname(ae));
+ assertEqualString("hardlink", archive_entry_pathname(ae));
assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
- assertEqualString("hardlink", archive_entry_hardlink(ae));
+ assertEqualString("file", archive_entry_hardlink(ae));
assertEqualInt(0, archive_entry_size_is_set(ae));
assertEqualInt(0, archive_entry_size(ae));
assertEqualInt(86401, archive_entry_mtime(ae));
diff --git a/lib/libarchive/test/test_read_format_isozisofs_bz2.c b/lib/libarchive/test/test_read_format_isozisofs_bz2.c
index 56c39c0..a4f392e 100644
--- a/lib/libarchive/test/test_read_format_isozisofs_bz2.c
+++ b/lib/libarchive/test/test_read_format_isozisofs_bz2.c
@@ -96,10 +96,10 @@ DEFINE_TEST(test_read_format_isozisofs_bz2)
assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
assertEqualInt(1, archive_entry_uid(ae));
assertEqualInt(2, archive_entry_gid(ae));
- } else if (strcmp("hardlink", archive_entry_pathname(ae)) == 0) {
+ } else if (strcmp("file", archive_entry_pathname(ae)) == 0) {
int r;
/* A regular file. */
- assertEqualString("hardlink", archive_entry_pathname(ae));
+ assertEqualString("file", archive_entry_pathname(ae));
assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
assertEqualInt(12345684, archive_entry_size(ae));
r = archive_read_data_block(a, &p, &size, &offset);
@@ -111,23 +111,23 @@ DEFINE_TEST(test_read_format_isozisofs_bz2)
assertEqualMem(p, "hello\n", 6);
}
assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(86401, archive_entry_atime(ae));
assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
assertEqualInt(1, archive_entry_uid(ae));
assertEqualInt(2, archive_entry_gid(ae));
- } else if (strcmp("file", archive_entry_pathname(ae)) == 0) {
+ } else if (strcmp("hardlink", archive_entry_pathname(ae)) == 0) {
/* A hardlink to the regular file. */
/* Note: If "hardlink" gets returned before "file",
* then "hardlink" will get returned as a regular file
* and "file" will get returned as the hardlink.
* This test should tolerate that, since it's a
* perfectly permissible thing for libarchive to do. */
- assertEqualString("file", archive_entry_pathname(ae));
+ assertEqualString("hardlink", archive_entry_pathname(ae));
assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
- assertEqualString("hardlink", archive_entry_hardlink(ae));
+ assertEqualString("file", archive_entry_hardlink(ae));
assertEqualInt(0, archive_entry_size_is_set(ae));
assertEqualInt(0, archive_entry_size(ae));
assertEqualInt(86401, archive_entry_mtime(ae));
- assertEqualInt(86401, archive_entry_atime(ae));
assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
assertEqualInt(1, archive_entry_uid(ae));
assertEqualInt(2, archive_entry_gid(ae));
diff --git a/lib/libarchive/test/test_read_format_mtree.c b/lib/libarchive/test/test_read_format_mtree.c
index 5001e4d..93e658f 100644
--- a/lib/libarchive/test/test_read_format_mtree.c
+++ b/lib/libarchive/test/test_read_format_mtree.c
@@ -134,10 +134,53 @@ test_read_format_mtree2(void)
assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
}
+/*
+ * Reported to libarchive.googlecode.com as Issue 121.
+ */
+static void
+test_read_format_mtree3(void)
+{
+ static char archive[] =
+ "#mtree\n"
+ "a type=file contents=file\n"
+ "b type=link link=a\n"
+ "c type=file contents=file\n";
+ struct archive_entry *ae;
+ struct archive *a;
+
+ assertMakeDir("mtree3", 0777);
+ assertChdir("mtree3");
+ assertMakeFile("file", 0644, "file contents");
+
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_support_compression_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_support_format_all(a));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_memory(a, archive, sizeof(archive)));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "a");
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "b");
+ assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString(archive_entry_pathname(ae), "c");
+ assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
+
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
+
+ assertChdir("..");
+}
+
DEFINE_TEST(test_read_format_mtree)
{
test_read_format_mtree1();
test_read_format_mtree2();
+ test_read_format_mtree3();
}
diff --git a/lib/libarchive/test/test_write_compress_lzma.c b/lib/libarchive/test/test_write_compress_lzma.c
index 639e58f..88b9d63 100644
--- a/lib/libarchive/test/test_write_compress_lzma.c
+++ b/lib/libarchive/test/test_write_compress_lzma.c
@@ -185,10 +185,15 @@ DEFINE_TEST(test_write_compress_lzma)
archive_write_close(a);
assert(0 == archive_write_finish(a));
- /* Level 0 really does result in larger data. */
+ /* It would be nice to assert that compression-level=0 produced
+ * consistently larger/smaller results than the default compression,
+ * but the results here vary a lot depending on the version of liblzma
+ * being used. */
+ /*
failure("Compression-level=0 wrote %d bytes; default wrote %d bytes",
(int)used2, (int)used1);
assert(used2 > used1);
+ */
assert((a = archive_read_new()) != NULL);
assertA(0 == archive_read_support_format_all(a));
diff --git a/lib/libarchive/test/test_write_compress_xz.c b/lib/libarchive/test/test_write_compress_xz.c
index 988fb6e..554d163 100644
--- a/lib/libarchive/test/test_write_compress_xz.c
+++ b/lib/libarchive/test/test_write_compress_xz.c
@@ -193,10 +193,14 @@ DEFINE_TEST(test_write_compress_xz)
archive_write_close(a);
assert(0 == archive_write_finish(a));
- /* Level 0 really does result in larger data. */
+ /* I would like to assert that compression-level=0 results in
+ * larger data than the default compression, but that's not true
+ * for all versions of liblzma. */
+ /*
failure("Compression-level=0 wrote %d bytes; default wrote %d bytes",
(int)used2, (int)used1);
assert(used2 > used1);
+ */
assert((a = archive_read_new()) != NULL);
assertA(0 == archive_read_support_format_all(a));
diff --git a/lib/libbsnmp/libbsnmp/Makefile b/lib/libbsnmp/libbsnmp/Makefile
index d33808d..f21f1d3 100644
--- a/lib/libbsnmp/libbsnmp/Makefile
+++ b/lib/libbsnmp/libbsnmp/Makefile
@@ -8,7 +8,7 @@ CONTRIB= ${.CURDIR}/../../../contrib/bsnmp/lib
.PATH: ${CONTRIB}
LIB= bsnmp
-SHLIBDIR?= /lib
+SHLIB_MAJOR= 6
CFLAGS+= -I${CONTRIB} -DHAVE_ERR_H -DHAVE_GETADDRINFO -DHAVE_STRLCPY
CFLAGS+= -DHAVE_STDINT_H -DHAVE_INTTYPES_H -DQUADFMT='"llu"' -DQUADXFMT='"llx"'
diff --git a/lib/libc/amd64/string/Makefile.inc b/lib/libc/amd64/string/Makefile.inc
index f5d69d6..46571ab 100644
--- a/lib/libc/amd64/string/Makefile.inc
+++ b/lib/libc/amd64/string/Makefile.inc
@@ -1,4 +1,4 @@
# $FreeBSD$
MDSRCS+= bcmp.S bcopy.S bzero.S memcmp.S memcpy.S memmove.S memset.S \
- strcat.S strcmp.S strcpy.S
+ strcat.S strcmp.S stpcpy.S strcpy.c
diff --git a/lib/libc/amd64/string/strcpy.S b/lib/libc/amd64/string/stpcpy.S
index 5feb925..52ac69c 100644
--- a/lib/libc/amd64/string/strcpy.S
+++ b/lib/libc/amd64/string/stpcpy.S
@@ -1,17 +1,14 @@
/*
- * Written by J.T. Conklin <jtc@acorntoolworks.com>
+ * Adapted by Guillaume Morin <guillaume@morinfr.org> from strcpy.S
+ * written by J.T. Conklin <jtc@acorntoolworks.com>
* Public domain.
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
-#if 0
- RCSID("$NetBSD: strcpy.S,v 1.3 2004/07/19 20:04:41 drochner Exp $")
-#endif
-
/*
- * This strcpy implementation copies a byte at a time until the
+ * This stpcpy implementation copies a byte at a time until the
* source pointer is aligned to a word boundary, it then copies by
* words until it finds a word containing a zero byte, and finally
* copies by bytes until the end of the string is reached.
@@ -23,10 +20,11 @@ __FBSDID("$FreeBSD$");
* requirements.
*/
-ENTRY(strcpy)
- movq %rdi,%rax
- movabsq $0x0101010101010101,%r8
- movabsq $0x8080808080808080,%r9
+ .globl stpcpy,__stpcpy
+ENTRY(stpcpy)
+__stpcpy:
+ movabsq $0x0101010101010101,%r8
+ movabsq $0x8080808080808080,%r9
/*
* Align source to a word boundary.
@@ -41,6 +39,8 @@ ENTRY(strcpy)
incq %rdi
testb %dl,%dl
jne .Lalign
+ movq %rdi,%rax
+ dec %rax
ret
.p2align 4
@@ -61,54 +61,56 @@ ENTRY(strcpy)
*/
movb %dl,(%rdi)
- incq %rdi
testb %dl,%dl /* 1st byte == 0? */
je .Ldone
+ incq %rdi
shrq $8,%rdx
movb %dl,(%rdi)
- incq %rdi
testb %dl,%dl /* 2nd byte == 0? */
je .Ldone
+ incq %rdi
shrq $8,%rdx
movb %dl,(%rdi)
- incq %rdi
testb %dl,%dl /* 3rd byte == 0? */
je .Ldone
+ incq %rdi
shrq $8,%rdx
movb %dl,(%rdi)
- incq %rdi
testb %dl,%dl /* 4th byte == 0? */
je .Ldone
+ incq %rdi
shrq $8,%rdx
movb %dl,(%rdi)
- incq %rdi
testb %dl,%dl /* 5th byte == 0? */
je .Ldone
+ incq %rdi
shrq $8,%rdx
movb %dl,(%rdi)
- incq %rdi
testb %dl,%dl /* 6th byte == 0? */
je .Ldone
+ incq %rdi
shrq $8,%rdx
movb %dl,(%rdi)
- incq %rdi
testb %dl,%dl /* 7th byte == 0? */
je .Ldone
+ incq %rdi
shrq $8,%rdx
movb %dl,(%rdi)
incq %rdi
testb %dl,%dl /* 8th byte == 0? */
jne .Lword_aligned
+ decq %rdi
.Ldone:
+ movq %rdi,%rax
ret
-END(strcpy)
-
+END(stpcpy)
+
.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/amd64/string/strcpy.c b/lib/libc/amd64/string/strcpy.c
new file mode 100644
index 0000000..11a24eb
--- /dev/null
+++ b/lib/libc/amd64/string/strcpy.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2011 George V. Neville-Neil. All rights reserved.
+ *
+ * The compilation of software known as FreeBSD is distributed under the
+ * following terms:
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+char *__stpcpy(char * __restrict, const char * __restrict);
+
+char *
+strcpy(char * __restrict to, const char * __restrict from)
+{
+ __stpcpy(to, from);
+ return(to);
+}
diff --git a/lib/libc/net/ethers.3 b/lib/libc/net/ethers.3
index c8aa51a..6fe568b 100644
--- a/lib/libc/net/ethers.3
+++ b/lib/libc/net/ethers.3
@@ -68,7 +68,7 @@
These functions operate on ethernet addresses using an
.Vt ether_addr
structure, which is defined in the header file
-.In netinet/if_ether.h :
+.In net/ethernet.h :
.Bd -literal -offset indent
/*
* The number of bytes in an ethernet (MAC) address.
diff --git a/lib/libc/net/sctp_sys_calls.c b/lib/libc/net/sctp_sys_calls.c
index 27664bc..0d721d5 100644
--- a/lib/libc/net/sctp_sys_calls.c
+++ b/lib/libc/net/sctp_sys_calls.c
@@ -410,6 +410,9 @@ sctp_opt_info(int sd, sctp_assoc_t id, int opt, void *arg, socklen_t * size)
case SCTP_DEFAULT_PRINFO:
((struct sctp_default_prinfo *)arg)->pr_assoc_id = id;
break;
+ case SCTP_PEER_ADDR_THLDS:
+ ((struct sctp_paddrthlds *)arg)->spt_assoc_id = id;
+ break;
case SCTP_MAX_BURST:
((struct sctp_assoc_value *)arg)->assoc_id = id;
break;
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc
index d5b151c..3627294 100644
--- a/lib/libc/stdlib/Makefile.inc
+++ b/lib/libc/stdlib/Makefile.inc
@@ -51,7 +51,3 @@ MLINKS+=tsearch.3 tdelete.3 tsearch.3 tfind.3 tsearch.3 twalk.3
CFLAGS+= -DMALLOC_PRODUCTION
.endif
-.if ${CC:T:Mclang} == "clang"
-# XXX: Temporary workaround for LLVM PR 9352
-CFLAGS+= ${.IMPSRC:T:Mmalloc.c:C/^.+$/-no-integrated-as/}
-.endif
diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc
index 008180a..fe5061d 100644
--- a/lib/libc/sys/Makefile.inc
+++ b/lib/libc/sys/Makefile.inc
@@ -77,7 +77,7 @@ ${SPSEUDO}:
MAN+= abort2.2 accept.2 access.2 acct.2 adjtime.2 \
aio_cancel.2 aio_error.2 aio_read.2 aio_return.2 \
aio_suspend.2 aio_waitcomplete.2 aio_write.2 \
- bind.2 brk.2 cap_enter.2 chdir.2 chflags.2 \
+ bind.2 brk.2 cap_enter.2 cap_new.2 chdir.2 chflags.2 \
chmod.2 chown.2 chroot.2 clock_gettime.2 close.2 closefrom.2 \
connect.2 cpuset.2 cpuset_getaffinity.2 dup.2 execve.2 _exit.2 \
extattr_get_file.2 fcntl.2 fhopen.2 flock.2 fork.2 fsync.2 \
@@ -96,7 +96,7 @@ MAN+= abort2.2 accept.2 access.2 acct.2 adjtime.2 \
mq_setattr.2 \
msgctl.2 msgget.2 msgrcv.2 msgsnd.2 \
msync.2 munmap.2 nanosleep.2 nfssvc.2 ntp_adjtime.2 open.2 \
- pathconf.2 pipe.2 poll.2 posix_fallocate.2 posix_openpt.2 profil.2 \
+ pathconf.2 pdfork.2 pipe.2 poll.2 posix_fallocate.2 posix_openpt.2 profil.2 \
pselect.2 ptrace.2 quotactl.2 \
read.2 readlink.2 reboot.2 recv.2 rename.2 revoke.2 rfork.2 rmdir.2 \
rtprio.2
@@ -119,6 +119,7 @@ MAN+= sctp_generic_recvmsg.2 sctp_generic_sendmsg.2 sctp_peeloff.2 \
MLINKS+=access.2 eaccess.2 access.2 faccessat.2
MLINKS+=brk.2 sbrk.2
MLINKS+=cap_enter.2 cap_getmode.2
+MLINKS+=cap_new.2 cap_getrights.2
MLINKS+=chdir.2 fchdir.2
MLINKS+=chflags.2 fchflags.2 chflags.2 lchflags.2
MLINKS+=chmod.2 fchmod.2 chmod.2 fchmodat.2 chmod.2 lchmod.2
@@ -177,6 +178,9 @@ MLINKS+=ntp_adjtime.2 ntp_gettime.2
MLINKS+=open.2 openat.2
MLINKS+=pathconf.2 fpathconf.2
MLINKS+=pathconf.2 lpathconf.2
+MLINKS+=pdfork.2 pdgetpid.2\
+ pdfork.2 pdkill.2 \
+ pdfork.2 pdwait4.2
MLINKS+=read.2 pread.2 read.2 preadv.2 read.2 readv.2
MLINKS+=readlink.2 readlinkat.2
MLINKS+=recv.2 recvfrom.2 recv.2 recvmsg.2
diff --git a/lib/libc/sys/Symbol.map b/lib/libc/sys/Symbol.map
index cd31f24..095751a 100644
--- a/lib/libc/sys/Symbol.map
+++ b/lib/libc/sys/Symbol.map
@@ -363,7 +363,12 @@ FBSD_1.1 {
FBSD_1.2 {
cap_enter;
cap_getmode;
+ cap_new;
+ cap_getrights;
getloginclass;
+ pdfork;
+ pdgetpid;
+ pdkill;
posix_fallocate;
rctl_get_racct;
rctl_get_rules;
diff --git a/lib/libc/sys/cap_new.2 b/lib/libc/sys/cap_new.2
new file mode 100644
index 0000000..206715e
--- /dev/null
+++ b/lib/libc/sys/cap_new.2
@@ -0,0 +1,474 @@
+.\"
+.\" Copyright (c) 2008-2010 Robert N. M. Watson
+.\" All rights reserved.
+.\"
+.\" This software was developed at the University of Cambridge Computer
+.\" Laboratory with support from a grant from Google, Inc.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 20, 2011
+.Dt CAP_NEW 2
+.Os
+.Sh NAME
+.Nm cap_new ,
+.Nm cap_getrights
+.Nd System calls to manipulate capabilities
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/capability.h
+.Ft int
+.Fn cap_new "int fd" "cap_rights_t rights"
+.Ft int
+.Fn cap_getrights "int fd" "cap_rights_t *rightsp"
+.Sh DESCRIPTION
+Capabilities are special file descriptors derived from an existing file
+descriptor, such as one returned by
+.Xr fhopen 2 ,
+.Xr kqueue 2 ,
+.Xr mq_open 2 ,
+.Xr open 2 ,
+.Xr pipe 2 ,
+.Xr shm_open 2 ,
+.Xr socket 2 ,
+or
+.Xr socketpair 2 ,
+but with a restricted set of permitted operations determined by a rights
+mask set when the capability is created.
+These restricted rights cannot be changed after the capability is created,
+although further capabilities with yet more restricted rights may be created
+from an existing capability.
+In every other sense, a capability behaves in the same way as the file
+descriptor it was created from.
+.Pp
+.Fn cap_new
+creates a new capability for the existing file descriptor
+.Fa fd ,
+and returns a file descriptor for it.
+Operations on the capability will be limited to those permitted by
+.Fa rights ,
+which is static for the lifetime of the capability.
+If
+.Fa fd
+refers to an existing capability, then
+.Fa rights
+must be equal to or a subset of the rights on that capability.
+As with
+.Xr dup 2
+and
+.Xr dup2 2 ,
+many properties are shared between the new capability and the existing file
+descriptor, including open file flags, blocking disposition, and file offset.
+Many applications will prefer to use the
+.Xr cap_limitfd 3
+library call, part of
+.Xr libcapsicum 3 ,
+as it offers a more convenient interface.
+.Pp
+.Fn cap_getrights
+queries the rights associated with the capability referred to by file
+descriptor
+.Fa fd .
+.Pp
+These system calls, when combined with
+.Xr cap_enter 2 ,
+may be used to construct process sandboxes with highly granular rights
+assignment.
+.Sh RIGHTS
+The following rights may be specified in a new capability rights mask:
+.Bl -tag -width CAP_EXTATTR_DELETE
+.It Dv CAP_ACCEPT
+Permit
+.Xr accept 2 .
+.It Dv CAP_ACL_CHECK
+Permit checking of an ACL on a file descriptor; there is no cross-reference
+for this system call.
+.It Dv CAP_ACL_DELETE
+Permit
+.Xr acl_delete_fd_np 2 .
+.It Dv CAP_ACL_GET
+Permit
+.Xr acl_get_fd 2
+and
+.Xr acl_get_fd_np 2 .
+.It Dv CAP_ACL_SET
+Permit
+.Xr acl_set_fd 2
+and
+.Xr acl_set_fd_np 2 .
+.It Dv CAP_BIND
+Permit
+.Xr bind 2 .
+Note that sockets can also become bound implicitly as a result of
+.Xr connect 2
+or
+.Xr send 2 ,
+and that socket options set with
+.Xr setsockopt 2
+may also affect binding behavior.
+.It Dv CAP_CONNECT
+Permit
+.Xr connect 2 ;
+also required for
+.Xr sendto 2
+with a non-NULL destination address.
+.It Dv CAP_EVENT
+Permit
+.Xr select 2 ,
+.Xr poll 2 ,
+and
+.Xr kevent 2
+to be used in monitoring the file descriptor for events.
+.It Dv CAP_FEXECVE
+Permit
+.Xr fexecve 2 ;
+.Dv CAP_READ
+will also be required.
+.It Dv CAP_EXTATTR_DELETE
+Permit
+.Xr extattr_delete_fd 2 .
+.It Dv CAP_EXTATTR_GET
+Permit
+.Xr extattr_get_fd 2 .
+.It Dv CAP_EXTATTR_LIST
+Permit
+.Xr extattr_list_fd 2 .
+.It Dv CAP_EXTATTR_SET
+Permit
+.Xr extattr_set_fd 2 .
+.It Dv CAP_FCHDIR
+Permit
+.Xr fchdir 2 .
+.It Dv CAP_FCHFLAGS
+Permit
+.Xr fchflags 2 .
+.It Dv CAP_FCHMOD
+Permit
+.Xr fchmod 2 .
+.It Dv CAP_FCHOWN
+Permit
+.Xr fchown 2 .
+.It Dv CAP_FCNTL
+Permit
+.Xr fcntl 2 ;
+be aware that this call provides indirect access to other operations, such as
+.Xr flock 2 .
+.It Dv CAP_FLOCK
+Permit
+.Xr flock 2
+and related calls.
+.It Dv CAP_FPATHCONF
+Permit
+.Xr fpathconf 2 .
+.It Dv CAP_FSCK
+Permit UFS background-fsck operations on the descriptor.
+.It Dv CAP_FSTAT
+Permit
+.Xr fstat 2 .
+.It Dv CAP_FSTATFS
+Permit
+.Xr fstatfs 2 .
+.It Dv CAP_FSYNC
+Permit
+.Xr aio_fsync 2
+and
+.Xr fsync 2 .
+.Pp
+.It Dv CAP_FTRUNCATE
+Permit
+.Xr ftruncate 2 .
+.It Dv CAP_FUTIMES
+Permit
+.Xr futimes 2 .
+.It Dv CAP_GETPEERNAME
+Permit
+.Xr getpeername 2 .
+.It Dv CAP_GETSOCKNAME
+Permit
+.Xr getsockname 2 .
+.It Dv CAP_GETSOCKOPT
+Permit
+.Xr getsockopt 2 .
+.It Dv CAP_IOCTL
+Permit
+.Xr ioctl 2 .
+Be aware that this system call has enormous scope, including potentially
+global scope for some objects.
+.It Dv CAP_KEVENT
+Permit
+.Xr kevent 2 ;
+.Dv CAP_EVENT
+is also required on file descriptors that will be monitored using
+.Xr kevent 2 .
+.It Dv CAP_LISTEN
+Permit
+.Xr listen 2 ;
+not much use (generally) without
+.Dv CAP_BIND .
+.It Dv CAP_LOOKUP
+Permit the file descriptor to be used as a starting directory for calls such
+as
+.Xr linkat 2 ,
+.Xr openat 2 ,
+and
+.Xr unlinkat 2 .
+Note that these calls are not available in capability mode as they manipulate
+a global name space; see
+.Xr cap_enter 2
+for details.
+.It Dv CAP_MAC_GET
+Permit
+.Xr mac_get_fd 2 .
+.It Dv CAP_MAC_SET
+Permit
+.Xr mac_set_fd 2 .
+.It Dv CAP_MMAP
+Permit
+.Xr mmap 2 ;
+specific invocations may also require
+.Dv CAP_READ
+or
+.Dv CAP_WRITE .
+.Pp
+.It Dv CAP_PDGETPID
+Permit
+.Xr pdgetpid 2 .
+.It Dv CAP_PDKILL
+Permit
+.Xr pdkill 2 .
+.It Dv CAP_PDWAIT
+Permit
+.Xr pdwait4 2 .
+.It Dv CAP_PEELOFF
+Permit
+.Xr sctp_peeloff 2 .
+.It Dv CAP_READ
+Allow
+.Xr aio_read 2 ,
+.Xr pread 2 ,
+.Xr read 2 ,
+.Xr recv 2 ,
+.Xr recvfrom 2 ,
+.Xr recvmsg 2 ,
+and related system calls.
+.Pp
+For files and other seekable objects,
+.Dv CAP_SEEK
+may also be required.
+.It Dv CAP_REVOKE
+Permit
+.Xr frevoke 2
+in certain ABI compatibility modes that support this system call.
+.It Dv CAP_SEEK
+Permit operations that seek on the file descriptor, such as
+.Xr lseek 2 ,
+but also required for I/O system calls that modify the file offset, such as
+.Xr read 2
+and
+.Xr write 2 .
+.It Dv CAP_SEM_GETVALUE
+Permit
+.Xr sem_getvalue 3 .
+.It Dv CAP_SEM_POST
+Permit
+.Xr sem_post 3 .
+.It Dv CAP_SEM_WAIT
+Permit
+.Xr sem_wait 3
+and
+.Xr sem_trywait 3 .
+.It Dv CAP_SETSOCKOPT
+Permit
+.Xr setsockopt 2 ;
+this controls various aspects of socket behavior and may affect binding,
+connecting, and other behaviors with global scope.
+.It Dv CAP_SHUTDOWN
+Permit explicit
+.Xr shutdown 2 ;
+closing the socket will also generally shut down any connections on it.
+.It Dv CAP_TTYHOOK
+Allow configuration of TTY hooks, such as
+.Xr snp 4 ,
+on the file descriptor.
+.It Dv CAP_WRITE
+Allow
+.Xr aio_write 2 ,
+.Xr pwrite 2 ,
+.Xr send 2 ,
+.Xr sendmsg 2 ,
+.Xr sendto 2 ,
+.Xr write 2 ,
+and related system calls.
+.Pp
+For files and other seekable objects,
+.Dv CAP_SEEK
+may also be required.
+.Pp
+For
+.Xr sendto 2
+with a non-NULL connection address,
+.Dv CAP_CONNECT
+is also required.
+.El
+.Sh CAVEAT
+The
+.Fn cap_new
+system call and the capabilities it creates may be used to assign
+fine-grained rights to sandboxed processes running in capability mode.
+However, the semantics of objects accessed via file descriptors are complex,
+so caution should be exercised in passing object capabilities into sandboxes.
+.Sh RETURN VALUES
+If successful,
+.Fn cap_new
+returns a non-negative integer, termed a file descriptor.
+It returns -1 on failure, and sets
+.Va errno
+to indicate the error.
+.Pp
+.Rv -std cap_getrights
+.Sh ERRORS
+.Fn cap_new
+may return the following errors:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa fd
+argument is not a valid active descriptor.
+.It Bq Er EINVAL
+An invalid right has been requested in
+.Fa rights .
+.It Bq Er EMFILE
+The process has already reached its limit for open file descriptors.
+.It Bq Er ENFILE
+The system file table is full.
+.It Bq Er EPERM
+.Fa rights
+contains requested rights not present in the current rights mask associated
+with the capability referenced by
+.Fa fd ,
+if any.
+.El
+.Pp
+.Fn cap_getrights
+may return the following errors:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa fd
+argument is not a valid active descriptor.
+.It Bq Er EINVAL
+The
+.Fa fd
+argument is not a capability.
+.El
+.Sh SEE ALSO
+.Xr accept 2 ,
+.Xr acl_delete_fd_np 2 ,
+.Xr acl_get_fd 2 ,
+.Xr acl_get_fd_np 2 ,
+.Xr acl_set_fd_np 2 ,
+.Xr aio_read 2 ,
+.Xr aio_fsync 2 ,
+.Xr aio_write 2 ,
+.Xr bind 2 ,
+.Xr cap_enter 2 ,
+.Xr connect 2 ,
+.Xr dup 2 ,
+.Xr dup2 2 ,
+.Xr extattr_delete_fd 2 ,
+.Xr extattr_get_fd 2 ,
+.Xr extattr_list_fd 2 ,
+.Xr extattr_set_fd 2 ,
+.Xr fchflags 2 ,
+.Xr fchown 2 ,
+.Xr fcntl 2 ,
+.Xr fexecve 2 ,
+.Xr fhopen 2 ,
+.Xr flock 2 ,
+.Xr fpathconf 2 ,
+.Xr fstat 2 ,
+.Xr fstatfs 2 ,
+.Xr fsync 2 ,
+.Xr ftruncate 2 ,
+.Xr futimes 2 ,
+.Xr getpeername 2 ,
+.Xr getsockname 2 ,
+.Xr getsockopt 2 ,
+.Xr ioctl 2 ,
+.Xr kevent 2 ,
+.Xr kqueue 2 ,
+.Xr linkat 2 ,
+.Xr listen 2 ,
+.Xr mac_get_fd 2 ,
+.Xr mac_set_fd 2 ,
+.Xr mmap 2 ,
+.Xr mq_open 2 ,
+.Xr open 2 ,
+.Xr openat 2 ,
+.Xr pdgetpid 2 ,
+.Xr pdkill 2 ,
+.Xr pdwait4 2 ,
+.Xr pipe 2 ,
+.Xr poll 2 ,
+.Xr pread 2 ,
+.Xr pwrite 2 ,
+.Xr read 2 ,
+.Xr recv 2 ,
+.Xr recvfrom 2 ,
+.Xr recvmsg 2 ,
+.Xr sctp_peeloff 2 ,
+.Xr select 2 ,
+.Xr send 2 ,
+.Xr sendmsg 2 ,
+.Xr sendto 2 ,
+.Xr setsockopt 2 ,
+.Xr shm_open 2 ,
+.Xr shutdown 2 ,
+.Xr socket 2 ,
+.Xr socketpair 2 ,
+.Xr unlinkat 2 ,
+.Xr write 2 ,
+.Xr cap_limitfd 3 ,
+.Xr libcapsicum 3 ,
+.Xr sem_getvalue 3 ,
+.Xr sem_post 3 ,
+.Xr sem_trywait 3 ,
+.Xr sem_wait 3 ,
+.Xr snp 4
+.Sh HISTORY
+Support for capabilities and capabilities mode was developed as part of the
+.Tn TrustedBSD
+Project.
+.Sh BUGS
+This man page should list the set of permitted system calls more specifically
+for each capability right.
+.Pp
+Capability rights sometimes have unclear indirect impacts, which should be
+documented, or at least hinted at.
+.Sh AUTHORS
+These functions and the capability facility were created by
+.An "Robert N. M. Watson"
+at the University of Cambridge Computer Laboratory with support from a grant
+from Google, Inc.
diff --git a/lib/libc/sys/dup.2 b/lib/libc/sys/dup.2
index c87b386..f6f6f46 100644
--- a/lib/libc/sys/dup.2
+++ b/lib/libc/sys/dup.2
@@ -28,7 +28,7 @@
.\" @(#)dup.2 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd June 4, 1993
+.Dd August 14, 2011
.Dt DUP 2
.Os
.Sh NAME
@@ -115,6 +115,11 @@ and
is a valid descriptor, then
.Fn dup2
is successful, and does nothing.
+.Pp
+The related
+.Xr cap_new 2
+system call allows file descriptors to be duplicated with restrictions on
+their use.
.Sh RETURN VALUES
The value -1 is returned if an error occurs in either call.
The external variable
@@ -139,6 +144,7 @@ Too many descriptors are active.
.El
.Sh SEE ALSO
.Xr accept 2 ,
+.Xr cap_new 2 ,
.Xr close 2 ,
.Xr fcntl 2 ,
.Xr getdtablesize 2 ,
diff --git a/lib/libc/sys/pdfork.2 b/lib/libc/sys/pdfork.2
new file mode 100644
index 0000000..3f36e88
--- /dev/null
+++ b/lib/libc/sys/pdfork.2
@@ -0,0 +1,182 @@
+.\"
+.\" Copyright (c) 2009-2010 Robert N. M. Watson
+.\" All rights reserved.
+.\"
+.\" This software was developed at the University of Cambridge Computer
+.\" Laboratory with support from a grant from Google, Inc.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 16, 2011
+.Dt PDFORK 2
+.Os
+.Sh NAME
+.Nm pdfork ,
+.Nm pdgetpid ,
+.Nm pdkill ,
+.Nm pdwait4
+.Nd System calls to manage process descriptors
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/procdesc.h
+.Ft int
+.Fn pdfork "int *fdp" "int flags"
+.Ft int
+.Fn pdgetpid "int fd" "pid_t *pidp"
+.Ft int
+.Fn pdkill "int fd" "int signum"
+.Ft int
+.Fn pdwait4 "int fd" "int *status" "int options" "struct rusage *rusage"
+.Sh DESCRIPTION
+Process descriptors are special file descriptors that represent processes,
+and are created using
+.Fn pdfork ,
+a variant of
+.Xr fork 2 ,
+which, if successful, returns a process descriptor in the integer pointed to
+by
+.Fa pidp .
+Processes created via
+.Fn pdfork
+will not cause
+.Dv SIGCHLD
+on termination.
+.Fn pdfork
+can accept the flags:
+.Bl -tag -width ".Dv PD_DAEMON"
+.It Dv PD_DAEMON
+Instead of the default terminate-on-close behaviour, allow the process to
+live until it is explicitly killed with
+.Xr kill 2 .
+.Pp
+This option is not permitted in Capsicum capability mode (see
+.Xr cap_enter 2 ) .
+.El
+.Pp
+.Fn pdgetpid
+queries the process ID (PID) if the process descriptor
+.Fa fd .
+.Pp
+.Fn pdkill
+is functionally identical to
+.Xr kill 2 ,
+except that it accepts a process descriptor,
+.Fa fd ,
+rather than a PID.
+.Pp
+.Fn pdwait4
+behaves identially to
+.Xr wait4 2 ,
+but operates with respect to a process descriptor argument rather than a PID.
+.Pp
+The following system calls also have effects specific to process descriptors:
+.Pp
+.Xr fstat 2
+queries status of a process descriptor; currently only the
+.Fa st_mode ,
+.Fa st_birthtime ,
+.Fa st_atime ,
+.Fa st_ctime
+and
+.Fa st_mtime
+fields are defined. If the owner read, write, and execute bits are set then the
+process represented by the process descriptor is still alive.
+.Pp
+.Xr poll 2
+and
+.Xr select 2
+allow waiting for process state transitions; currently only
+.Dv POLLHUP
+is defined, and will be raised when the process dies.
+.Pp
+.Xr close 2
+will close the process descriptor unless
+.Dv PD_DAEMON
+is set; if the process is still alive and this is
+the last reference to the process descriptor, the process will be terminated
+with the signal
+.Dv SIGKILL .
+.Sh RETURN VALUES
+.Fn pdfork
+returns a PID, 0 or -1, as
+.Xr fork 2
+does.
+.Pp
+.Fn pdgetpid
+and
+.Fn pdkill
+return 0 on success and -1 on failure.
+.Pp
+.Fn pdwait4
+returns a PID on success and -1 on failure.
+.Sh ERRORS
+These functions may return the same error numbers as their PID-based equivalents
+(e.g.
+.Fn pdfork
+may return the same error numbers as
+.Xr fork 2 ) ,
+with the following additions:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The signal number given to
+.Fn pdkill
+is invalid.
+.It Bq Er ENOTCAPABLE
+The process descriptor being operated on has insufficient rights (e.g.
+.Dv CAP_PDKILL
+for
+.Fn pdkill ) .
+.El
+.Sh SEE ALSO
+.Xr close 2 ,
+.Xr fork 2 ,
+.Xr fstat 2 ,
+.Xr kill 2 ,
+.Xr poll 2 ,
+.Xr wait4 2
+.Sh HISTORY
+The
+.Fn pdfork ,
+.Fn pdgetpid ,
+.Fn pdkill
+and
+.Fn pdwait4
+system calls first appeared in
+.Fx 9.0 .
+.Pp
+Support for process descriptors mode was developed as part of the
+.Tn TrustedBSD
+Project.
+.Sh AUTHORS
+.An -nosplit
+These functions and the capability facility were created by
+.An "Robert N. M. Watson" Aq rwatson@FreeBSD.org
+and
+.An "Jonathan Anderson" Aq jonathan@FreeBSD.org
+at the University of Cambridge Computer Laboratory with support from a grant
+from Google, Inc.
+.Sh BUGS
+.Fn pdwait4
+has not yet been implemented.
diff --git a/lib/libc/sys/sigwait.2 b/lib/libc/sys/sigwait.2
index 8c00cf4..a9e605c 100644
--- a/lib/libc/sys/sigwait.2
+++ b/lib/libc/sys/sigwait.2
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 11, 2005
+.Dd August 24, 2011
.Dt SIGWAIT 2
.Os
.Sh NAME
@@ -82,6 +82,14 @@ selected, it will be the lowest numbered one.
The selection order between realtime
and non-realtime signals, or between multiple pending non-realtime signals,
is unspecified.
+.Sh IMPLEMENTATION NOTES
+The
+.Fn sigwait
+function is implemented as a wrapper around the
+.Fn __sys_sigwait
+system call, which retries the call on
+.Er EINTR
+error.
.Sh RETURN VALUES
If successful,
.Fn sigwait
diff --git a/lib/libc/sys/sigwaitinfo.2 b/lib/libc/sys/sigwaitinfo.2
index 41be9e2..a83de06 100644
--- a/lib/libc/sys/sigwaitinfo.2
+++ b/lib/libc/sys/sigwaitinfo.2
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 11, 2005
+.Dd August 24, 2011
.Dt SIGTIMEDWAIT 2
.Os
.Sh NAME
@@ -116,6 +116,16 @@ except that the selected signal number shall be stored in the
member, and the cause of the signal shall be stored in the
.Va si_code
member.
+Besides this, the
+.Fn sigwaitinfo
+and
+.Fn sigtimedwait
+system calls may return
+.Er EINTR
+if interrupted by signal, which is not allowed for the
+.Fn sigwait
+function.
+.Pp
If any value is queued to the selected signal, the first such queued
value is dequeued and, if the info argument is
.Pf non- Dv NULL ,
diff --git a/lib/libcam/Makefile b/lib/libcam/Makefile
index c5773ea..9a21dde 100644
--- a/lib/libcam/Makefile
+++ b/lib/libcam/Makefile
@@ -42,4 +42,6 @@ MLINKS+= cam.3 cam_open_device.3 \
SDIR= ${.CURDIR}/../../sys
CFLAGS+= -I${.CURDIR} -I${SDIR}
+SHLIB_MAJOR= 6
+
.include <bsd.lib.mk>
diff --git a/lib/libdwarf/Makefile b/lib/libdwarf/Makefile
index aa182e7..dbd7895 100644
--- a/lib/libdwarf/Makefile
+++ b/lib/libdwarf/Makefile
@@ -22,7 +22,7 @@ INCS= dwarf.h libdwarf.h
CFLAGS+= -I${.CURDIR}
-SHLIB_MAJOR= 2
+SHLIB_MAJOR= 3
WITHOUT_MAN=
diff --git a/lib/libkvm/kvm_ia64.c b/lib/libkvm/kvm_ia64.c
index 04b3c21..74e2b80 100644
--- a/lib/libkvm/kvm_ia64.c
+++ b/lib/libkvm/kvm_ia64.c
@@ -33,6 +33,7 @@
#include <sys/mman.h>
#include <machine/atomic.h>
+#include <machine/bootinfo.h>
#include <machine/pte.h>
#include <kvm.h>
@@ -51,11 +52,16 @@
#define KPTE_DIR0_INDEX(va,ps) ((((va)/(ps)) / NKPTEPG(ps)) / NKPTEDIR(ps))
#define KPTE_DIR1_INDEX(va,ps) ((((va)/(ps)) / NKPTEPG(ps)) % NKPTEDIR(ps))
+#define PBVM_BASE 0x9ffc000000000000UL
+#define PBVM_PGSZ (64 * 1024)
+
struct vmstate {
void *mmapbase;
size_t mmapsize;
size_t pagesize;
u_long kptdir;
+ u_long *pbvm_pgtbl;
+ u_int pbvm_pgtblsz;
};
/*
@@ -110,11 +116,28 @@ _kvm_pa2off(kvm_t *kd, uint64_t pa, off_t *ofs, size_t pgsz)
return (pgsz - ((size_t)pa & (pgsz - 1)));
}
+static ssize_t
+_kvm_read_phys(kvm_t *kd, uint64_t pa, void *buf, size_t bufsz)
+{
+ off_t ofs;
+ size_t sz;
+
+ sz = _kvm_pa2off(kd, pa, &ofs, 0);
+ if (sz < bufsz)
+ return ((ssize_t)sz);
+
+ if (lseek(kd->pmfd, ofs, 0) == -1)
+ return (-1);
+ return (read(kd->pmfd, buf, bufsz));
+}
+
void
_kvm_freevtop(kvm_t *kd)
{
struct vmstate *vm = kd->vmst;
+ if (vm->pbvm_pgtbl != NULL)
+ free(vm->pbvm_pgtbl);
if (vm->mmapbase != NULL)
munmap(vm->mmapbase, vm->mmapsize);
free(vm);
@@ -124,10 +147,12 @@ _kvm_freevtop(kvm_t *kd)
int
_kvm_initvtop(kvm_t *kd)
{
+ struct bootinfo bi;
struct nlist nl[2];
uint64_t va;
Elf64_Ehdr *ehdr;
size_t hdrsz;
+ ssize_t sz;
kd->vmst = (struct vmstate *)_kvm_malloc(kd, sizeof(*kd->vmst));
if (kd->vmst == NULL) {
@@ -146,6 +171,42 @@ _kvm_initvtop(kvm_t *kd)
return (-1);
/*
+ * Load the PBVM page table. We need this to resolve PBVM addresses.
+ * The PBVM page table is obtained from the bootinfo structure, of
+ * which the physical address is given to us in e_entry. If e_entry
+ * is 0, then this is assumed to be a pre-PBVM kernel.
+ */
+ if (ehdr->e_entry != 0) {
+ sz = _kvm_read_phys(kd, ehdr->e_entry, &bi, sizeof(bi));
+ if (sz != sizeof(bi)) {
+ _kvm_err(kd, kd->program,
+ "cannot read bootinfo from PA %#lx", ehdr->e_entry);
+ return (-1);
+ }
+ if (bi.bi_magic != BOOTINFO_MAGIC) {
+ _kvm_err(kd, kd->program, "invalid bootinfo");
+ return (-1);
+ }
+ kd->vmst->pbvm_pgtbl = _kvm_malloc(kd, bi.bi_pbvm_pgtblsz);
+ if (kd->vmst->pbvm_pgtbl == NULL) {
+ _kvm_err(kd, kd->program, "cannot allocate page table");
+ return (-1);
+ }
+ kd->vmst->pbvm_pgtblsz = bi.bi_pbvm_pgtblsz;
+ sz = _kvm_read_phys(kd, bi.bi_pbvm_pgtbl, kd->vmst->pbvm_pgtbl,
+ bi.bi_pbvm_pgtblsz);
+ if (sz != bi.bi_pbvm_pgtblsz) {
+ _kvm_err(kd, kd->program,
+ "cannot read page table from PA %#lx",
+ bi.bi_pbvm_pgtbl);
+ return (-1);
+ }
+ } else {
+ kd->vmst->pbvm_pgtbl = NULL;
+ kd->vmst->pbvm_pgtblsz = 0;
+ }
+
+ /*
* At this point we've got enough information to use kvm_read() for
* direct mapped (ie region 6 and region 7) address, such as symbol
* addresses/values.
@@ -174,17 +235,18 @@ _kvm_initvtop(kvm_t *kd)
}
int
-_kvm_kvatop(kvm_t *kd, u_long va, off_t *pa)
+_kvm_kvatop(kvm_t *kd, u_long va, off_t *ofs)
{
struct ia64_lpte pte;
- uint64_t pgaddr, pt0addr, pt1addr;
+ uint64_t pa, pgaddr, pt0addr, pt1addr;
size_t pgno, pgsz, pt0no, pt1no;
if (va >= REGION_BASE(6)) {
/* Regions 6 and 7: direct mapped. */
- return (_kvm_pa2off(kd, REGION_ADDR(va), pa, 0));
+ pa = REGION_ADDR(va);
+ return (_kvm_pa2off(kd, pa, ofs, 0));
} else if (va >= REGION_BASE(5)) {
- /* Region 5: virtual. */
+ /* Region 5: Kernel Virtual Memory. */
va = REGION_ADDR(va);
pgsz = kd->vmst->pagesize;
pt0no = KPTE_DIR0_INDEX(va, pgsz);
@@ -207,12 +269,24 @@ _kvm_kvatop(kvm_t *kd, u_long va, off_t *pa)
goto fail;
if (!(pte.pte & PTE_PRESENT))
goto fail;
- va = (pte.pte & PTE_PPN_MASK) + (va & (pgsz - 1));
- return (_kvm_pa2off(kd, va, pa, pgsz));
+ pa = (pte.pte & PTE_PPN_MASK) + (va & (pgsz - 1));
+ return (_kvm_pa2off(kd, pa, ofs, pgsz));
+ } else if (va >= PBVM_BASE) {
+ /* Region 4: Pre-Boot Virtual Memory (PBVM). */
+ va -= PBVM_BASE;
+ pgsz = PBVM_PGSZ;
+ pt0no = va / pgsz;
+ if (pt0no >= (kd->vmst->pbvm_pgtblsz >> 3))
+ goto fail;
+ pt0addr = kd->vmst->pbvm_pgtbl[pt0no];
+ if (!(pt0addr & PTE_PRESENT))
+ goto fail;
+ pa = (pt0addr & PTE_PPN_MASK) + va % pgsz;
+ return (_kvm_pa2off(kd, pa, ofs, pgsz));
}
fail:
_kvm_err(kd, kd->program, "invalid kernel virtual address");
- *pa = ~0UL;
+ *ofs = ~0UL;
return (0);
}
diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c
index 338d217..876af50 100644
--- a/lib/libkvm/kvm_proc.c
+++ b/lib/libkvm/kvm_proc.c
@@ -426,10 +426,10 @@ nopgrp:
kp->ki_lastcpu = mtd.td_lastcpu;
kp->ki_wchan = mtd.td_wchan;
if (mtd.td_name[0] != 0)
- strlcpy(kp->ki_ocomm, mtd.td_name, MAXCOMLEN);
+ strlcpy(kp->ki_tdname, mtd.td_name, MAXCOMLEN);
kp->ki_oncpu = mtd.td_oncpu;
if (mtd.td_name[0] != '\0')
- strlcpy(kp->ki_ocomm, mtd.td_name, sizeof(kp->ki_ocomm));
+ strlcpy(kp->ki_tdname, mtd.td_name, sizeof(kp->ki_tdname));
kp->ki_pctcpu = 0;
kp->ki_rqindex = 0;
} else {
diff --git a/lib/libmemstat/libmemstat.3 b/lib/libmemstat/libmemstat.3
index c4817ae..d7a000c 100644
--- a/lib/libmemstat/libmemstat.3
+++ b/lib/libmemstat/libmemstat.3
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 27, 2005
+.Dd July 21, 2011
.Dt LIBMEMSTAT 3
.Os
.Sh NAME
@@ -412,10 +412,6 @@ values of
.Er EACCES
or
.Er EPERM .
-.It Dv MEMSTAT_ERROR_TOOMANYCPUS
-Returned if the compile-time limit on the number of CPUs in
-.Nm
-is lower than the number of CPUs returned by a statistics data source.
.It Dv MEMSTAT_ERROR_DATAERROR
Returned if
.Nm
diff --git a/lib/libmemstat/memstat.c b/lib/libmemstat/memstat.c
index 1a08d3f..c7957c8 100644
--- a/lib/libmemstat/memstat.c
+++ b/lib/libmemstat/memstat.c
@@ -49,8 +49,6 @@ memstat_strerror(int error)
return ("Version mismatch");
case MEMSTAT_ERROR_PERMISSION:
return ("Permission denied");
- case MEMSTAT_ERROR_TOOMANYCPUS:
- return ("Too many CPUs");
case MEMSTAT_ERROR_DATAERROR:
return ("Data format error");
case MEMSTAT_ERROR_KVM:
@@ -99,6 +97,8 @@ _memstat_mtl_empty(struct memory_type_list *list)
struct memory_type *mtp;
while ((mtp = LIST_FIRST(&list->mtl_list))) {
+ free(mtp->mt_percpu_alloc);
+ free(mtp->mt_percpu_cache);
LIST_REMOVE(mtp, mt_list);
free(mtp);
}
@@ -147,7 +147,7 @@ memstat_mtl_find(struct memory_type_list *list, int allocator,
*/
struct memory_type *
_memstat_mt_allocate(struct memory_type_list *list, int allocator,
- const char *name)
+ const char *name, int maxcpus)
{
struct memory_type *mtp;
@@ -158,6 +158,10 @@ _memstat_mt_allocate(struct memory_type_list *list, int allocator,
bzero(mtp, sizeof(*mtp));
mtp->mt_allocator = allocator;
+ mtp->mt_percpu_alloc = malloc(sizeof(struct mt_percpu_alloc_s) *
+ maxcpus);
+ mtp->mt_percpu_cache = malloc(sizeof(struct mt_percpu_cache_s) *
+ maxcpus);
strlcpy(mtp->mt_name, name, MEMTYPE_MAXNAME);
LIST_INSERT_HEAD(&list->mtl_list, mtp, mt_list);
return (mtp);
@@ -171,7 +175,7 @@ _memstat_mt_allocate(struct memory_type_list *list, int allocator,
* libmemstat(3) internal function.
*/
void
-_memstat_mt_reset_stats(struct memory_type *mtp)
+_memstat_mt_reset_stats(struct memory_type *mtp, int maxcpus)
{
int i;
@@ -193,7 +197,7 @@ _memstat_mt_reset_stats(struct memory_type *mtp)
mtp->mt_zonefree = 0;
mtp->mt_kegfree = 0;
- for (i = 0; i < MEMSTAT_MAXCPU; i++) {
+ for (i = 0; i < maxcpus; i++) {
mtp->mt_percpu_alloc[i].mtp_memalloced = 0;
mtp->mt_percpu_alloc[i].mtp_memfreed = 0;
mtp->mt_percpu_alloc[i].mtp_numallocs = 0;
diff --git a/lib/libmemstat/memstat.h b/lib/libmemstat/memstat.h
index e973f1a..cca75b3 100644
--- a/lib/libmemstat/memstat.h
+++ b/lib/libmemstat/memstat.h
@@ -30,12 +30,6 @@
#define _MEMSTAT_H_
/*
- * Number of CPU slots in library-internal data structures. This should be
- * at least the value of MAXCPU from param.h.
- */
-#define MEMSTAT_MAXCPU 32
-
-/*
* Amount of caller data to maintain for each caller data slot. Applications
* must not request more than this number of caller save data, or risk
* corrupting internal libmemstat(3) data structures. A compile time check
@@ -70,7 +64,6 @@
#define MEMSTAT_ERROR_NOMEMORY 1 /* Out of memory. */
#define MEMSTAT_ERROR_VERSION 2 /* Unsupported version. */
#define MEMSTAT_ERROR_PERMISSION 3 /* Permission denied. */
-#define MEMSTAT_ERROR_TOOMANYCPUS 4 /* Too many CPUs. */
#define MEMSTAT_ERROR_DATAERROR 5 /* Error in stat data. */
#define MEMSTAT_ERROR_KVM 6 /* See kvm_geterr() for err. */
#define MEMSTAT_ERROR_KVM_NOSYMBOL 7 /* Symbol not available. */
diff --git a/lib/libmemstat/memstat_internal.h b/lib/libmemstat/memstat_internal.h
index b7fdd71..2416e09 100644
--- a/lib/libmemstat/memstat_internal.h
+++ b/lib/libmemstat/memstat_internal.h
@@ -92,7 +92,7 @@ struct memory_type {
* Per-CPU measurements fall into two categories: per-CPU allocation,
* and per-CPU cache state.
*/
- struct {
+ struct mt_percpu_alloc_s {
uint64_t mtp_memalloced;/* Per-CPU mt_memalloced. */
uint64_t mtp_memfreed; /* Per-CPU mt_memfreed. */
uint64_t mtp_numallocs; /* Per-CPU mt_numallocs. */
@@ -100,11 +100,11 @@ struct memory_type {
uint64_t mtp_sizemask; /* Per-CPU mt_sizemask. */
void *mtp_caller_pointer[MEMSTAT_MAXCALLER];
uint64_t mtp_caller_uint64[MEMSTAT_MAXCALLER];
- } mt_percpu_alloc[MEMSTAT_MAXCPU];
+ } *mt_percpu_alloc;
- struct {
+ struct mt_percpu_cache_s {
uint64_t mtp_free; /* Per-CPU cache free items. */
- } mt_percpu_cache[MEMSTAT_MAXCPU];
+ } *mt_percpu_cache;
LIST_ENTRY(memory_type) mt_list; /* List of types. */
};
@@ -119,7 +119,8 @@ struct memory_type_list {
void _memstat_mtl_empty(struct memory_type_list *list);
struct memory_type *_memstat_mt_allocate(struct memory_type_list *list,
- int allocator, const char *name);
-void _memstat_mt_reset_stats(struct memory_type *mtp);
+ int allocator, const char *name, int maxcpus);
+void _memstat_mt_reset_stats(struct memory_type *mtp,
+ int maxcpus);
#endif /* !_MEMSTAT_INTERNAL_H_ */
diff --git a/lib/libmemstat/memstat_malloc.c b/lib/libmemstat/memstat_malloc.c
index 28a48c6..1fd3621 100644
--- a/lib/libmemstat/memstat_malloc.c
+++ b/lib/libmemstat/memstat_malloc.c
@@ -96,11 +96,6 @@ retry:
return (-1);
}
- if (maxcpus > MEMSTAT_MAXCPU) {
- list->mtl_error = MEMSTAT_ERROR_TOOMANYCPUS;
- return (-1);
- }
-
size = sizeof(count);
if (sysctlbyname("kern.malloc_count", &count, &size, NULL, 0) < 0) {
if (errno == EACCES || errno == EPERM)
@@ -160,12 +155,6 @@ retry:
return (-1);
}
- if (mtshp->mtsh_maxcpus > MEMSTAT_MAXCPU) {
- list->mtl_error = MEMSTAT_ERROR_TOOMANYCPUS;
- free(buffer);
- return (-1);
- }
-
/*
* For the remainder of this function, we are quite trusting about
* the layout of structures and sizes, since we've determined we have
@@ -184,7 +173,7 @@ retry:
mtp = NULL;
if (mtp == NULL)
mtp = _memstat_mt_allocate(list, ALLOCATOR_MALLOC,
- mthp->mth_name);
+ mthp->mth_name, maxcpus);
if (mtp == NULL) {
_memstat_mtl_empty(list);
free(buffer);
@@ -195,7 +184,7 @@ retry:
/*
* Reset the statistics on a current node.
*/
- _memstat_mt_reset_stats(mtp);
+ _memstat_mt_reset_stats(mtp, maxcpus);
for (j = 0; j < maxcpus; j++) {
mtsp = (struct malloc_type_stats *)p;
@@ -295,7 +284,7 @@ memstat_kvm_malloc(struct memory_type_list *list, void *kvm_handle)
void *kmemstatistics;
int hint_dontsearch, j, mp_maxcpus, ret;
char name[MEMTYPE_MAXNAME];
- struct malloc_type_stats mts[MEMSTAT_MAXCPU], *mtsp;
+ struct malloc_type_stats *mts, *mtsp;
struct malloc_type_internal *mtip;
struct malloc_type type, *typep;
kvm_t *kvm;
@@ -322,11 +311,6 @@ memstat_kvm_malloc(struct memory_type_list *list, void *kvm_handle)
return (-1);
}
- if (mp_maxcpus > MEMSTAT_MAXCPU) {
- list->mtl_error = MEMSTAT_ERROR_TOOMANYCPUS;
- return (-1);
- }
-
ret = kread_symbol(kvm, X_KMEMSTATISTICS, &kmemstatistics,
sizeof(kmemstatistics), 0);
if (ret != 0) {
@@ -334,10 +318,17 @@ memstat_kvm_malloc(struct memory_type_list *list, void *kvm_handle)
return (-1);
}
+ mts = malloc(sizeof(struct malloc_type_stats) * mp_maxcpus);
+ if (mts == NULL) {
+ list->mtl_error = MEMSTAT_ERROR_NOMEMORY;
+ return (-1);
+ }
+
for (typep = kmemstatistics; typep != NULL; typep = type.ks_next) {
ret = kread(kvm, typep, &type, sizeof(type), 0);
if (ret != 0) {
_memstat_mtl_empty(list);
+ free(mts);
list->mtl_error = ret;
return (-1);
}
@@ -345,6 +336,7 @@ memstat_kvm_malloc(struct memory_type_list *list, void *kvm_handle)
MEMTYPE_MAXNAME);
if (ret != 0) {
_memstat_mtl_empty(list);
+ free(mts);
list->mtl_error = ret;
return (-1);
}
@@ -358,6 +350,7 @@ memstat_kvm_malloc(struct memory_type_list *list, void *kvm_handle)
sizeof(struct malloc_type_stats), 0);
if (ret != 0) {
_memstat_mtl_empty(list);
+ free(mts);
list->mtl_error = ret;
return (-1);
}
@@ -368,9 +361,10 @@ memstat_kvm_malloc(struct memory_type_list *list, void *kvm_handle)
mtp = NULL;
if (mtp == NULL)
mtp = _memstat_mt_allocate(list, ALLOCATOR_MALLOC,
- name);
+ name, mp_maxcpus);
if (mtp == NULL) {
_memstat_mtl_empty(list);
+ free(mts);
list->mtl_error = MEMSTAT_ERROR_NOMEMORY;
return (-1);
}
@@ -379,7 +373,7 @@ memstat_kvm_malloc(struct memory_type_list *list, void *kvm_handle)
* This logic is replicated from kern_malloc.c, and should
* be kept in sync.
*/
- _memstat_mt_reset_stats(mtp);
+ _memstat_mt_reset_stats(mtp, mp_maxcpus);
for (j = 0; j < mp_maxcpus; j++) {
mtsp = &mts[j];
mtp->mt_memalloced += mtsp->mts_memalloced;
diff --git a/lib/libmemstat/memstat_uma.c b/lib/libmemstat/memstat_uma.c
index 485a4f2..35f6dad 100644
--- a/lib/libmemstat/memstat_uma.c
+++ b/lib/libmemstat/memstat_uma.c
@@ -30,7 +30,6 @@
#include <sys/cpuset.h>
#include <sys/sysctl.h>
-#define LIBMEMSTAT /* Cause vm_page.h not to include opt_vmpage.h */
#include <vm/vm.h>
#include <vm/vm_page.h>
@@ -79,7 +78,7 @@ memstat_sysctl_uma(struct memory_type_list *list, int flags)
struct uma_type_header *uthp;
struct uma_percpu_stat *upsp;
struct memory_type *mtp;
- int count, hint_dontsearch, i, j, maxcpus;
+ int count, hint_dontsearch, i, j, maxcpus, maxid;
char *buffer, *p;
size_t size;
@@ -93,24 +92,19 @@ memstat_sysctl_uma(struct memory_type_list *list, int flags)
* from the header.
*/
retry:
- size = sizeof(maxcpus);
- if (sysctlbyname("kern.smp.maxcpus", &maxcpus, &size, NULL, 0) < 0) {
+ size = sizeof(maxid);
+ if (sysctlbyname("kern.smp.maxid", &maxid, &size, NULL, 0) < 0) {
if (errno == EACCES || errno == EPERM)
list->mtl_error = MEMSTAT_ERROR_PERMISSION;
else
list->mtl_error = MEMSTAT_ERROR_DATAERROR;
return (-1);
}
- if (size != sizeof(maxcpus)) {
+ if (size != sizeof(maxid)) {
list->mtl_error = MEMSTAT_ERROR_DATAERROR;
return (-1);
}
- if (maxcpus > MEMSTAT_MAXCPU) {
- list->mtl_error = MEMSTAT_ERROR_TOOMANYCPUS;
- return (-1);
- }
-
size = sizeof(count);
if (sysctlbyname("vm.zone_count", &count, &size, NULL, 0) < 0) {
if (errno == EACCES || errno == EPERM)
@@ -125,7 +119,7 @@ retry:
}
size = sizeof(*uthp) + count * (sizeof(*uthp) + sizeof(*upsp) *
- maxcpus);
+ (maxid + 1));
buffer = malloc(size);
if (buffer == NULL) {
@@ -170,12 +164,6 @@ retry:
return (-1);
}
- if (ushp->ush_maxcpus > MEMSTAT_MAXCPU) {
- list->mtl_error = MEMSTAT_ERROR_TOOMANYCPUS;
- free(buffer);
- return (-1);
- }
-
/*
* For the remainder of this function, we are quite trusting about
* the layout of structures and sizes, since we've determined we have
@@ -194,7 +182,7 @@ retry:
mtp = NULL;
if (mtp == NULL)
mtp = _memstat_mt_allocate(list, ALLOCATOR_UMA,
- uthp->uth_name);
+ uthp->uth_name, maxid + 1);
if (mtp == NULL) {
_memstat_mtl_empty(list);
free(buffer);
@@ -205,7 +193,7 @@ retry:
/*
* Reset the statistics on a current node.
*/
- _memstat_mt_reset_stats(mtp);
+ _memstat_mt_reset_stats(mtp, maxid + 1);
mtp->mt_numallocs = uthp->uth_allocs;
mtp->mt_numfrees = uthp->uth_frees;
@@ -398,7 +386,7 @@ memstat_kvm_uma(struct memory_type_list *list, void *kvm_handle)
mtp = NULL;
if (mtp == NULL)
mtp = _memstat_mt_allocate(list, ALLOCATOR_UMA,
- name);
+ name, mp_maxid + 1);
if (mtp == NULL) {
free(ucp_array);
_memstat_mtl_empty(list);
@@ -408,7 +396,7 @@ memstat_kvm_uma(struct memory_type_list *list, void *kvm_handle)
/*
* Reset the statistics on a current node.
*/
- _memstat_mt_reset_stats(mtp);
+ _memstat_mt_reset_stats(mtp, mp_maxid + 1);
mtp->mt_numallocs = uz.uz_allocs;
mtp->mt_numfrees = uz.uz_frees;
mtp->mt_failures = uz.uz_fails;
diff --git a/lib/libopie/Makefile b/lib/libopie/Makefile
index 360dddc..647bfee 100644
--- a/lib/libopie/Makefile
+++ b/lib/libopie/Makefile
@@ -4,7 +4,7 @@
#
OPIE_DIST?= ${.CURDIR}/../../contrib/opie
DIST_DIR= ${OPIE_DIST}/${.CURDIR:T}
-SHLIB_MAJOR= 6
+SHLIB_MAJOR= 7
KEYFILE?= \"/etc/opiekeys\"
diff --git a/lib/libpcap/Makefile b/lib/libpcap/Makefile
index 80c61d80..5b613e7 100644
--- a/lib/libpcap/Makefile
+++ b/lib/libpcap/Makefile
@@ -99,7 +99,7 @@ CFLAGS+=-DHAVE_NET_PFVAR_H
WARNS?= 0
-SHLIB_MAJOR=7
+SHLIB_MAJOR= 8
#
# Magic to grab sources out of src/contrib
diff --git a/lib/libproc/proc_create.c b/lib/libproc/proc_create.c
index c372a47..9bd24a2 100644
--- a/lib/libproc/proc_create.c
+++ b/lib/libproc/proc_create.c
@@ -79,12 +79,11 @@ proc_attach(pid_t pid, int flags, struct proc_handle **pphdl)
else
phdl->status = PS_STOP;
+out:
if (error)
proc_free(phdl);
else
*pphdl = phdl;
-out:
- proc_free(phdl);
return (error);
}
diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c
index 22ca668..facce11 100644
--- a/lib/libprocstat/libprocstat.c
+++ b/lib/libprocstat/libprocstat.c
@@ -282,7 +282,7 @@ procstat_freefiles(struct procstat *procstat, struct filestat_list *head)
static struct filestat *
filestat_new_entry(void *typedep, int type, int fd, int fflags, int uflags,
- int refcount, off_t offset, char *path)
+ int refcount, off_t offset, char *path, cap_rights_t cap_rights)
{
struct filestat *entry;
@@ -299,6 +299,7 @@ filestat_new_entry(void *typedep, int type, int fd, int fflags, int uflags,
entry->fs_ref_count = refcount;
entry->fs_offset = offset;
entry->fs_path = path;
+ entry->fs_cap_rights = cap_rights;
return (entry);
}
@@ -381,21 +382,21 @@ procstat_getfiles_kvm(struct procstat *procstat, struct kinfo_proc *kp, int mmap
/* root directory vnode, if one. */
if (filed.fd_rdir) {
entry = filestat_new_entry(filed.fd_rdir, PS_FST_TYPE_VNODE, -1,
- PS_FST_FFLAG_READ, PS_FST_UFLAG_RDIR, 0, 0, NULL);
+ PS_FST_FFLAG_READ, PS_FST_UFLAG_RDIR, 0, 0, NULL, 0);
if (entry != NULL)
STAILQ_INSERT_TAIL(head, entry, next);
}
/* current working directory vnode. */
if (filed.fd_cdir) {
entry = filestat_new_entry(filed.fd_cdir, PS_FST_TYPE_VNODE, -1,
- PS_FST_FFLAG_READ, PS_FST_UFLAG_CDIR, 0, 0, NULL);
+ PS_FST_FFLAG_READ, PS_FST_UFLAG_CDIR, 0, 0, NULL, 0);
if (entry != NULL)
STAILQ_INSERT_TAIL(head, entry, next);
}
/* jail root, if any. */
if (filed.fd_jdir) {
entry = filestat_new_entry(filed.fd_jdir, PS_FST_TYPE_VNODE, -1,
- PS_FST_FFLAG_READ, PS_FST_UFLAG_JAIL, 0, 0, NULL);
+ PS_FST_FFLAG_READ, PS_FST_UFLAG_JAIL, 0, 0, NULL, 0);
if (entry != NULL)
STAILQ_INSERT_TAIL(head, entry, next);
}
@@ -403,14 +404,14 @@ procstat_getfiles_kvm(struct procstat *procstat, struct kinfo_proc *kp, int mmap
if (kp->ki_tracep) {
entry = filestat_new_entry(kp->ki_tracep, PS_FST_TYPE_VNODE, -1,
PS_FST_FFLAG_READ | PS_FST_FFLAG_WRITE,
- PS_FST_UFLAG_TRACE, 0, 0, NULL);
+ PS_FST_UFLAG_TRACE, 0, 0, NULL, 0);
if (entry != NULL)
STAILQ_INSERT_TAIL(head, entry, next);
}
/* text vnode, if one */
if (kp->ki_textvp) {
entry = filestat_new_entry(kp->ki_textvp, PS_FST_TYPE_VNODE, -1,
- PS_FST_FFLAG_READ, PS_FST_UFLAG_TEXT, 0, 0, NULL);
+ PS_FST_FFLAG_READ, PS_FST_UFLAG_TEXT, 0, 0, NULL, 0);
if (entry != NULL)
STAILQ_INSERT_TAIL(head, entry, next);
}
@@ -418,7 +419,7 @@ procstat_getfiles_kvm(struct procstat *procstat, struct kinfo_proc *kp, int mmap
if ((vp = getctty(kd, kp)) != NULL) {
entry = filestat_new_entry(vp, PS_FST_TYPE_VNODE, -1,
PS_FST_FFLAG_READ | PS_FST_FFLAG_WRITE,
- PS_FST_UFLAG_CTTY, 0, 0, NULL);
+ PS_FST_UFLAG_CTTY, 0, 0, NULL, 0);
if (entry != NULL)
STAILQ_INSERT_TAIL(head, entry, next);
}
@@ -471,8 +472,9 @@ procstat_getfiles_kvm(struct procstat *procstat, struct kinfo_proc *kp, int mmap
default:
continue;
}
+ /* XXXRW: No capability rights support for kvm yet. */
entry = filestat_new_entry(data, type, i,
- to_filestat_flags(file.f_flag), 0, 0, 0, NULL);
+ to_filestat_flags(file.f_flag), 0, 0, 0, NULL, 0);
if (entry != NULL)
STAILQ_INSERT_TAIL(head, entry, next);
}
@@ -531,7 +533,7 @@ do_mmapped:
*/
entry = filestat_new_entry(object.handle,
PS_FST_TYPE_VNODE, -1, fflags,
- PS_FST_UFLAG_MMAP, 0, 0, NULL);
+ PS_FST_UFLAG_MMAP, 0, 0, NULL, 0);
if (entry != NULL)
STAILQ_INSERT_TAIL(head, entry, next);
}
@@ -586,6 +588,7 @@ kinfo_fflags2fst(int kfflags)
} kfflags2fst[] = {
{ KF_FLAG_APPEND, PS_FST_FFLAG_APPEND },
{ KF_FLAG_ASYNC, PS_FST_FFLAG_ASYNC },
+ { KF_FLAG_CAPABILITY, PS_FST_FFLAG_CAPABILITY },
{ KF_FLAG_CREAT, PS_FST_FFLAG_CREAT },
{ KF_FLAG_DIRECT, PS_FST_FFLAG_DIRECT },
{ KF_FLAG_EXCL, PS_FST_FFLAG_EXCL },
@@ -644,6 +647,7 @@ procstat_getfiles_sysctl(struct procstat *procstat, struct kinfo_proc *kp, int m
int cnt, fd, fflags;
int i, type, uflags;
int refcount;
+ cap_rights_t cap_rights;
assert(kp);
if (kp->ki_fd == NULL)
@@ -676,12 +680,13 @@ procstat_getfiles_sysctl(struct procstat *procstat, struct kinfo_proc *kp, int m
path = strdup(kif->kf_path);
else
path = NULL;
+ cap_rights = kif->kf_cap_rights;
/*
* Create filestat entry.
*/
entry = filestat_new_entry(kif, type, fd, fflags, uflags,
- refcount, offset, path);
+ refcount, offset, path, cap_rights);
if (entry != NULL)
STAILQ_INSERT_TAIL(head, entry, next);
}
@@ -707,7 +712,8 @@ procstat_getfiles_sysctl(struct procstat *procstat, struct kinfo_proc *kp, int m
else
path = NULL;
entry = filestat_new_entry(kve, PS_FST_TYPE_VNODE, -1,
- fflags, PS_FST_UFLAG_MMAP, refcount, offset, path);
+ fflags, PS_FST_UFLAG_MMAP, refcount, offset, path,
+ 0);
if (entry != NULL)
STAILQ_INSERT_TAIL(head, entry, next);
}
diff --git a/lib/libprocstat/libprocstat.h b/lib/libprocstat/libprocstat.h
index 62b1bd5..f1ca109 100644
--- a/lib/libprocstat/libprocstat.h
+++ b/lib/libprocstat/libprocstat.h
@@ -88,6 +88,7 @@
#define PS_FST_FFLAG_DIRECT 0x1000
#define PS_FST_FFLAG_EXEC 0x2000
#define PS_FST_FFLAG_HASLOCK 0x4000
+#define PS_FST_FFLAG_CAPABILITY 0x8000
struct procstat;
struct filestat {
@@ -101,6 +102,7 @@ struct filestat {
void *fs_typedep; /* Type dependent data. */
char *fs_path;
STAILQ_ENTRY(filestat) next;
+ cap_rights_t fs_cap_rights; /* Capability rights, if flag set. */
};
struct vnstat {
uint64_t vn_fileid;
diff --git a/lib/librtld_db/Makefile b/lib/librtld_db/Makefile
index efaed62..2815a07 100644
--- a/lib/librtld_db/Makefile
+++ b/lib/librtld_db/Makefile
@@ -3,7 +3,7 @@
.include <bsd.own.mk>
LIB= rtld_db
-SHLIB_MAJOR= 1
+SHLIB_MAJOR= 2
MAN= librtld_db.3
SRCS= rtld_db.c
diff --git a/lib/libtacplus/Makefile b/lib/libtacplus/Makefile
index 617f877..798c949 100644
--- a/lib/libtacplus/Makefile
+++ b/lib/libtacplus/Makefile
@@ -30,7 +30,7 @@ INCS= taclib.h
CFLAGS+= -Wall
DPADD= ${LIBMD}
LDADD= -lmd
-SHLIB_MAJOR= 4
+SHLIB_MAJOR= 5
MAN= libtacplus.3 tacplus.conf.5
WARNS?= 2
diff --git a/lib/libthread_db/arch/amd64/libpthread_md.c b/lib/libthread_db/arch/amd64/libpthread_md.c
index 646d36d..624e650 100644
--- a/lib/libthread_db/arch/amd64/libpthread_md.c
+++ b/lib/libthread_db/arch/amd64/libpthread_md.c
@@ -92,18 +92,21 @@ pt_ucontext_to_reg(const ucontext_t *uc, struct reg *r)
void
pt_fpreg_to_ucontext(const struct fpreg* r, ucontext_t *uc)
{
- memcpy(&uc->uc_mcontext.mc_fpstate, r, sizeof(r));
+
+ memcpy(&uc->uc_mcontext.mc_fpstate, r, sizeof(*r));
}
void
pt_ucontext_to_fpreg(const ucontext_t *uc, struct fpreg *r)
{
- memcpy(r, &uc->uc_mcontext.mc_fpstate, sizeof(r));
+
+ memcpy(r, &uc->uc_mcontext.mc_fpstate, sizeof(*r));
}
void
pt_md_init(void)
{
+
/* Nothing to do */
}
diff --git a/lib/libthread_db/arch/sparc64/libpthread_md.c b/lib/libthread_db/arch/sparc64/libpthread_md.c
index f5f12d3..6a84518 100644
--- a/lib/libthread_db/arch/sparc64/libpthread_md.c
+++ b/lib/libthread_db/arch/sparc64/libpthread_md.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2004 Marcel Moolenaar
+ * Copyright (c) 2011 Marius Strobl <marius@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,39 +28,63 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/procfs.h>
+#include <sys/types.h>
+#include <string.h>
#include <thread_db.h>
#include <ucontext.h>
+#include <machine/fsr.h>
#include "libpthread_db.h"
void
-pt_reg_to_ucontext(const struct reg *r __unused, ucontext_t *uc __unused)
+pt_reg_to_ucontext(const struct reg *r, ucontext_t *uc)
{
+
+ memcpy(&uc->uc_mcontext, r, MIN(sizeof(uc->uc_mcontext), sizeof(*r)));
}
void
-pt_ucontext_to_reg(const ucontext_t *uc __unused, struct reg *r __unused)
+pt_ucontext_to_reg(const ucontext_t *uc, struct reg *r)
{
+
+ memcpy(r, &uc->uc_mcontext, MIN(sizeof(uc->uc_mcontext), sizeof(*r)));
}
void
-pt_fpreg_to_ucontext(const struct fpreg* r __unused, ucontext_t *uc __unused)
+pt_fpreg_to_ucontext(const struct fpreg* r, ucontext_t *uc)
{
+ mcontext_t *mc = &uc->uc_mcontext;
+
+ memcpy(mc->mc_fp, r->fr_regs, MIN(sizeof(mc->mc_fp),
+ sizeof(r->fr_regs)));
+ mc->mc_fsr = r->fr_fsr;
+ mc->mc_gsr = r->fr_gsr;
+ mc->mc_fprs |= FPRS_FEF;
}
void
-pt_ucontext_to_fpreg(const ucontext_t *uc __unused, struct fpreg *r __unused)
+pt_ucontext_to_fpreg(const ucontext_t *uc, struct fpreg *r)
{
+ const mcontext_t *mc = &uc->uc_mcontext;
+
+ if ((mc->mc_fprs & FPRS_FEF) != 0) {
+ memcpy(r->fr_regs, mc->mc_fp, MIN(sizeof(mc->mc_fp),
+ sizeof(r->fr_regs)));
+ r->fr_fsr = mc->mc_fsr;
+ r->fr_gsr = mc->mc_gsr;
+ } else
+ memset(r, 0, sizeof(*r));
}
void
pt_md_init(void)
{
+
}
int
pt_reg_sstep(struct reg *reg __unused, int step __unused)
{
+
return (0);
}
diff --git a/lib/libthread_db/libthr_db.c b/lib/libthread_db/libthr_db.c
index 33225f4..b24385f 100644
--- a/lib/libthread_db/libthr_db.c
+++ b/lib/libthread_db/libthr_db.c
@@ -202,7 +202,7 @@ static td_err_e
pt_ta_map_id2thr(const td_thragent_t *ta, thread_t id, td_thrhandle_t *th)
{
psaddr_t pt;
- int32_t lwp;
+ int64_t lwp;
int ret;
TDBG_FUNC();
@@ -214,7 +214,7 @@ pt_ta_map_id2thr(const td_thragent_t *ta, thread_t id, td_thrhandle_t *th)
return (TD_ERR);
/* Iterate through thread list to find pthread */
while (pt != 0) {
- ret = thr_pread_int(ta, pt + ta->thread_off_tid, &lwp);
+ ret = thr_pread_long(ta, pt + ta->thread_off_tid, &lwp);
if (ret != 0)
return (TD_ERR);
if (lwp == id)
@@ -245,7 +245,7 @@ pt_ta_thr_iter(const td_thragent_t *ta, td_thr_iter_f *callback,
{
td_thrhandle_t th;
psaddr_t pt;
- int32_t lwp;
+ int64_t lwp;
int ret;
TDBG_FUNC();
@@ -254,7 +254,7 @@ pt_ta_thr_iter(const td_thragent_t *ta, td_thr_iter_f *callback,
if (ret != 0)
return (TD_ERR);
while (pt != 0) {
- ret = thr_pread_int(ta, pt + ta->thread_off_tid, &lwp);
+ ret = thr_pread_long(ta, pt + ta->thread_off_tid, &lwp);
if (ret != 0)
return (TD_ERR);
if (lwp != 0 && lwp != TERMINATED) {
@@ -368,7 +368,7 @@ pt_ta_event_getmsg(const td_thragent_t *ta, td_event_msg_t *msg)
psaddr_t pt;
td_thr_events_e tmp;
- int32_t lwp;
+ int64_t lwp;
int ret;
TDBG_FUNC();
@@ -395,7 +395,7 @@ pt_ta_event_getmsg(const td_thragent_t *ta, td_event_msg_t *msg)
ps_pwrite(ta->ph, pt + ta->thread_off_event_buf, &tmp, sizeof(tmp));
/* Convert event */
pt = msg->th_p;
- ret = thr_pread_int(ta, pt + ta->thread_off_tid, &lwp);
+ ret = thr_pread_long(ta, pt + ta->thread_off_tid, &lwp);
if (ret != 0)
return (TD_ERR);
handle.th_ta = ta;
@@ -672,7 +672,7 @@ pt_thr_event_getmsg(const td_thrhandle_t *th, td_event_msg_t *msg)
static td_thrhandle_t handle;
const td_thragent_t *ta = th->th_ta;
psaddr_t pt, pt_temp;
- int32_t lwp;
+ int64_t lwp;
int ret;
td_thr_events_e tmp;
@@ -699,7 +699,7 @@ pt_thr_event_getmsg(const td_thrhandle_t *th, td_event_msg_t *msg)
ps_pwrite(ta->ph, pt + ta->thread_off_event_buf, &tmp, sizeof(tmp));
/* Convert event */
pt = msg->th_p;
- ret = thr_pread_int(ta, pt + ta->thread_off_tid, &lwp);
+ ret = thr_pread_long(ta, pt + ta->thread_off_tid, &lwp);
if (ret != 0)
return (TD_ERR);
handle.th_ta = ta;
diff --git a/lib/libufs/Makefile b/lib/libufs/Makefile
index 1dfc242..78832d8 100644
--- a/lib/libufs/Makefile
+++ b/lib/libufs/Makefile
@@ -2,6 +2,7 @@
LIB= ufs
SHLIBDIR?= /lib
+SHLIB_MAJOR= 6
SRCS= block.c cgroup.c inode.c sblock.c type.c ffs_subr.c ffs_tables.c
INCS= libufs.h
diff --git a/lib/libusb/Makefile b/lib/libusb/Makefile
index f438cff..c4396cc 100644
--- a/lib/libusb/Makefile
+++ b/lib/libusb/Makefile
@@ -45,6 +45,7 @@ MLINKS += libusb.3 libusb_get_device_list.3
MLINKS += libusb.3 libusb_free_device_list.3
MLINKS += libusb.3 libusb_get_bus_number.3
MLINKS += libusb.3 libusb_get_device_address.3
+MLINKS += libusb.3 libusb_get_device_speed.3
MLINKS += libusb.3 libusb_get_max_packet_size.3
MLINKS += libusb.3 libusb_ref_device.3
MLINKS += libusb.3 libusb_unref_device.3
diff --git a/lib/libusb/libusb.3 b/lib/libusb/libusb.3
index 33d807d..1f52b9e 100644
--- a/lib/libusb/libusb.3
+++ b/lib/libusb/libusb.3
@@ -26,247 +26,211 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 18, 2010
+.Dd August 16, 2011
.Dt LIBUSB 3
.Os
.Sh NAME
.Nm libusb
-.
.Nd "USB access library"
-.
-.
.Sh LIBRARY
-.
-.
-USB access library (libusb -lusb)
-.
-.
+USB access library
+.Pq libusb, -lusb
.Sh SYNOPSIS
-.
-.
.In libusb.h
-.
-.
.Sh DESCRIPTION
The
.Nm
library contains interfaces for directly managing a usb device.
The current implementation supports v1.0 of the libusb API.
-.
-.
.Sh LIBRARY INITIALISATION / DEINITIALISATION
-.
.Pp
-.
.Ft int
.Fn libusb_init libusb_context **ctx
-This function initialises libusb. Must be called at the beginning
-of the program. This function returns 0 on success or LIBUSB_ERROR on
+This function initialises libusb.
+It must be called at the beginning
+of the program, before other libusb routines are used.
+This function returns 0 on success or LIBUSB_ERROR on
failure.
-.
.Pp
-.
.Ft void
.Fn libusb_exit "libusb_context *ctx"
-Deinitialise libusb. Must be called at the end of the application.
-.
+Deinitialise libusb.
+Must be called at the end of the application.
+Other libusb routines may not be called after this function.
.Pp
-.
.Ft const char *
.Fn libusb_strerror "int code"
-Get ASCII representation of the error given by the
+Get the ASCII representation of the error given by the
.Fa code
argument.
-.
-.
.Pp
-.
.Ft void
.Fn libusb_set_debug "libusb_context *ctx" "int level"
-Set debug to the
-.Fa level
-level.
-.
+Set the debug level to
+.Fa level .
.Pp
-.
.Ft ssize_t
.Fn libusb_get_device_list "libusb_context *ctx" "libusb_device ***list"
-Fill into
-.Fa list
-the list of usb device available. All the device created by this
-function must be unref and free when you are done with them. This
-function returns the number of devices in list or a LIBUSB_ERROR code.
-.
-.Pp
-.
+Populate
+.Fa list
+with the list of usb devices available, adding a reference to each
+device in the list.
+All the list entries created by this
+function must have their reference counter
+decremented when you are done with them,
+and the list itself must be freed.
+This
+function returns the number of devices in the list or a LIBUSB_ERROR code.
+.Pp
.Ft void
.Fn libusb_free_device_list "libusb_device **list" "int unref_devices"
-Free the list of devices discovered by libusb_get_device_list. If
+Free the list of devices discovered by libusb_get_device_list.
+If
.Fa unref_device
-is set to 1 all devices are unref one time.
-.
+is set to 1 all devices in the list have their reference
+counter decremented once.
.Pp
-.
.Ft uint8_t
.Fn libusb_get_bus_number "libusb_device *dev"
Returns the number of the bus contained by the device
.Fa dev.
-.
.Pp
-.
.Ft uint8_t
.Fn libusb_get_device_address "libusb_device *dev"
-Return the device_address contained by the device
+Returns the device_address contained by the device
.Fa dev.
-.
.Pp
-.
+.Ft enum libusb_speed
+.Fn libusb_get_device_speed "libusb_device *dev"
+Returns the wire speed at which the device is connected.
+See the LIBUSB_SPEED_XXX enums for more information.
+LIBUSB_SPEED_UNKNOWN is returned in case of unknown wire speed.
+.Pp
.Ft int
.Fn libusb_get_max_packet_size "libusb_device *dev" "unsigned char endpoint"
-Return the wMaxPacketSize value on success, LIBUSB_ERROR_NOT_FOUND if the
+Returns the wMaxPacketSize value on success, LIBUSB_ERROR_NOT_FOUND if the
endpoint does not exist and LIBUSB_ERROR_OTHERS on other failure.
-.
.Pp
-.
.Ft libusb_device *
.Fn libusb_ref_device "libusb_device *dev"
Increment the reference counter of the device
.Fa dev.
-.
.Pp
-.
.Ft void
.Fn libusb_unref_device "libusb_device *dev"
Decrement the reference counter of the device
.Fa dev.
-.
.Pp
-.
.Ft int
.Fn libusb_open "libusb_device *dev" "libusb_device_handle **devh"
-Open a device and obtain a device_handle. Return 0 on success,
-LIBUSB_ERROR_NO_MEM on memory allocation problem, LIBUSB_ERROR_ACCESS
-on permission problem, LIBUSB_ERROR_NO_DEVICE if the device has been
-disconnected and a LIBUSB_ERROR code on error.
-.
+Open a device and obtain a device_handle.
+Returns 0 on success,
+LIBUSB_ERROR_NO_MEM on memory allocation problems, LIBUSB_ERROR_ACCESS
+on permissions problems, LIBUSB_ERROR_NO_DEVICE if the device has been
+disconnected and a LIBUSB_ERROR code on other errors.
.Pp
-.
.Ft libusb_device_handle *
.Fn libusb_open_device_with_vid_pid "libusb_context *ctx" "uint16_t vid" "uint16_t pid"
-Convenience function to open a device with is
-.Fa vid
-and
+A convenience function to open a device by vendor and product IDs
+.Fa vid
+and
.Fa pid.
-Return NULL on error.
-.
+Returns NULL on error.
.Pp
-.
.Ft void
.Fn libusb_close "libusb_device_handle *devh"
Close a device handle.
-.
.Pp
-.
.Ft libusb_device *
-.Fn libusb_get_device(libusb_device_handle *devh)
-Get the device contained by devh. Return NULL on error.
-.
+.Fn libusb_get_device "libusb_device_handle *devh"
+Get the device contained by devh.
+Returns NULL on error.
.Pp
-.
.Ft int
.Fn libusb_get_configuration "libusb_device_handle *devh" "int *config"
-Return the bConfiguration value of the current configuration. return 0
-on success, LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
+Returns the bConfiguration value of the current configuration.
+Returns 0
+on success, LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
and a LIBUSB_ERROR code on error.
-.
.Pp
-.
.Ft int
.Fn libusb_set_configuration "libusb_device_handle *devh" "int config"
-Set the active configuration
+Set the active configuration to
.Fa config
for the device contained by
.Fa devh.
-This function return 0 on success, LIBUSB_ERROR_NOT_FOUND if the requested
-configuration does not exist, LIBUSB_ERROR_BUSY if the interfaces are currently
-claimed, LIBUSB_ERROR_NO_DEVICE if the device has been disconnected and a
+This function returns 0 on success, LIBUSB_ERROR_NOT_FOUND if the requested
+configuration does not exist, LIBUSB_ERROR_BUSY if the interfaces are currently
+claimed, LIBUSB_ERROR_NO_DEVICE if the device has been disconnected and a
LIBUSB_ERROR code on failure.
-.
.Pp
-.
.Ft int
.Fn libusb_claim_interface "libusb_device_handle *devh" "int interface_number"
Claim an interface in a given libusb_handle
.Fa devh.
-This is a non-blocking function. It return 0 success, LIBUSB_ERROR_NOT_FOUND
-if the requested interface does not exist, LIBUSB_ERROR_BUSY if a program or
-driver has claimed the interface, LIBUSB_ERROR_NO_DEVICE if the device has
+This is a non-blocking function.
+It returns 0 on success, LIBUSB_ERROR_NOT_FOUND
+if the requested interface does not exist, LIBUSB_ERROR_BUSY if a program or
+driver has claimed the interface, LIBUSB_ERROR_NO_DEVICE if the device has
been disconnected and a LIBUSB_ERROR code on failure.
-.
.Pp
-.
.Ft int
.Fn libusb_release_interface "libusb_device_handle *devh" "int interface_number"
-This function release an interface. All the claimed interface must be released
-before closing a device. Returns 0 on success, LIBUSB_ERROR_NOT_FOUND if the
-interface was not claimed, LIBUSB_ERROR_NO_DEVICE if the device has been
+This function releases an interface.
+All the claimed interfaces on a device must be released
+before closing the device.
+Returns 0 on success, LIBUSB_ERROR_NOT_FOUND if the
+interface was not claimed, LIBUSB_ERROR_NO_DEVICE if the device has been
disconnected and LIBUSB_ERROR on failure.
-.
.Pp
-.
.Ft int
.Fn libusb_set_interface_alt_setting "libusb_device_handle *dev" "int interface_number" "int alternate_setting"
-Activate an alternate setting for an interface. Returns 0 on success,
-LIBUSB_ERROR_NOT_FOUND if the interface was not claimed or the requested
-setting does not exist, LIBUSB_ERROR_NO_DEVICE if the device has been
-disconnected and LIBUSB_ERROR code on failure.
-.
+Activate an alternate setting for an interface.
+Returns 0 on success,
+LIBUSB_ERROR_NOT_FOUND if the interface was not claimed or the requested
+setting does not exist, LIBUSB_ERROR_NO_DEVICE if the device has been
+disconnected and a LIBUSB_ERROR code on failure.
.Pp
-.
.Ft int
.Fn libusb_clear_halt "libusb_device_handle *devh" "unsigned char endpoint"
-Clear an halt/stall for a endpoint. Returns 0 on success, LIBUSB_ERROR_NOT_FOUND
-if the endpoint does not exist, LIBUSB_ERROR_NO_DEVICE if the device has been
+Clear an halt/stall for a endpoint.
+Returns 0 on success, LIBUSB_ERROR_NOT_FOUND
+if the endpoint does not exist, LIBUSB_ERROR_NO_DEVICE if the device has been
disconnected and a LIBUSB_ERROR code on failure.
-.
.Pp
-.
.Ft int
.Fn libusb_reset_device "libusb_device_handle *devh"
-Perform an USB port reset for an usb device. Returns 0 on success,
+Perform an USB port reset for an usb device.
+Returns 0 on success,
LIBUSB_ERROR_NOT_FOUND if re-enumeration is required or if the device has
been disconnected and a LIBUSB_ERROR code on failure.
-.
.Pp
-.
.Ft int
.Fn libusb_check_connected "libusb_device_handle *devh"
-Test if USB device is still connected. Returns 0 on success,
-LIBUSB_ERROR_NO_DEVICE if has been disconnected and a LIBUSB_ERROR
+Test if the USB device is still connected.
+Returns 0 on success,
+LIBUSB_ERROR_NO_DEVICE if it has been disconnected and a LIBUSB_ERROR
code on failure.
-.
.Pp
-.
.Ft int
.Fn libusb_kernel_driver_active "libusb_device_handle *devh" "int interface"
-Determine if a driver is active on a interface. Returns 0 if no kernel driver
-is active, returns 1 if a kernel driver is active, returns LIBUSB_ERROR_NO_DEVICE
-if the device has been disconnected and return a LIBUSB_ERROR code on failure.
-.
+Determine if a driver is active on a interface.
+Returns 0 if no kernel driver
+is active, 1 if a kernel driver is active, LIBUSB_ERROR_NO_DEVICE
+if the device has been disconnected and a LIBUSB_ERROR code on failure.
.Pp
-.
.Ft int
.Fn libusb_get_driver "libusb_device_handle *devh" "int interface" "char *name" "int namelen"
or
.Ft int
.Fn libusb_get_driver_np "libusb_device_handle *devh" "int interface" "char *name" "int namelen"
-Gets the name of the driver attached to the given
+Copy the name of the driver attached to the given
.Fa device
and
.Fa interface
-into the buffer given by
+into the buffer
.Fa name
-and
+of length
.Fa namelen .
Returns 0 on success, LIBUSB_ERROR_NOT_FOUND if no kernel driver is attached
to the given interface and LIBUSB_ERROR_INVALID_PARAM if the interface does
@@ -275,239 +239,230 @@ This function is non-portable.
The buffer pointed to by
.Fa name
is only zero terminated on success.
-.
.Pp
-.
.Ft int
.Fn libusb_detach_kernel_driver "libusb_device_handle *devh" "int interface"
or
.Ft int
.Fn libusb_detach_kernel_driver_np "libusb_device_handle *devh" "int interface"
Detach a kernel driver from an interface.
-This is needed to claim an interface required by a kernel driver.
+This is needed to claim an interface already claimed by a kernel driver.
Returns 0 on success, LIBUSB_ERROR_NOT_FOUND if no kernel driver was active,
-LIBUSB_ERROR_INVALID_PARAM if the interface does not exist, LIBUSB_ERROR_NO_DEVICE if the device has been disconnected and a LIBUSB_ERROR code on failure. This function is non-portable.
-.
+LIBUSB_ERROR_INVALID_PARAM if the interface does not exist,
+LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
+and a LIBUSB_ERROR code on failure.
+This function is non-portable.
.Pp
-.
.Ft int
.Fn libusb_attach_kernel_driver "libusb_device_handle *devh" "int interface"
-Re-attach an interface kernel driver previously detached. Returns 0 on success,
-LIBUSB_ERROR_INVALID_PARAM if the interface does not exist, LIBUSB_ERROR_NO_DEVICE
-if the device has been disconnect, LIBUSB_ERROR_BUSY if the driver cannot be
-attached because the interface is claimed by a program or driver and a
+Re-attach an interface kernel driver that was previously detached.
+Returns 0 on success,
+LIBUSB_ERROR_INVALID_PARAM if the interface does not exist,
+LIBUSB_ERROR_NO_DEVICE
+if the device has been disconnected, LIBUSB_ERROR_BUSY if the driver cannot be
+attached because the interface is claimed by a program or driver and a
LIBUSB_ERROR code on failure.
-.
.Pp
-.
.Sh USB DESCRIPTORS
-.
.Pp
-.
.Ft int
.Fn libusb_get_device_descriptor "libusb_device *dev" "libusb_device_descriptor *desc"
Get the USB device descriptor for the device
.Fa dev.
-This is a non-blocking function. Returns 0 on success and a LIBUSB_ERROR code on
+This is a non-blocking function.
+Returns 0 on success and a LIBUSB_ERROR code on
failure.
-.
.Pp
-.Ft int
+.Ft int
.Fn libsub_get_active_config_descriptor "libusb_device *dev" "struct libusb_config_descriptor **config"
-Get the USB configuration descriptor for the active configuration. Returns 0 on
-success, returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state
-and return another LIBUSB_ERROR code on error.
-.
+Get the USB configuration descriptor for the active configuration.
+Returns 0 on
+success, LIBUSB_ERROR_NOT_FOUND if the device is in
+an unconfigured state
+and a LIBUSB_ERROR code on error.
.Pp
-.Ft int
+.Ft int
.Fn libusb_get_config_descriptor "libusb_device *dev" "uint8_t config_index" "libusb_config_descriptor **config"
-Get USB configuration descriptor based on its index
+Get a USB configuration descriptor based on its index
.Fa idx.
-Returns 0 on success, LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
-and returns another LIBUSB_ERROR code on error.
-.
+Returns 0 on success, LIBUSB_ERROR_NOT_FOUND if the configuration does not exist
+and a LIBUSB_ERROR code on error.
.Pp
.Ft int
.Fn libusb_get_config_descriptor_by_value "libusb_device *dev" "uint8 bConfigurationValue" "libusb_config_descriptor **config"
-Get a USB configuration descriptor with a specific bConfigurationValue. This is
-a non-blocking function which does not send request through the device. Returns 0
-on success, LIBUSB_ERROR_NOT_FOUND if the configuration does not exist and another
+Get a USB configuration descriptor with a specific bConfigurationValue.
+This is
+a non-blocking function which does not send a request through the device.
+Returns 0
+on success, LIBUSB_ERROR_NOT_FOUND if the configuration
+does not exist and a
LIBUSB_ERROR code on failure.
-.
.Pp
.Ft void
.Fn libusb_free_config_descriptor "libusb_config_descriptor *config"
Free a configuration descriptor.
-.
.Pp
.Ft int
.Fn libusb_get_string_descriptor_ascii "libusb_device_handle *devh" "uint8_t desc_idx" "unsigned char *data" "int length"
-Retrieve a string descriptor in C style ascii. Returns a number of byte on success
-and a LIBUSB_ERROR code on failure.
-.
+Retrieve a string descriptor in C style ASCII.
+Returns the positive number of bytes in the resulting ASCII string
+on success and a LIBUSB_ERROR code on failure.
.Pp
-.
.Sh USB ASYNCHRONOUS I/O
-.
.Pp
.Ft struct libusb_transfer *
.Fn libusb_alloc_transfer "int iso_packets"
-Allocate a transfer with
-.Fa iso_packets
-numbers of isochronous packet descriptors. Returns NULL on error.
-.
+Allocate a transfer with the number of isochronous packet descriptors
+specified by
+.Fa iso_packets .
+Returns NULL on error.
.Pp
.Ft void
.Fn libusb_free_transfer "struct libusb_transfer *tr"
Free a transfer.
-.
.Pp
.Ft int
.Fn libusb_submit_transfer "struct libusb_transfer *tr"
-This function will submit a transfer and returns immediately. Returns 0 on
-success, LIBUSB_ERROR_NO_DEVICE if the device has been disconnected and
+This function will submit a transfer and returns immediately.
+Returns 0 on success, LIBUSB_ERROR_NO_DEVICE if
+the device has been disconnected and a
LIBUSB_ERROR code on other failure.
-.
.Pp
.Ft int
.Fn libusb_cancel_transfer "struct libusb_transfer *tr"
-This function asynchronously cancel a transfer. Returns 0 on success and
-LIBUSB_ERROR code on failure.
-.
+This function asynchronously cancels a transfer.
+Returns 0 on success and a LIBUSB_ERROR code on failure.
.Pp
.Sh USB SYNCHRONOUS I/O
-.
.Pp
.Ft int
.Fn libusb_control_transfer "libusb_device_handle *devh" "uint8_t bmRequestType" "uint8_t bRequest" "uint16_t wValue" "uint16_t wIndex" "unsigned char *data" "uint16_t wLength" "unsigned int timeout"
-Perform a USB control transfer. Returns the actual number of bytes
-transferred on success in the range from and including zero until and
+Perform a USB control transfer.
+Returns the actual number of bytes
+transferred on success, in the range from and including zero up to and
including
.Fa wLength .
-On error a libusb error code is returned, for example
-LIBUSB_ERROR_TIMEOUT if the transfer timeout, LIBUSB_ERROR_PIPE if the
+On error a LIBUSB_ERROR code is returned, for example
+LIBUSB_ERROR_TIMEOUT if the transfer timed out, LIBUSB_ERROR_PIPE if the
control request was not supported, LIBUSB_ERROR_NO_DEVICE if the
-device has been disconnected or another LIBUSB_ERROR code on other failures.
-The libusb error codes are always negative.
-.
+device has been disconnected and another LIBUSB_ERROR code on other failures.
+The LIBUSB_ERROR codes are all negative.
.Pp
.Ft int
.Fn libusb_bulk_transfer "struct libusb_device_handle *devh" "unsigned char endpoint" "unsigned char *data" "int length" "int *transferred" "unsigned int timeout"
Perform an USB bulk transfer.
A timeout value of zero means no timeout.
The timeout value is given in milliseconds.
-Returns 0 on success, LIBUSB_ERROR_TIMEOUT
-if the transfer timeout, LIBUSB_ERROR_PIPE if the control request was not
-supported, LIBUSB_ERROR_OVERFLOW if the device offered more data,
-LIBUSB_ERROR_NO_DEVICE if the device has been disconnected and
-LIBUSB_ERROR code on other failure.
-.
+Returns 0 on success, LIBUSB_ERROR_TIMEOUT
+if the transfer timed out, LIBUSB_ERROR_PIPE if the control request was not
+supported, LIBUSB_ERROR_OVERFLOW if the device offered more data,
+LIBUSB_ERROR_NO_DEVICE if the device has been disconnected and
+a LIBUSB_ERROR code on other failure.
.Pp
.Ft int
.Fn libusb_interrupt_transfer "struct libusb_device_handle *devh" "unsigned char endpoint" "unsigned char *data" "int length" "int *transferred" "unsigned int timeout"
Perform an USB Interrupt transfer.
A timeout value of zero means no timeout.
The timeout value is given in milliseconds.
-Returns 0 on success, LIBUSB_ERROR_TIMEOUT
-if the transfer timeout, LIBUSB_ERROR_PIPE if the control request was not
-supported, LIBUSB_ERROR_OVERFLOW if the device offered more data,
-LIBUSB_ERROR_NO_DEVICE if the device has been disconnected and
-LIBUSB_ERROR code on other failure.
-.
+Returns 0 on success, LIBUSB_ERROR_TIMEOUT
+if the transfer timed out, LIBUSB_ERROR_PIPE if the control request was not
+supported, LIBUSB_ERROR_OVERFLOW if the device offered more data,
+LIBUSB_ERROR_NO_DEVICE if the device has been disconnected and
+a LIBUSB_ERROR code on other failure.
.Pp
.Sh USB EVENTS
-.
.Pp
.Ft int
.Fn libusb_try_lock_events "libusb_context *ctx"
-Try to acquire the event handling lock. Returns 0 if the lock was obtained and 1
-if not.
-.
+Try to acquire the event handling lock.
+Returns 0 if the lock was obtained and 1 if not.
.Pp
.Ft void
.Fn libusb_lock_events "libusb_context *ctx"
-Acquire the event handling lock. This function is blocking.
-.
+Acquire the event handling lock.
+This function is blocking.
.Pp
.Ft void
.Fn libusb_unlock_events "libusb_context *ctx"
-Release the event handling lock. This will wake up any thread blocked
-on libusb_wait_for_event().
-.
+Release the event handling lock.
+This will wake up any thread blocked
+on
+.B libusb_wait_for_event() .
.Pp
.Ft int
.Fn libusb_event_handling_ok "libusb_context *ctx"
-Determine if it still OK for this thread to be doing event handling. Returns 1
-if event handling can start or continue. Returns 0 if this thread must give up
+Determine if it still OK for this thread to be doing event handling.
+Returns 1
+if event handling can start or continue.
+Returns 0 if this thread must give up
the events lock.
-.
.Pp
.Ft int
.Fn libusb_event_handler_active "libusb_context *ctx"
-Determine if an active thread is handling events. Returns 1 if yes and 0 if there
+Determine if an active thread is handling events.
+Returns 1 if there is a thread handling events and 0 if there
are no threads currently handling events.
-.
.Pp
.Ft void
.Fn libusb_lock_event_waiters "libusb_context *ctx"
-Acquire the event_waiters lock. This lock is designed to be obtained under the
+Acquire the event_waiters lock.
+This lock is designed to be obtained in the
situation where you want to be aware when events are completed, but some other
thread is event handling so calling libusb_handle_events() is not allowed.
-.
.Pp
.Ft void
.Fn libusb_unlock_event_waiters "libusb_context *ctx"
Release the event_waiters lock.
-.
.Pp
-.Ft int
+.Ft int
.Fn libusb_wait_for_event "libusb_context *ctx" "struct timeval *tv"
-Wait for another thread to signal completion of an event. Must be called
-with the event waiters lock held, see libusb_lock_event_waiters(). This will
+Wait for another thread to signal completion of an event.
+Must be called
+with the event waiters lock held, see libusb_lock_event_waiters().
+This will
block until the timeout expires or a transfer completes or a thread releases
-the event handling lock through libusb_unlock_events(). Returns 0 after a
-transfer completes or another thread stops event handling, returns 1 if the
+the event handling lock through libusb_unlock_events().
+Returns 0 after a
+transfer completes or another thread stops event handling, and 1 if the
timeout expired.
-.
.Pp
.Ft int
.Fn libusb_handle_events_timeout "libusb_context *ctx" "struct timeval *tv"
-Handle any pending events by checking if timeouts have expired and by
-checking the set of file descriptors for activity. Returns 0 on success, or a
+Handle any pending events by checking if timeouts have expired and by
+checking the set of file descriptors for activity.
+Returns 0 on success, or a
LIBUSB_ERROR code on failure.
-.
.Pp
.Ft int
.Fn libusb_handle_events "libusb_context *ctx"
-Handle any pending events in blocking mode with a sensible timeout. Returns 0
-on success, returns a LIBUSB_ERROR code on failure.
-.
+Handle any pending events in blocking mode with a sensible timeout.
+Returns 0
+on success and a LIBUSB_ERROR code on failure.
.Pp
.Ft int
.Fn libusb_handle_events_locked "libusb_context *ctx" "struct timeval *tv"
Handle any pending events by polling file desciptors, without checking if
-another threads are already doing so. Must be called with the event lock held.
-.
+another thread is already doing so.
+Must be called with the event lock held.
.Pp
.Ft int
.Fn libusb_get_next_timeout "libusb_context *ctx" "struct timeval *tv"
-Determine the next internal timeout that libusb needs to handle. Returns 0
-if there are no pending timeouts, 1 if a timeout was returned, or LIBUSB_ERROR
+Determine the next internal timeout that libusb needs to handle.
+Returns 0
+if there are no pending timeouts, 1 if a timeout was returned, or a LIBUSB_ERROR
code on failure.
-.
.Pp
.Ft void
.Fn libusb_set_pollfd_notifiers "libusb_context *ctx" "libusb_pollfd_added_cb added_cb" "libusb_pollfd_removed_cb remove_cb" "void *user_data"
Register notification functions for file descriptor additions/removals.
These functions will be invoked for every new or removed file descriptor
that libusb uses as an event source.
-.
.Pp
.Ft const struct libusb_pollfd **
.Fn libusb_get_pollfds "libusb_context *ctx"
-Retrive a list of file descriptors that should be polled by your main loop as
-libusb event sources. Returns a NULL-terminated list on success or NULL on failure.
-.
+Retrive a list of file descriptors that should be polled by your main loop as
+libusb event sources.
+Returns a NULL-terminated list on success or NULL on failure.
.Sh LIBUSB VERSION 0.1 COMPATIBILITY
.Pp
The library is also compliant with LibUSB version 0.1.12.
@@ -544,16 +499,13 @@ The library is also compliant with LibUSB version 0.1.12.
.Fn usb_check_connected
.Fn usb_get_driver_np
.Fn usb_detach_kernel_driver_np
-.
.Sh SEE ALSO
.Xr libusb20 3 ,
.Xr usb 4 ,
.Xr usbconfig 8
.Pp
.Pa http://libusb.sourceforge.net/
-.
.Sh HISTORY
-.
.Nm
support first appeared in
.Fx 8.0 .
diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h
index 0c9e50f..bbde475 100644
--- a/lib/libusb/libusb.h
+++ b/lib/libusb/libusb.h
@@ -151,6 +151,14 @@ enum libusb_error {
LIBUSB_ERROR_OTHER = -99,
};
+enum libusb_speed {
+ LIBUSB_SPEED_UNKNOWN = 0,
+ LIBUSB_SPEED_LOW = 1,
+ LIBUSB_SPEED_FULL = 2,
+ LIBUSB_SPEED_HIGH = 3,
+ LIBUSB_SPEED_SUPER = 4,
+};
+
enum libusb_transfer_status {
LIBUSB_TRANSFER_COMPLETED,
LIBUSB_TRANSFER_ERROR,
@@ -304,6 +312,7 @@ ssize_t libusb_get_device_list(libusb_context * ctx, libusb_device *** list);
void libusb_free_device_list(libusb_device ** list, int unref_devices);
uint8_t libusb_get_bus_number(libusb_device * dev);
uint8_t libusb_get_device_address(libusb_device * dev);
+enum libusb_speed libusb_get_device_speed(libusb_device * dev);
int libusb_clear_halt(libusb_device_handle *devh, uint8_t endpoint);
int libusb_get_max_packet_size(libusb_device * dev, uint8_t endpoint);
libusb_device *libusb_ref_device(libusb_device * dev);
diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c
index 3ecba58..b66ccb6 100644
--- a/lib/libusb/libusb10.c
+++ b/lib/libusb/libusb10.c
@@ -272,6 +272,27 @@ libusb_get_device_address(libusb_device *dev)
return (libusb20_dev_get_address(dev->os_priv));
}
+enum libusb_speed
+libusb_get_device_speed(libusb_device *dev)
+{
+ if (dev == NULL)
+ return (LIBUSB_SPEED_UNKNOWN); /* should not happen */
+
+ switch (libusb20_dev_get_speed(dev->os_priv)) {
+ case LIBUSB20_SPEED_LOW:
+ return (LIBUSB_SPEED_LOW);
+ case LIBUSB20_SPEED_FULL:
+ return (LIBUSB_SPEED_FULL);
+ case LIBUSB20_SPEED_HIGH:
+ return (LIBUSB_SPEED_HIGH);
+ case LIBUSB20_SPEED_SUPER:
+ return (LIBUSB_SPEED_SUPER);
+ default:
+ break;
+ }
+ return (LIBUSB_SPEED_UNKNOWN);
+}
+
int
libusb_get_max_packet_size(libusb_device *dev, uint8_t endpoint)
{
diff --git a/lib/libusbhid/parse.c b/lib/libusbhid/parse.c
index ce034b1..d2b49d4 100644
--- a/lib/libusbhid/parse.c
+++ b/lib/libusbhid/parse.c
@@ -322,6 +322,8 @@ hid_get_item(hid_data_t s, hid_item_t *h)
* one and one item:
*/
c->report_count = 1;
+ c->usage_minimum = 0;
+ c->usage_maximum = 0;
} else {
s->ncount = 1;
}
@@ -512,13 +514,14 @@ hid_report_size(report_desc_t r, enum hid_kind k, int id)
uint32_t temp;
uint32_t hpos;
uint32_t lpos;
+ int report_id = 0;
hpos = 0;
lpos = 0xFFFFFFFF;
memset(&h, 0, sizeof h);
for (d = hid_start_parse(r, 1 << k, id); hid_get_item(d, &h); ) {
- if (h.report_ID == id && h.kind == k) {
+ if ((h.report_ID == id || id < 0) && h.kind == k) {
/* compute minimum */
if (lpos > h.pos)
lpos = h.pos;
@@ -527,6 +530,8 @@ hid_report_size(report_desc_t r, enum hid_kind k, int id)
/* compute maximum */
if (hpos < temp)
hpos = temp;
+ if (h.report_ID != 0)
+ report_id = 1;
}
}
hid_end_parse(d);
@@ -537,11 +542,8 @@ hid_report_size(report_desc_t r, enum hid_kind k, int id)
else
temp = hpos - lpos;
- if (id)
- temp += 8;
-
/* return length in bytes rounded up */
- return ((temp + 7) / 8);
+ return ((temp + 7) / 8 + report_id);
}
int
diff --git a/lib/libz/Makefile b/lib/libz/Makefile
index c03a1c3..8ae9aeb 100644
--- a/lib/libz/Makefile
+++ b/lib/libz/Makefile
@@ -42,16 +42,16 @@ CFLAGS+= -DASMV -DNO_UNDERLINE
ACFLAGS+= -Wa,--noexecstack
.endif
-.if ${MACHINE_ARCH} == "amd64"
-.PATH: ${.CURDIR}/contrib/gcc_gvmat64
-SRCS+= gvmat64.S
-CFLAGS+= -DASMV -DNO_UNDERLINE
-ACFLAGS+= -Wa,--noexecstack
-.if ${CC:T:Mclang} == "clang"
-# XXX: clang integrated-as doesn't grok .intel_syntax directives yet
-ACFLAGS+= ${.IMPSRC:T:Mgvmat64.S:C/^.+$/-no-integrated-as/}
-.endif
-.endif
+#.if ${MACHINE_ARCH} == "amd64"
+#.PATH: ${.CURDIR}/contrib/gcc_gvmat64
+#SRCS+= gvmat64.S
+#CFLAGS+= -DASMV -DNO_UNDERLINE
+#ACFLAGS+= -Wa,--noexecstack
+#.if ${CC:T:Mclang} == "clang"
+## XXX: clang integrated-as doesn't grok .intel_syntax directives yet
+#ACFLAGS+= ${.IMPSRC:T:Mgvmat64.S:C/^.+$/-no-integrated-as/}
+#.endif
+#.endif
VERSION_DEF= ${.CURDIR}/Versions.def
SYMBOL_MAPS= ${.CURDIR}/Symbol.map
OpenPOWER on IntegriCloud