Update Source To libutil-58.40.2

This commit is contained in:
Thomas A 2023-02-05 18:32:05 -08:00
parent cd2e90bdf0
commit 1557cdf88a
9 changed files with 1020 additions and 7 deletions

86
expand_number.3 Normal file
View File

@ -0,0 +1,86 @@
.\" Copyright (c) 2007 Eric Anderson <anderson@FreeBSD.org>
.\" Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
.\" 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 AUTHORS 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 AUTHORS 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, 2019
.Dt EXPAND_NUMBER 3
.Os
.Sh NAME
.Nm expand_number
.Nd format a number from human readable form
.Sh LIBRARY
.Lb libutil
.Sh SYNOPSIS
.In libutil.h
.Ft int
.Fo expand_number
.Fa "const char *buf" "uint64_t *num"
.Fc
.Sh DESCRIPTION
The
.Fn expand_number
function parses the
.Fa buf
string and stores a unsigned 64-bit quantity at
.Fa *num .
.Pp
The
.Fn expand_number
function
is case-insensitive and
follows the SI power of two convention.
.Pp
The suffixes are:
.Bl -column "Suffix" "Description" "1000000000000000000" -offset indent
.It Sy "Suffix" Ta Sy "Description" Ta Sy "Multiplier"
.It Li K Ta No kilo Ta 1024
.It Li M Ta No mega Ta 1048576
.It Li G Ta No giga Ta 1073741824
.It Li T Ta No tera Ta 1099511627776
.It Li P Ta No peta Ta 1125899906842624
.It Li E Ta No exa Ta 1152921504606846976
.El
.Sh RETURN VALUES
.Rv -std
.Sh ERRORS
The
.Fn expand_number
function will fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
The given string contains no digits.
.It Bq Er EINVAL
An unrecognized suffix was given.
.It Bq Er ERANGE
Result doesn't fit into 64 bits.
.El
.Sh SEE ALSO
.Xr humanize_number 3
.Sh HISTORY
The
.Fn expand_number
function first appeared in
.Fx 6.3 .

95
expand_number.c Normal file
View File

@ -0,0 +1,95 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2007 Eric Anderson <anderson@FreeBSD.org>
* Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* 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 AUTHORS 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 AUTHORS 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$");
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <inttypes.h>
#include <libutil.h>
#include <stdint.h>
int
expand_number(const char *buf, uint64_t *num)
{
char *endptr;
uintmax_t umaxval;
uint64_t number;
unsigned shift;
int serrno;
serrno = errno;
errno = 0;
umaxval = strtoumax(buf, &endptr, 0);
if (umaxval > UINT64_MAX)
errno = ERANGE;
if (errno != 0)
return (-1);
errno = serrno;
number = umaxval;
switch (tolower((unsigned char)*endptr)) {
case 'e':
shift = 60;
break;
case 'p':
shift = 50;
break;
case 't':
shift = 40;
break;
case 'g':
shift = 30;
break;
case 'm':
shift = 20;
break;
case 'k':
shift = 10;
break;
case 'b':
case '\0': /* No unit. */
*num = number;
return (0);
default:
/* Unrecognized unit. */
errno = EINVAL;
return (-1);
}
if ((number << shift) >> shift != number) {
/* Overflow */
errno = ERANGE;
return (-1);
}
*num = number << shift;
return (0);
}

View File

@ -1,3 +1,4 @@
_expand_number
_freemntopts
_getmnt_silent
_getmntoptnum

View File

@ -58,6 +58,7 @@ struct in_addr;
struct sockaddr;
__BEGIN_DECLS
int expand_number(const char *_buf, uint64_t *_num);
int humanize_number(char *_buf, size_t _len, int64_t _number,
const char *_suffix, int _scale, int _flags);

View File

@ -82,6 +82,8 @@
BA79F9E613BB76B0006A292D /* wipefs.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = BA79F9BC13BB70FF006A292D /* wipefs.3 */; };
BA79F9E913BB77FA006A292D /* libutil.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = BA79F9AB13BB70FF006A292D /* libutil.plist */; };
BA79F9EA13BB77FF006A292D /* libutil.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = BA79F9AC13BB70FF006A292D /* libutil.txt */; };
C198003123F661F9004D70D5 /* expand_number.c in Sources */ = {isa = PBXBuildFile; fileRef = C198003023F661DF004D70D5 /* expand_number.c */; };
C198003223F66284004D70D5 /* expand_number.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C198002F23F661DF004D70D5 /* expand_number.3 */; };
FDA46DED1D6D110000C63528 /* libutil.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = FDA46DEC1D6D110000C63528 /* libutil.plist */; };
FDA4991B199D6A0400A32E83 /* humanize_number_test.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA4991A199D6A0400A32E83 /* humanize_number_test.c */; };
FDA4991C199D6B9300A32E83 /* libutil.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BA79F9C513BB718B006A292D /* libutil.dylib */; };
@ -164,6 +166,7 @@
dstPath = /usr/local/share/man/man3;
dstSubfolderSpec = 0;
files = (
C198003223F66284004D70D5 /* expand_number.3 in CopyFiles */,
BA79F9DD13BB76B0006A292D /* getmntopts.3 in CopyFiles */,
BA79F9DE13BB76B0006A292D /* humanize_number.3 in CopyFiles */,
BA79F9DF13BB76B0006A292D /* pidfile.3 in CopyFiles */,
@ -244,6 +247,8 @@
BA79F9BD13BB70FF006A292D /* wipefs.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wipefs.cpp; sourceTree = "<group>"; };
BA79F9BE13BB70FF006A292D /* wipefs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wipefs.h; sourceTree = "<group>"; };
BA79F9C513BB718B006A292D /* libutil.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libutil.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
C198002F23F661DF004D70D5 /* expand_number.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = expand_number.3; sourceTree = "<group>"; };
C198003023F661DF004D70D5 /* expand_number.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = expand_number.c; sourceTree = "<group>"; };
FDA46DEC1D6D110000C63528 /* libutil.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = libutil.plist; sourceTree = "<group>"; };
FDA49903199D69B000A32E83 /* humanize_number_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = humanize_number_test; sourceTree = BUILT_PRODUCTS_DIR; };
FDA4991A199D6A0400A32E83 /* humanize_number_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = humanize_number_test.c; sourceTree = "<group>"; };
@ -294,8 +299,11 @@
BA79F99513BB70D7006A292D = {
isa = PBXGroup;
children = (
C198002F23F661DF004D70D5 /* expand_number.3 */,
C198003023F661DF004D70D5 /* expand_number.c */,
BA79F9A313BB70FF006A292D /* ExtentManager.cpp */,
BA79F9A413BB70FF006A292D /* ExtentManager.h */,
7259A9711D519321008F83F6 /* Frameworks */,
BA79F9A513BB70FF006A292D /* getmntopts.3 */,
BA79F9A613BB70FF006A292D /* getmntopts.c */,
BA79F9A713BB70FF006A292D /* humanize_number.3 */,
@ -307,6 +315,7 @@
BA79F9AE13BB70FF006A292D /* mntopts.h */,
BA79F9AF13BB70FF006A292D /* pidfile.3 */,
BA79F9B013BB70FF006A292D /* pidfile.c */,
BA79F9C613BB718B006A292D /* Products */,
BA79F9B313BB70FF006A292D /* realhostname_sa.3 */,
BA79F9B413BB70FF006A292D /* realhostname.3 */,
BA79F9B513BB70FF006A292D /* realhostname.c */,
@ -315,16 +324,14 @@
FDA49919199D6A0400A32E83 /* tests */,
BA79F9B813BB70FF006A292D /* trimdomain.3 */,
BA79F9B913BB70FF006A292D /* trimdomain.c */,
FDBC27081741B47200CA4B2B /* tzlink_internal.h */,
FDBC26F91741B18500CA4B2B /* tzlink.c */,
FDBC27091741B47200CA4B2B /* tzlink.h */,
FDBC27081741B47200CA4B2B /* tzlink_internal.h */,
FDBC26F11741B13400CA4B2B /* tzlinkd */,
BA79F9BC13BB70FF006A292D /* wipefs.3 */,
BA79F9BD13BB70FF006A292D /* wipefs.cpp */,
BA79F9BE13BB70FF006A292D /* wipefs.h */,
FDBC270C1741B66500CA4B2B /* xcconfigs */,
BA79F9C613BB718B006A292D /* Products */,
7259A9711D519321008F83F6 /* Frameworks */,
);
sourceTree = "<group>";
};
@ -431,6 +438,7 @@
FDBC26EC1741B13400CA4B2B /* Sources */,
FDBC26ED1741B13400CA4B2B /* Frameworks */,
FDBC26EE1741B13400CA4B2B /* CopyFiles */,
35459D5A24BF78E800AD3207 /* Install Sandbox Profile */,
);
buildRules = (
);
@ -447,14 +455,15 @@
BA79F99713BB70D7006A292D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0420;
LastUpgradeCheck = 1200;
};
buildConfigurationList = BA79F99A13BB70D7006A292D /* Build configuration list for PBXProject "libutil" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = BA79F99513BB70D7006A292D;
productRefGroup = BA79F9C613BB718B006A292D /* Products */;
@ -473,6 +482,26 @@
/* End PBXProject section */
/* Begin PBXShellScriptBuildPhase section */
35459D5A24BF78E800AD3207 /* Install Sandbox Profile */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"$(SRCROOT)/tzlinkd/com.apple.tzlinkd.sb",
);
name = "Install Sandbox Profile";
outputFileListPaths = (
);
outputPaths = (
"$(INSTALL_ROOT)/System/Library/Sandbox/Profiles/com.apple.tzlinkd.sb",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if [ ${PLATFORM_NAME} = \"macosx\" ]; then\n ${CP} ${SCRIPT_INPUT_FILE_0} ${SCRIPT_OUTPUT_FILE_0}\nfi\n";
};
BA79F9DA13BB750E006A292D /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@ -512,6 +541,7 @@
BA79F9CC13BB7207006A292D /* getmntopts.c in Sources */,
BA79F9CD13BB7207006A292D /* humanize_number.c in Sources */,
BA79F9CE13BB7207006A292D /* pidfile.c in Sources */,
C198003123F661F9004D70D5 /* expand_number.c in Sources */,
BA79F9D013BB7207006A292D /* realhostname.c in Sources */,
BA79F9D113BB7207006A292D /* reexec_to_match_kernel.c in Sources */,
BA79F9D213BB7207006A292D /* trimdomain.c in Sources */,
@ -590,6 +620,7 @@
3EB206CD1F5096F100B150D3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
@ -597,6 +628,7 @@
3EB206CE1F5096F100B150D3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
@ -606,6 +638,34 @@
baseConfigurationReference = 3F09C378186D1F73007AF93C /* base.xcconfig */;
buildSettings = {
APPLY_RULES_IN_COPY_FILES = YES;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
"PLIST_FILE_OUTPUT_FORMAT[sdk=iphoneos*]" = binary;
"PLIST_FILE_OUTPUT_FORMAT[sdk=macosx*]" = XML;
USE_HEADERMAP = NO;
@ -617,6 +677,32 @@
baseConfigurationReference = 3F09C378186D1F73007AF93C /* base.xcconfig */;
buildSettings = {
APPLY_RULES_IN_COPY_FILES = YES;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
"PLIST_FILE_OUTPUT_FORMAT[sdk=iphoneos*]" = binary;
"PLIST_FILE_OUTPUT_FORMAT[sdk=macosx*]" = XML;
USE_HEADERMAP = NO;
@ -627,7 +713,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 3F7A5E8820510D34007087AF /* lib.xcconfig */;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
CLANG_ENABLE_OBJC_WEAK = YES;
DYLIB_COMPATIBILITY_VERSION = 1.0;
DYLIB_CURRENT_VERSION = 1.0;
EXECUTABLE_PREFIX = lib;
@ -654,7 +740,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 3F7A5E8820510D34007087AF /* lib.xcconfig */;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
CLANG_ENABLE_OBJC_WEAK = YES;
DYLIB_COMPATIBILITY_VERSION = 1.0;
DYLIB_CURRENT_VERSION = 1.0;
EXECUTABLE_PREFIX = lib;
@ -676,6 +762,8 @@
isa = XCBuildConfiguration;
baseConfigurationReference = FDA4991D199D6CB800A32E83 /* test.xcconfig */;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = YES;
CODE_SIGN_IDENTITY = "-";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
@ -684,6 +772,8 @@
isa = XCBuildConfiguration;
baseConfigurationReference = FDA4991D199D6CB800A32E83 /* test.xcconfig */;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = YES;
CODE_SIGN_IDENTITY = "-";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
@ -691,6 +781,7 @@
FDA49911199D69B800A32E83 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
@ -698,6 +789,7 @@
FDA49912199D69B800A32E83 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
@ -705,6 +797,7 @@
FDBC26E51741B09300CA4B2B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
@ -712,6 +805,7 @@
FDBC26E61741B09300CA4B2B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
@ -719,6 +813,7 @@
FDBC26EA1741B09D00CA4B2B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
@ -726,6 +821,7 @@
FDBC26EB1741B09D00CA4B2B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
@ -734,6 +830,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = FDBC270D1741B66500CA4B2B /* tzlinkd.xcconfig */;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
};
name = Debug;
@ -742,6 +839,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = FDBC270D1741B66500CA4B2B /* tzlinkd.xcconfig */;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
};
name = Release;

View File

@ -0,0 +1,621 @@
/*-
* Copyright 2012 Clifton Royston
* Copyright 2013 John-Mark Gurney
* 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 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$
*
*/
#include <sys/param.h>
#include <inttypes.h>
#include <libutil.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define MAX_STR_FLAGS_RESULT 80
#define MAX_INT_STR_DIGITS 12
#ifdef __APPLE__
#define nitems(x) (sizeof((x)) / sizeof((x)[0]))
#define __INT_MAX INT_MAX
#endif /* __APPLE__ */
static const int64_t halfExabyte = (int64_t)500*1000*1000*1000*1000*1000L;
static struct {
int retval;
const char *res;
int64_t num;
int flags;
int scale;
} test_args[] = {
/* tests 0-13 test 1000 suffixes */
{ 2, "0 ", (int64_t)0L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 3, "1 k", (int64_t)500L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 3, "1 M", (int64_t)500*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 3, "1 G", (int64_t)500*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 3, "1 T", (int64_t)500*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 3, "1 P", (int64_t)500*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 3, "1 E", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 2, "1 ", (int64_t)1L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 3, "2 k", (int64_t)1500L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 3, "2 M", (int64_t)1500*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 3, "2 G", (int64_t)1500*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 3, "2 T", (int64_t)1500*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 3, "2 P", (int64_t)1500*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 3, "2 E", (int64_t)1500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
/* tests 14-27 test 1024 suffixes */
{ 2, "0 ", (int64_t)0L, 0, HN_AUTOSCALE },
{ 3, "1 K", (int64_t)512L, 0, HN_AUTOSCALE },
{ 3, "1 M", (int64_t)512*1024L, 0, HN_AUTOSCALE },
{ 3, "1 G", (int64_t)512*1024*1024L, 0, HN_AUTOSCALE },
{ 3, "1 T", (int64_t)512*1024*1024*1024L, 0, HN_AUTOSCALE },
{ 3, "1 P", (int64_t)512*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
{ 3, "1 E", (int64_t)512*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
{ 2, "1 ", (int64_t)1L, 0, HN_AUTOSCALE },
{ 3, "2 K", (int64_t)1536L, 0, HN_AUTOSCALE },
{ 3, "2 M", (int64_t)1536*1024L, 0, HN_AUTOSCALE },
{ 3, "2 G", (int64_t)1536*1024*1024L, 0, HN_AUTOSCALE },
{ 3, "2 T", (int64_t)1536*1024*1024*1024L, 0, HN_AUTOSCALE },
{ 3, "2 P", (int64_t)1536*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
{ 3, "2 E", (int64_t)1536*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
/* tests 28-37 test rounding */
{ 3, "0 M", (int64_t)500*1000L-1, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 3, "1 M", (int64_t)500*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 3, "1 M", (int64_t)1000*1000L + 500*1000L-1, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 3, "2 M", (int64_t)1000*1000L + 500*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 3, "0 K", (int64_t)512L-1, 0, HN_AUTOSCALE },
{ 3, "1 K", (int64_t)512L, 0, HN_AUTOSCALE },
{ 3, "0 M", (int64_t)512*1024L-1, 0, HN_AUTOSCALE },
{ 3, "1 M", (int64_t)512*1024L, 0, HN_AUTOSCALE },
{ 3, "1 M", (int64_t)1024*1024L + 512*1024L-1, 0, HN_AUTOSCALE },
{ 3, "2 M", (int64_t)1024*1024L + 512*1024L, 0, HN_AUTOSCALE },
/* tests 38-61 test specific scale factors with 1000 divisor */
{ 3, "0 k", (int64_t)0L, HN_DIVISOR_1000, 1 },
{ 3, "1 k", (int64_t)500L, HN_DIVISOR_1000, 1 },
{ 3, "0 M", (int64_t)500L, HN_DIVISOR_1000, 2 },
{ 3, "1 M", (int64_t)500*1000L, HN_DIVISOR_1000, 2 },
{ 3, "0 G", (int64_t)500*1000L, HN_DIVISOR_1000, 3 },
{ 3, "1 G", (int64_t)500*1000*1000L, HN_DIVISOR_1000, 3 },
{ 3, "0 T", (int64_t)500*1000*1000L, HN_DIVISOR_1000, 4 },
{ 3, "1 T", (int64_t)500*1000*1000*1000L, HN_DIVISOR_1000, 4 },
{ 3, "0 P", (int64_t)500*1000*1000*1000L, HN_DIVISOR_1000, 5 },
{ 3, "1 P", (int64_t)500*1000*1000*1000*1000L, HN_DIVISOR_1000, 5 },
{ 3, "0 E", (int64_t)500*1000*1000*1000*1000L, HN_DIVISOR_1000, 6 },
{ 3, "1 E", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6 },
{ 3, "0 k", (int64_t)1L, HN_DIVISOR_1000, 1 },
{ 3, "2 k", (int64_t)1500L, HN_DIVISOR_1000, 1 },
{ 3, "0 M", (int64_t)1500L, HN_DIVISOR_1000, 2 },
{ 3, "2 M", (int64_t)1500*1000L, HN_DIVISOR_1000, 2 },
{ 3, "0 G", (int64_t)1500*1000L, HN_DIVISOR_1000, 3 },
{ 3, "2 G", (int64_t)1500*1000*1000L, HN_DIVISOR_1000, 3 },
{ 3, "0 T", (int64_t)1500*1000*1000L, HN_DIVISOR_1000, 4 },
{ 3, "2 T", (int64_t)1500*1000*1000*1000L, HN_DIVISOR_1000, 4 },
{ 3, "0 P", (int64_t)1500*1000*1000*1000L, HN_DIVISOR_1000, 5 },
{ 3, "2 P", (int64_t)1500*1000*1000*1000*1000L, HN_DIVISOR_1000, 5 },
{ 3, "0 E", (int64_t)1500*1000*1000*1000*1000L, HN_DIVISOR_1000, 6 },
{ 3, "2 E", (int64_t)1500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6 },
/* tests 62-85 test specific scale factors with 1024 divisor */
{ 3, "0 K", (int64_t)0L, 0, 1 },
{ 3, "1 K", (int64_t)512L, 0, 1 },
{ 3, "0 M", (int64_t)512L, 0, 2 },
{ 3, "1 M", (int64_t)512*1024L, 0, 2 },
{ 3, "0 G", (int64_t)512*1024L, 0, 3 },
{ 3, "1 G", (int64_t)512*1024*1024L, 0, 3 },
{ 3, "0 T", (int64_t)512*1024*1024L, 0, 4 },
{ 3, "1 T", (int64_t)512*1024*1024*1024L, 0, 4 },
{ 3, "0 P", (int64_t)512*1024*1024*1024L, 0, 5 },
{ 3, "1 P", (int64_t)512*1024*1024*1024*1024L, 0, 5 },
{ 3, "0 E", (int64_t)512*1024*1024*1024*1024L, 0, 6 },
{ 3, "1 E", (int64_t)512*1024*1024*1024*1024*1024L, 0, 6 },
{ 3, "0 K", (int64_t)1L, 0, 1 },
{ 3, "2 K", (int64_t)1536L, 0, 1 },
{ 3, "0 M", (int64_t)1536L, 0, 2 },
{ 3, "2 M", (int64_t)1536*1024L, 0, 2 },
{ 3, "0 G", (int64_t)1536*1024L, 0, 3 },
{ 3, "2 G", (int64_t)1536*1024*1024L, 0, 3 },
{ 3, "0 T", (int64_t)1536*1024*1024L, 0, 4 },
{ 3, "2 T", (int64_t)1536*1024*1024*1024L, 0, 4 },
{ 3, "0 P", (int64_t)1536*1024*1024*1024L, 0, 5 },
{ 3, "2 P", (int64_t)1536*1024*1024*1024*1024L, 0, 5 },
{ 3, "0 E", (int64_t)1536*1024*1024*1024*1024L, 0, 6 },
{ 3, "2 E", (int64_t)1536*1024*1024*1024*1024*1024L, 0, 6 },
/* tests 86-99 test invalid specific scale values of < 0 or >= 7 with
and without HN_DIVISOR_1000 set */
/* all should return errors with new code; with old, the latter 3
are instead processed as if having AUTOSCALE and/or GETSCALE set */
{ -1, "", (int64_t)1L, 0, 7 },
{ -1, "", (int64_t)1L, HN_DIVISOR_1000, 7 },
{ -1, "", (int64_t)1L, 0, 1000 },
{ -1, "", (int64_t)1L, HN_DIVISOR_1000, 1000 },
{ -1, "", (int64_t)0L, 0, 1000*1000 },
{ -1, "", (int64_t)0L, HN_DIVISOR_1000, 1000*1000 },
{ -1, "", (int64_t)0L, 0, INT_MAX },
{ -1, "", (int64_t)0L, HN_DIVISOR_1000, INT_MAX },
/* Negative scale values are not handled well
by the existing library routine - should report as error */
/* all should return errors with new code, fail assertion with old */
{ -1, "", (int64_t)1L, 0, -1 },
{ -1, "", (int64_t)1L, HN_DIVISOR_1000, -1 },
{ -1, "", (int64_t)1L, 0, -1000 },
{ -1, "", (int64_t)1L, HN_DIVISOR_1000, -1000 },
/* __INT_MIN doesn't print properly, skipped. */
{ -1, "", (int64_t)1L, 0, -__INT_MAX },
{ -1, "", (int64_t)1L, HN_DIVISOR_1000, -__INT_MAX },
/* tests for scale == 0, without autoscale */
/* tests 100-114 test scale 0 with 1000 divisor - print first N digits */
{ 2, "0 ", (int64_t)0L, HN_DIVISOR_1000, 0 },
{ 2, "1 ", (int64_t)1L, HN_DIVISOR_1000, 0 },
{ 3, "10 ", (int64_t)10L, HN_DIVISOR_1000, 0 },
{ 3, "0 M", (int64_t)150L, HN_DIVISOR_1000, HN_NOSPACE },
{ 3, "0 M", (int64_t)500L, HN_DIVISOR_1000, HN_NOSPACE },
{ 3, "0 M", (int64_t)999L, HN_DIVISOR_1000, HN_NOSPACE },
{ 4, "150", (int64_t)150L, HN_DIVISOR_1000, 0 },
{ 4, "500", (int64_t)500L, HN_DIVISOR_1000, 0 },
{ 4, "999", (int64_t)999L, HN_DIVISOR_1000, 0 },
{ 5, "100", (int64_t)1000L, HN_DIVISOR_1000, 0 },
{ 5, "150", (int64_t)1500L, HN_DIVISOR_1000, 0 },
{ 7, "500", (int64_t)500*1000L, HN_DIVISOR_1000, 0 },
{ 8, "150", (int64_t)1500*1000L, HN_DIVISOR_1000, 0 },
{ 10, "500", (int64_t)500*1000*1000L, HN_DIVISOR_1000, 0 },
{ 11, "150", (int64_t)1500*1000*1000L, HN_DIVISOR_1000, 0 },
/* tests 115-126 test scale 0 with 1024 divisor - print first N digits */
{ 2, "0 ", (int64_t)0L, 0, 0 },
{ 2, "1 ", (int64_t)1L, 0, 0 },
{ 3, "10 ", (int64_t)10L, 0, 0 },
{ 4, "150", (int64_t)150L, 0, 0 },
{ 4, "500", (int64_t)500L, 0, 0 },
{ 4, "999", (int64_t)999L, 0, 0 },
{ 5, "100", (int64_t)1000L, 0, 0 },
{ 5, "150", (int64_t)1500L, 0, 0 },
{ 7, "500", (int64_t)500*1000L, 0, 0 },
{ 8, "150", (int64_t)1500*1000L, 0, 0 },
{ 10, "500", (int64_t)500*1000*1000L, 0, 0 },
{ 11, "150", (int64_t)1500*1000*1000L, 0, 0 },
/* Test boundary cases for very large positive/negative number formatting */
/* Explicit scale, divisor 1024 */
/* XXX = requires length 5 (buflen 6) for some cases*/
/* KLUDGE - test loop below will bump length 5 up to 5 */
{ 3, "8 E", INT64_MAX, 0, 6 },
{ 4, "-8 E", -INT64_MAX, 0, 6 },
{ 3, "0 E", (int64_t)92*1024*1024*1024*1024*1024L, 0, 6 },
{ 3, "0 E", -(int64_t)92*1024*1024*1024*1024*1024L, 0, 6 },
{ 3, "0 E", (int64_t)82*1024*1024*1024*1024*1024L, 0, 6 },
{ 3, "0 E", -(int64_t)82*1024*1024*1024*1024*1024L, 0, 6 },
{ 3, "0 E", (int64_t)81*1024*1024*1024*1024*1024L, 0, 6 },
{ 3, "0 E", -(int64_t)81*1024*1024*1024*1024*1024L, 0, 6 },
{ 4, "92 P", (int64_t)92*1024*1024*1024*1024*1024L, 0, 5 },
{ 5, "-92 P", -(int64_t)92*1024*1024*1024*1024*1024L, 0, 5 },
{ 4, "82 P", (int64_t)82*1024*1024*1024*1024*1024L, 0, 5 },
{ 5, "-82 P", -(int64_t)82*1024*1024*1024*1024*1024L, 0, 5 },
{ 4, "81 P", (int64_t)81*1024*1024*1024*1024*1024L, 0, 5 },
{ 5, "-81 P", -(int64_t)81*1024*1024*1024*1024*1024L, 0, 5 },
/* Explicit scale, divisor 1000 */
{ 3, "9 E", INT64_MAX, HN_DIVISOR_1000, 6 },
{ 4, "-9 E", -INT64_MAX, HN_DIVISOR_1000, 6 },
{ 3, "0 E", (int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 6 },
{ 3, "0 E", -(int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 6 },
{ 3, "0 E", (int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 6 },
{ 3, "0 E", -(int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 6 },
{ 4, "92 P", (int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 5 },
{ 5, "-92 P", -(int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 5 },
{ 4, "91 P", (int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 5 },
{ 5, "-91 P", -(int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 5 },
/* Autoscale, divisor 1024 */
{ 3, "8 E", INT64_MAX, 0, HN_AUTOSCALE },
{ 4, "-8 E", -INT64_MAX, 0, HN_AUTOSCALE },
{ 4, "92 P", (int64_t)92*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
{ 5, "-92 P", -(int64_t)92*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
{ 4, "82 P", (int64_t)82*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
{ 5, "-82 P", -(int64_t)82*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
{ 4, "81 P", (int64_t)81*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
{ 5, "-81 P", -(int64_t)81*1024*1024*1024*1024*1024L, 0, HN_AUTOSCALE },
/* Autoscale, divisor 1000 */
{ 3, "9 E", INT64_MAX, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 4, "-9 E", -INT64_MAX, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 4, "92 P", (int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 5, "-92 P", -(int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 4, "91 P", (int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 5, "-91 P", -(int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, HN_AUTOSCALE },
/* 0 scale, divisor 1024 */
{ 12, "skdj", INT64_MAX, 0, 0 },
{ 21, "-9223", -INT64_MAX, 0, 0 },
{ 19, "10358", (int64_t)92*1024*1024*1024*1024*1024L, 0, 0 },
{ 20, "-1035", -(int64_t)92*1024*1024*1024*1024*1024L, 0, 0 },
{ 18, "92323", (int64_t)82*1024*1024*1024*1024*1024L, 0, 0 },
{ 19, "-9232", -(int64_t)82*1024*1024*1024*1024*1024L, 0, 0 },
{ 18, "91197", (int64_t)81*1024*1024*1024*1024*1024L, 0, 0 },
{ 19, "-9119", -(int64_t)81*1024*1024*1024*1024*1024L, 0, 0 },
/* 0 scale, divisor 1000 */
/* XXX - why does this fail? */
{ -1, "", INT64_MAX, HN_DIVISOR_1000, 0 },
{ 21, "-9223", -INT64_MAX, HN_DIVISOR_1000, 0 },
{ 19, "10358", (int64_t)92*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 0 },
{ 20, "-1035", -(int64_t)92*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 0 },
{ 18, "92323", (int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 0 },
{ 19, "-9232", -(int64_t)82*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 0 },
/* Expected to pass */
{ 18, "91197", (int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 0 },
{ 19, "-9119", -(int64_t)81*1024*1024*1024*1024*1024L, HN_DIVISOR_1000, 0 },
/* Need to implement tests for GETSCALE */
/* { ?, "", (int64_t)0L, HN_DIVISOR_1000, HN_GETSCALE },
...
*/
/* Tests for HN_DECIMAL */
/* Positive, Autoscale */
{ 5, "500 k", (int64_t)500*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
{ 5, "994 k", (int64_t)994*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
{ 5, "995 k", (int64_t)995*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
{ 5, "999 k", (int64_t)999*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
{ 5, "1.0 M", (int64_t)1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
{ 5, "1.5 M", (int64_t)1500*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
{ 5, "1.9 M", (int64_t)1949*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
{ 5, "2.0 M", (int64_t)1950*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
{ 5, "9.9 M", (int64_t)9949*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
{ 4, "10 M", (int64_t)9950*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
{ 5, "500 M", (int64_t)500*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
{ 5, "994 M", (int64_t)994*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
{ 5, "995 M", (int64_t)995*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
{ 5, "999 M", (int64_t)999*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
{ 5, "500 K", (int64_t)500*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "994 K", (int64_t)994*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "995 K", (int64_t)995*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "999 K", (int64_t)999*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "1.0 M", (int64_t)1000*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "1.0 M", (int64_t)1018*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "1.0 M", (int64_t)1019*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "1.5 M", (int64_t)1536*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "1.9 M", (int64_t)1996*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "2.0 M", (int64_t)1997*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "2.0 M", (int64_t)2047*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "2.0 M", (int64_t)2048*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "2.0 M", (int64_t)2099*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "2.1 M", (int64_t)2100*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "9.9 M", (int64_t)10188*1024L, HN_DECIMAL, HN_AUTOSCALE },
/* XXX - shouldn't the following two be "10. M"? */
{ 4, "10 M", (int64_t)10189*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 4, "10 M", (int64_t)10240*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "500 M", (int64_t)500*1024*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "994 M", (int64_t)994*1024*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "995 M", (int64_t)995*1024*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "999 M", (int64_t)999*1024*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "1.0 G", (int64_t)1000*1024*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "1.0 G", (int64_t)1023*1024*1024L, HN_DECIMAL, HN_AUTOSCALE },
/* Negative, Autoscale - should pass */
{ 6, "-1.5 ", -(int64_t)1500*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
{ 6, "-1.9 ", -(int64_t)1949*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
{ 6, "-9.9 ", -(int64_t)9949*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
{ 6, "-1.5 ", -(int64_t)1536*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 6, "-1.9 ", -(int64_t)1949*1024L, HN_DECIMAL, HN_AUTOSCALE },
{ 6, "-9.7 ", -(int64_t)9949*1024L, HN_DECIMAL, HN_AUTOSCALE },
/* Positive/negative, at maximum scale */
{ 5, "500 P", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 5, "1.9 E", (int64_t)1949*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 5, "8.9 E", (int64_t)8949*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, HN_AUTOSCALE },
{ 5, "9.2 E", INT64_MAX, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
/* Negatives work with latest rev only: */
{ 6, "-9.2 ", -INT64_MAX, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
{ 6, "-8.9 ", -(int64_t)8949*1000*1000*1000*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, HN_AUTOSCALE },
{ 5, "8.0 E", INT64_MAX, HN_DECIMAL, HN_AUTOSCALE },
{ 5, "7.9 E", INT64_MAX-(int64_t)100*1024*1024*1024*1024*1024LL, HN_DECIMAL, HN_AUTOSCALE },
{ 6, "-8.0 ", -INT64_MAX, HN_DECIMAL, HN_AUTOSCALE },
{ 6, "-7.9 ", -INT64_MAX+(int64_t)100*1024*1024*1024*1024*1024LL, HN_DECIMAL, HN_AUTOSCALE },
/* Positive, Fixed scales */
{ 5, "500 k", (int64_t)500*1000L, HN_DECIMAL|HN_DIVISOR_1000, 1 },
{ 5, "0.5 M", (int64_t)500*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
{ 5, "949 k", (int64_t)949*1000L, HN_DECIMAL|HN_DIVISOR_1000, 1 },
{ 5, "0.9 M", (int64_t)949*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
{ 5, "950 k", (int64_t)950*1000L, HN_DECIMAL|HN_DIVISOR_1000, 1 },
{ 5, "1.0 M", (int64_t)950*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
{ 5, "999 k", (int64_t)999*1000L, HN_DECIMAL|HN_DIVISOR_1000, 1 },
{ 5, "1.0 M", (int64_t)999*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
{ 5, "1.5 M", (int64_t)1500*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
{ 5, "1.9 M", (int64_t)1949*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
{ 5, "2.0 M", (int64_t)1950*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
{ 5, "9.9 M", (int64_t)9949*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
{ 4, "10 M", (int64_t)9950*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
{ 5, "500 M", (int64_t)500*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
{ 5, "0.5 G", (int64_t)500*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, 3 },
{ 5, "999 M", (int64_t)999*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, 2 },
{ 5, "1.0 G", (int64_t)999*1000*1000L, HN_DECIMAL|HN_DIVISOR_1000, 3 },
/* Positive/negative, at maximum scale */
{ 5, "500 P", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 5 },
{ 5, "1.0 E", (int64_t)500*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6 },
{ 5, "1.9 E", (int64_t)1949*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6 },
{ 5, "8.9 E", (int64_t)8949*1000*1000*1000*1000*1000L, HN_DIVISOR_1000, 6 },
{ 5, "9.2 E", INT64_MAX, HN_DECIMAL|HN_DIVISOR_1000, 6 },
/* HN_DECIMAL + binary + fixed scale cases not completed */
{ 5, "512 K", (int64_t)512*1024L, HN_DECIMAL, 1 },
{ 5, "0.5 M", (int64_t)512*1024L, HN_DECIMAL, 2 },
/* Negative, Fixed scales */
/* Not yet added, but should work with latest rev */
};
/* Command line options usage */
static void
usage(char * progname) {
printf("%s: tests libutil humanize_number function\n", progname);
printf("Usage: %s [-nE] [-l num] [-v]\n\n", progname);
printf("Options:\n");
printf("\t-l num\tSet max length for result; buflen = num + 1\n");
printf("\t\t (NOTE: does not change expected result strings.)\n");
printf("\t-n\tInclude negative scale tests, which cause older libutil\n");
printf("\t\t version of function to coredump with assertion failure\n");
printf("\t-E\tInclude numbers > 1/2 Exa[byte] which currently fail\n");
printf("\t-v\tVerbose - always print summary results\n");
printf("\t-h, -?\tShow options\n");
}
/* Parse command line options */
static void
read_options(int argc, char * const argv[], size_t *bufLength,
int *includeNegativeScale, int *includeExabytes, int *verbose) {
int ch;
size_t temp;
while ((ch = getopt(argc, argv, "nEh?vl:")) != -1) {
switch (ch) {
default:
usage(argv[0]);
exit(1);
break; /* UNREACHABLE */
case 'h' :
case '?' :
usage(argv[0]);
exit(0);
break; /* UNREACHABLE */
case 'l' :
sscanf(optarg, "%zu", &temp);
*bufLength = temp + 1;
break;
case 'n' :
*includeNegativeScale = 1;
break;
case 'E' :
*includeExabytes = 1;
break;
case 'v' :
*verbose = 1;
break;
}
}
}
static struct {
int value;
const char *name;
} flags[] = {
{ HN_AUTOSCALE, "HN_AUTOSCALE" },
{ HN_GETSCALE, "HN_GETSCALE" },
{ HN_DIVISOR_1000, "HN_DIVISOR_1000"},
{ HN_B, "HN_B"},
{ HN_DECIMAL, "HN_DECIMAL"},
};
static const char *separator = "|";
/* Format flags parameter for meaningful display */
static char *
str_flags(int hn_flags, char *noFlags) {
size_t i;
char * result;
result = malloc(MAX_STR_FLAGS_RESULT);
result[0] = '\0';
for (i = 0; i < sizeof flags / sizeof *flags; i++) {
if (hn_flags & flags[i].value) {
if (*result != 0)
strlcat(result, separator,
MAX_STR_FLAGS_RESULT);
strlcat(result, flags[i].name, MAX_STR_FLAGS_RESULT);
}
}
if (strlen(result) == 0)
strlcat(result, noFlags, MAX_STR_FLAGS_RESULT);
return result;
}
/* Format scale parameter for meaningful display */
static char *
str_scale(int scale) {
char *result;
if (scale == HN_AUTOSCALE || scale == HN_GETSCALE)
return str_flags(scale, "");
result = malloc(MAX_INT_STR_DIGITS);
result[0] = '\0';
snprintf(result, MAX_INT_STR_DIGITS, "%d", scale);
return result;
}
static void
testskipped(size_t i)
{
printf("ok %zu # skip - not turned on\n", i);
#ifdef __APPLE__
printf("[PASS] test %zu\n", i);
#endif /* __APPLE__ */
}
int
main(int argc, char * const argv[])
{
char *buf;
char *flag_str, *scale_str;
size_t buflen, errcnt, i, skipped, tested;
int r;
int includeNegScale;
int includeExabyteTests;
int verbose;
buflen = 4;
includeNegScale = 0;
includeExabyteTests = 0;
verbose = 0;
read_options(argc, argv, &buflen, &includeNegScale,
&includeExabyteTests, &verbose);
buf = malloc(buflen);
errcnt = 0;
tested = 0;
skipped = 0;
if (buflen != 4)
printf("Warning: buffer size %zu != 4, expect some results to differ.\n", buflen);
printf("1..%zu\n", nitems(test_args));
#ifdef __APPLE__
printf("[TEST] humanize_number_test\n");
#endif /* __APPLE__ */
for (i = 0; i < nitems(test_args); i++) {
#ifdef __APPLE__
printf("[BEGIN] test %zu\n", i + 1);
#endif /* __APPLE__ */
/* KLUDGE */
if (test_args[i].num == INT64_MAX && buflen == 4) {
/* Start final tests which require buffer of 6 */
free(buf);
buflen = 6;
buf = malloc(buflen);
if (verbose)
printf("Buffer length increased to %zu\n",
buflen);
}
if (test_args[i].scale < 0 && ! includeNegScale) {
skipped++;
testskipped(i + 1);
continue;
}
if (test_args[i].num >= halfExabyte && ! includeExabyteTests) {
skipped++;
testskipped(i + 1);
continue;
}
r = humanize_number(buf, buflen, test_args[i].num, "",
test_args[i].scale, test_args[i].flags);
flag_str = str_flags(test_args[i].flags, "[no flags]");
scale_str = str_scale(test_args[i].scale);
if (r != test_args[i].retval) {
if (verbose)
printf("wrong return value on index %zu, "
"buflen: %zu, got: %d + \"%s\", "
"expected %d + \"%s\"; num = %jd, "
"scale = %s, flags= %s.\n",
i, buflen, r, buf, test_args[i].retval,
test_args[i].res,
(intmax_t)test_args[i].num,
scale_str, flag_str);
else
printf("not ok %zu # return %d != %d\n",
i + 1, r, test_args[i].retval);
errcnt++;
#ifdef __APPLE__
printf("[FAIL] test %zu\n", i + 1);
#endif /* __APPLE__ */
} else if (strcmp(buf, test_args[i].res) != 0) {
if (verbose)
printf("result mismatch on index %zu, got: "
"\"%s\", expected \"%s\"; num = %jd, "
"scale = %s, flags= %s.\n",
i, buf, test_args[i].res,
(intmax_t)test_args[i].num,
scale_str, flag_str);
else
printf("not ok %zu # buf \"%s\" != \"%s\"\n",
i + 1, buf, test_args[i].res);
errcnt++;
#ifdef __APPLE__
printf("[FAIL] test %zu\n", i + 1);
#endif /* __APPLE__ */
} else {
if (verbose)
printf("successful result on index %zu, "
"returned %d, got: \"%s\"; num = %jd, "
"scale = %s, flags= %s.\n",
i, r, buf,
(intmax_t)test_args[i].num,
scale_str, flag_str);
else
printf("ok %zu\n", i + 1);
#ifdef __APPLE__
printf("[PASS] test %zu\n", i + 1);
#endif /* __APPLE__ */
}
tested++;
}
printf("[SUMMARY]\n");
if (verbose)
printf("total errors: %zu/%zu tests, %zu skipped\n", errcnt,
tested, skipped);
if (errcnt)
return 1;
return 0;
}

28
tests/libutil.plist Normal file
View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Project</key>
<string>libutil</string>
<key>Tests</key>
<array>
<dict>
<key>Command</key>
<array>
<string>/AppleInternal/Tests/libutil/humanize_number_test</string>
<string>-v</string>
<string>-n</string>
</array>
<key>TestName</key>
<string>humanize_number_test</string>
<key>WhenToRun</key>
<array>
<string>PRESUBMISSION</string>
<string>NIGHTLY</string>
</array>
</dict>
</array>
<key>Timeout</key>
<integer>30</integer>
</dict>
</plist>

View File

@ -7,5 +7,8 @@
(allow file-write-create file-write-unlink
(literal "/private/var/db/timezone/localtime"))
(allow file-write-create file-write-unlink
(literal "/private/etc/localtime"))
(allow file-read*
(literal "/private/var/db/timezone/zoneinfo"))

View File

@ -34,9 +34,89 @@ static int set_timezone(const char *);
static int build_source_path(char *, size_t, const char *);
static int validate_source_path(const char *);
#if TARGET_OS_OSX
#include <sandbox.h>
#include <dirhelper_priv.h>
#include <sysexits.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
#include <pwd.h>
static void
enter_sandbox(void)
{
char buf[PATH_MAX] = "";
char *home_env = getenv("HOME");
if (home_env == NULL) {
os_log_debug(OS_LOG_DEFAULT, "$HOME not set, falling back to using getpwuid");
struct passwd *pwd = getpwuid(getuid());
if (pwd == NULL) {
os_log_error(OS_LOG_DEFAULT, "failed to get passwd entry for uid %u", getuid());
exit(EXIT_FAILURE);
}
home_env = pwd->pw_dir;
}
char *home = realpath(home_env, NULL);
if (home == NULL) {
os_log_error(OS_LOG_DEFAULT, "failed to resolve user's home directory: %{darwin.errno}d", errno);
exit(EXIT_FAILURE);
}
if (!_set_user_dir_suffix("tzlinkd") ||
confstr(_CS_DARWIN_USER_TEMP_DIR, buf, sizeof(buf)) == 0) {
os_log_error(OS_LOG_DEFAULT, "failed to initialize temporary directory: %{darwin.errno}d", errno);
exit(EXIT_FAILURE);
}
char *tempdir = realpath(buf, NULL);
if (tempdir == NULL) {
os_log_error(OS_LOG_DEFAULT, "failed to resolve temporary directory: %{darwin.errno}d", errno);
exit(EXIT_FAILURE);
}
if (confstr(_CS_DARWIN_USER_CACHE_DIR, buf, sizeof(buf)) == 0) {
os_log_error(OS_LOG_DEFAULT, "failed to initialize cache directory: %{darwin.errno}d", errno);
exit(EXIT_FAILURE);
}
char *cachedir = realpath(buf, NULL);
if (cachedir == NULL) {
os_log_error(OS_LOG_DEFAULT, "failed to resolve cache directory: %{darwin.errno}d", errno);
exit(EXIT_FAILURE);
}
const char *parameters[] = {
"HOME", home,
"TMPDIR", tempdir,
"DARWIN_CACHE_DIR", cachedir,
NULL
};
char *sberror = NULL;
// Note: The name of the sandbox profile here does not include the '.sb' extension.
if (sandbox_init_with_parameters("com.apple.tzlinkd", SANDBOX_NAMED, parameters, &sberror) != 0) {
os_log_error(OS_LOG_DEFAULT, "Failed to enter sandbox: %{public}s", sberror);
exit(EXIT_FAILURE);
}
free(home);
free(tempdir);
free(cachedir);
free(sberror);
}
#endif /* TARGET_OS_OSX */
int
main(void)
{
#if TARGET_OS_OSX
enter_sandbox();
#endif /* TARGET_OS_OSX */
dispatch_queue_t queue;
xpc_connection_t listener;