diff options
author | grehan <grehan@FreeBSD.org> | 2011-09-15 22:14:35 +0000 |
---|---|---|
committer | grehan <grehan@FreeBSD.org> | 2011-09-15 22:14:35 +0000 |
commit | 2256cbe5692847d9defa97bdd74ce0aa9e74157d (patch) | |
tree | 42ba64b8c25f527cf3d9b56c4ce4c51c11d445d1 /lib | |
parent | 1823067d93fba5ecf7990fee39428954fa5cbf1b (diff) | |
parent | e6011fb6bc29d6740516409bd2963015c583c2e9 (diff) | |
download | FreeBSD-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')
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 |