|
|
|
|
@@ -42,6 +42,9 @@
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <limits.h>
|
|
|
|
|
#include <ctype.h>
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
#include <byteswap.h>
|
|
|
|
|
#include <endian.h>
|
|
|
|
|
|
|
|
|
|
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
|
|
|
|
|
|
|
|
|
|
@@ -66,6 +69,8 @@ static const char *argv0;
|
|
|
|
|
/* will be used by constructor tests */
|
|
|
|
|
static int constructor_test_value;
|
|
|
|
|
|
|
|
|
|
static const int is_le = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__;
|
|
|
|
|
|
|
|
|
|
static const int is_nolibc =
|
|
|
|
|
#ifdef NOLIBC
|
|
|
|
|
1
|
|
|
|
|
@@ -74,6 +79,30 @@ static const int is_nolibc =
|
|
|
|
|
#endif
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
static const int is_glibc =
|
|
|
|
|
#ifdef __GLIBC__
|
|
|
|
|
1
|
|
|
|
|
#else
|
|
|
|
|
0
|
|
|
|
|
#endif
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
#if !defined(NOLIBC)
|
|
|
|
|
/* Some disabled tests may not compile. */
|
|
|
|
|
|
|
|
|
|
/* strlcat() and strlcpy() may not be in the system headers. */
|
|
|
|
|
#undef strlcat
|
|
|
|
|
#undef strlcpy
|
|
|
|
|
#define strlcat(d, s, l) 0
|
|
|
|
|
#define strlcpy(d, s, l) 0
|
|
|
|
|
|
|
|
|
|
/* readdir_r() is likely to be marked deprecated */
|
|
|
|
|
#undef readdir_r
|
|
|
|
|
#define readdir_r(dir, dirent, result) ((errno = EINVAL), -1)
|
|
|
|
|
|
|
|
|
|
#define _syscall(...) 0
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* definition of a series of tests */
|
|
|
|
|
struct test {
|
|
|
|
|
const char *name; /* test name */
|
|
|
|
|
@@ -142,21 +171,6 @@ static const char *errorname(int err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void align_result(size_t llen)
|
|
|
|
|
{
|
|
|
|
|
const size_t align = 64;
|
|
|
|
|
char buf[align];
|
|
|
|
|
size_t n;
|
|
|
|
|
|
|
|
|
|
if (llen >= align)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
n = align - llen;
|
|
|
|
|
memset(buf, ' ', n);
|
|
|
|
|
buf[n] = '\0';
|
|
|
|
|
fputs(buf, stdout);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum RESULT {
|
|
|
|
|
OK,
|
|
|
|
|
FAIL,
|
|
|
|
|
@@ -174,8 +188,10 @@ static void result(int llen, enum RESULT r)
|
|
|
|
|
else
|
|
|
|
|
msg = " [FAIL]";
|
|
|
|
|
|
|
|
|
|
align_result(llen);
|
|
|
|
|
puts(msg);
|
|
|
|
|
llen = 64 - llen;
|
|
|
|
|
if (llen < 0)
|
|
|
|
|
llen = 0;
|
|
|
|
|
printf("%*s%s\n", llen, "", msg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* The tests below are intended to be used by the macroes, which evaluate
|
|
|
|
|
@@ -304,10 +320,7 @@ int expect_syszr(int expr, int llen)
|
|
|
|
|
{
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
|
|
if (errno == ENOSYS) {
|
|
|
|
|
llen += printf(" = ENOSYS");
|
|
|
|
|
result(llen, SKIPPED);
|
|
|
|
|
} else if (expr) {
|
|
|
|
|
if (expr) {
|
|
|
|
|
ret = 1;
|
|
|
|
|
llen += printf(" = %d %s ", expr, errorname(errno));
|
|
|
|
|
result(llen, FAIL);
|
|
|
|
|
@@ -347,10 +360,7 @@ int expect_sysne(int expr, int llen, int val)
|
|
|
|
|
{
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
|
|
if (errno == ENOSYS) {
|
|
|
|
|
llen += printf(" = ENOSYS");
|
|
|
|
|
result(llen, SKIPPED);
|
|
|
|
|
} else if (expr == val) {
|
|
|
|
|
if (expr == val) {
|
|
|
|
|
ret = 1;
|
|
|
|
|
llen += printf(" = %d %s ", expr, errorname(errno));
|
|
|
|
|
result(llen, FAIL);
|
|
|
|
|
@@ -375,9 +385,7 @@ int expect_syserr2(int expr, int expret, int experr1, int experr2, int llen)
|
|
|
|
|
int _errno = errno;
|
|
|
|
|
|
|
|
|
|
llen += printf(" = %d %s ", expr, errorname(_errno));
|
|
|
|
|
if (errno == ENOSYS) {
|
|
|
|
|
result(llen, SKIPPED);
|
|
|
|
|
} else if (expr != expret || (_errno != experr1 && _errno != experr2)) {
|
|
|
|
|
if (expr != expret || (_errno != experr1 && _errno != experr2)) {
|
|
|
|
|
ret = 1;
|
|
|
|
|
if (experr2 == 0)
|
|
|
|
|
llen += printf(" != (%d %s) ", expret, errorname(experr1));
|
|
|
|
|
@@ -701,6 +709,37 @@ static void constructor2(int argc, char **argv, char **envp)
|
|
|
|
|
constructor_test_value |= 1 << 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int test_program_invocation_name(void)
|
|
|
|
|
{
|
|
|
|
|
char buf[100];
|
|
|
|
|
char *dirsep;
|
|
|
|
|
ssize_t r;
|
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
|
|
fd = open("/proc/self/cmdline", O_RDONLY);
|
|
|
|
|
if (fd == -1)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
r = read(fd, buf, sizeof(buf));
|
|
|
|
|
close(fd);
|
|
|
|
|
if (r < 1 || r == sizeof(buf))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
buf[r - 1] = '\0';
|
|
|
|
|
|
|
|
|
|
if (strcmp(program_invocation_name, buf) != 0)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
dirsep = strrchr(buf, '/');
|
|
|
|
|
if (!dirsep || dirsep[1] == '\0')
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
if (strcmp(program_invocation_short_name, dirsep + 1) != 0)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int run_startup(int min, int max)
|
|
|
|
|
{
|
|
|
|
|
int test;
|
|
|
|
|
@@ -715,6 +754,7 @@ int run_startup(int min, int max)
|
|
|
|
|
#ifdef NOLIBC
|
|
|
|
|
test_auxv = _auxv;
|
|
|
|
|
#endif
|
|
|
|
|
bool proc = access("/proc", R_OK) == 0;
|
|
|
|
|
|
|
|
|
|
for (test = min; test >= 0 && test <= max; test++) {
|
|
|
|
|
int llen = 0; /* line length */
|
|
|
|
|
@@ -740,6 +780,7 @@ int run_startup(int min, int max)
|
|
|
|
|
CASE_TEST(constructor); EXPECT_EQ(is_nolibc, constructor_test_value, 0x3); break;
|
|
|
|
|
CASE_TEST(linkage_errno); EXPECT_PTREQ(1, linkage_test_errno_addr(), &errno); break;
|
|
|
|
|
CASE_TEST(linkage_constr); EXPECT_EQ(1, linkage_test_constructor_test_value, 0x3); break;
|
|
|
|
|
CASE_TEST(prog_name); EXPECT_ZR(proc, test_program_invocation_name()); break;
|
|
|
|
|
case __LINE__:
|
|
|
|
|
return ret; /* must be last */
|
|
|
|
|
/* note: do not set any defaults so as to permit holes above */
|
|
|
|
|
@@ -866,7 +907,7 @@ int test_file_stream(void)
|
|
|
|
|
|
|
|
|
|
errno = 0;
|
|
|
|
|
r = fwrite("foo", 1, 3, f);
|
|
|
|
|
if (r != 0 || errno != EBADF) {
|
|
|
|
|
if (r != 0 || ((is_nolibc || is_glibc) && errno != EBADF)) {
|
|
|
|
|
fclose(f);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
@@ -1408,7 +1449,7 @@ int run_syscall(int min, int max)
|
|
|
|
|
CASE_TEST(fork); EXPECT_SYSZR(1, test_fork(FORK_STANDARD)); break;
|
|
|
|
|
CASE_TEST(getdents64_root); EXPECT_SYSNE(1, test_getdents64("/"), -1); break;
|
|
|
|
|
CASE_TEST(getdents64_null); EXPECT_SYSER(1, test_getdents64("/dev/null"), -1, ENOTDIR); break;
|
|
|
|
|
CASE_TEST(directories); EXPECT_SYSZR(proc, test_dirent()); break;
|
|
|
|
|
CASE_TEST(directories); EXPECT_SYSZR(is_nolibc && proc, test_dirent()); break;
|
|
|
|
|
CASE_TEST(getrandom); EXPECT_SYSZR(1, test_getrandom()); break;
|
|
|
|
|
CASE_TEST(gettimeofday_tv); EXPECT_SYSZR(1, gettimeofday(&tv, NULL)); break;
|
|
|
|
|
CASE_TEST(gettimeofday_tv_tz);EXPECT_SYSZR(1, gettimeofday(&tv, &tz)); break;
|
|
|
|
|
@@ -1442,6 +1483,7 @@ int run_syscall(int min, int max)
|
|
|
|
|
CASE_TEST(select_fault); EXPECT_SYSER(1, select(1, (void *)1, NULL, NULL, 0), -1, EFAULT); break;
|
|
|
|
|
CASE_TEST(stat_blah); EXPECT_SYSER(1, stat("/proc/self/blah", &stat_buf), -1, ENOENT); break;
|
|
|
|
|
CASE_TEST(stat_fault); EXPECT_SYSER(1, stat(NULL, &stat_buf), -1, EFAULT); break;
|
|
|
|
|
CASE_TEST(stat_rdev); EXPECT_SYSZR(1, ({ int ret = stat("/dev/null", &stat_buf); ret ?: stat_buf.st_rdev != makedev(1, 3); })); break;
|
|
|
|
|
CASE_TEST(stat_timestamps); EXPECT_SYSZR(1, test_stat_timestamps()); break;
|
|
|
|
|
CASE_TEST(symlink_root); EXPECT_SYSER(1, symlink("/", "/"), -1, EEXIST); break;
|
|
|
|
|
CASE_TEST(timer); EXPECT_SYSZR(1, test_timer()); break;
|
|
|
|
|
@@ -1460,9 +1502,11 @@ int run_syscall(int min, int max)
|
|
|
|
|
CASE_TEST(readv_zero); EXPECT_SYSZR(1, readv(0, NULL, 0)); break;
|
|
|
|
|
CASE_TEST(writev_badf); EXPECT_SYSER(1, writev(-1, &iov_one, 1), -1, EBADF); break;
|
|
|
|
|
CASE_TEST(writev_zero); EXPECT_SYSZR(1, writev(1, NULL, 0)); break;
|
|
|
|
|
CASE_TEST(ptrace); EXPECT_SYSER(1, ptrace(PTRACE_CONT, getpid(), NULL, NULL), -1, ESRCH); break;
|
|
|
|
|
CASE_TEST(ptrace); tmp = ptrace(PTRACE_CONT, getpid(), NULL, NULL); EXPECT_SYSER(tmp != -1 && errno != ENOSYS, tmp, -1, EFAULT); break;
|
|
|
|
|
CASE_TEST(syscall_noargs); EXPECT_SYSEQ(1, syscall(__NR_getpid), getpid()); break;
|
|
|
|
|
CASE_TEST(syscall_args); EXPECT_SYSER(1, syscall(__NR_statx, 0, NULL, 0, 0, NULL), -1, EFAULT); break;
|
|
|
|
|
CASE_TEST(_syscall_noargs); EXPECT_SYSEQ(is_nolibc, _syscall(__NR_getpid), getpid()); break;
|
|
|
|
|
CASE_TEST(_syscall_args); EXPECT_SYSEQ(is_nolibc, _syscall(__NR_statx, 0, NULL, 0, 0, NULL), -EFAULT); break;
|
|
|
|
|
CASE_TEST(namespace); EXPECT_SYSZR(euid0 && proc, test_namespace()); break;
|
|
|
|
|
case __LINE__:
|
|
|
|
|
return ret; /* must be last */
|
|
|
|
|
@@ -1511,6 +1555,60 @@ int test_time_types(void)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int test_malloc(void)
|
|
|
|
|
{
|
|
|
|
|
size_t sz_array1, sz_array2, sz_array3;
|
|
|
|
|
int *array1, *array2, *array3;
|
|
|
|
|
int pagesize = getpagesize();
|
|
|
|
|
size_t idx;
|
|
|
|
|
|
|
|
|
|
if (pagesize < 0)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
/* Dependent on the page size, as that is the granularity of our allocator. */
|
|
|
|
|
sz_array1 = pagesize / 2;
|
|
|
|
|
array1 = malloc(sz_array1 * sizeof(*array1));
|
|
|
|
|
if (!array1)
|
|
|
|
|
return 2;
|
|
|
|
|
|
|
|
|
|
for (idx = 0; idx < sz_array1; idx++)
|
|
|
|
|
array1[idx] = idx;
|
|
|
|
|
|
|
|
|
|
sz_array2 = pagesize * 2;
|
|
|
|
|
array2 = calloc(sz_array2, sizeof(*array2));
|
|
|
|
|
if (!array2) {
|
|
|
|
|
free(array1);
|
|
|
|
|
return 3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (idx = 0; idx < sz_array2; idx++) {
|
|
|
|
|
if (array2[idx] != 0) {
|
|
|
|
|
free(array2);
|
|
|
|
|
return 4;
|
|
|
|
|
}
|
|
|
|
|
array2[idx] = idx + sz_array1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Resize array1 into array3 and append array2 at the end. */
|
|
|
|
|
sz_array3 = sz_array1 + sz_array2;
|
|
|
|
|
array3 = realloc(array1, sz_array3 * sizeof(*array3));
|
|
|
|
|
if (!array3) {
|
|
|
|
|
free(array2);
|
|
|
|
|
free(array1);
|
|
|
|
|
return 5;
|
|
|
|
|
}
|
|
|
|
|
memcpy(array3 + sz_array1, array2, sizeof(*array2) * sz_array2);
|
|
|
|
|
free(array2);
|
|
|
|
|
|
|
|
|
|
/* The contents must be contiguous now. */
|
|
|
|
|
for (idx = 0; idx < sz_array3; idx++)
|
|
|
|
|
if (array3[idx] != (int)idx)
|
|
|
|
|
return 6;
|
|
|
|
|
|
|
|
|
|
free(array3);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int run_stdlib(int min, int max)
|
|
|
|
|
{
|
|
|
|
|
int test;
|
|
|
|
|
@@ -1637,6 +1735,22 @@ int run_stdlib(int min, int max)
|
|
|
|
|
CASE_TEST(memchr_foobar6_o); EXPECT_STREQ(1, memchr("foobar", 'o', 6), "oobar"); break;
|
|
|
|
|
CASE_TEST(memchr_foobar3_b); EXPECT_STRZR(1, memchr("foobar", 'b', 3)); break;
|
|
|
|
|
CASE_TEST(time_types); EXPECT_ZR(is_nolibc, test_time_types()); break;
|
|
|
|
|
CASE_TEST(makedev); EXPECT_EQ(1, makedev(0x12, 0x34), 0x1234); break;
|
|
|
|
|
CASE_TEST(major); EXPECT_EQ(1, major(0x1234), 0x12); break;
|
|
|
|
|
CASE_TEST(minor); EXPECT_EQ(1, minor(0x1234), 0x34); break;
|
|
|
|
|
CASE_TEST(makedev_big); EXPECT_EQ(1, makedev(0x11223344, 0x55667788), 0x1122355667734488); break;
|
|
|
|
|
CASE_TEST(major_big); EXPECT_EQ(1, major(0x1122355667734488), 0x11223344); break;
|
|
|
|
|
CASE_TEST(minor_big); EXPECT_EQ(1, minor(0x1122355667734488), 0x55667788); break;
|
|
|
|
|
CASE_TEST(malloc); EXPECT_ZR(1, test_malloc()); break;
|
|
|
|
|
CASE_TEST(bswap_16); EXPECT_EQ(1, bswap_16(0x0123), 0x2301); break;
|
|
|
|
|
CASE_TEST(bswap_32); EXPECT_EQ(1, bswap_32(0x01234567), 0x67452301); break;
|
|
|
|
|
CASE_TEST(bswap_64); EXPECT_EQ(1, bswap_64(0x0123456789abcdef), 0xefcdab8967452301); break;
|
|
|
|
|
CASE_TEST(htobe16); EXPECT_EQ(1, htobe16(is_le ? 0x0123 : 0x2301), 0x2301); break;
|
|
|
|
|
CASE_TEST(htole16); EXPECT_EQ(1, htole16(is_le ? 0x0123 : 0x2301), 0x0123); break;
|
|
|
|
|
CASE_TEST(htobe32); EXPECT_EQ(1, htobe32(is_le ? 0x01234567 : 0x67452301), 0x67452301); break;
|
|
|
|
|
CASE_TEST(htole32); EXPECT_EQ(1, htole32(is_le ? 0x01234567 : 0x67452301), 0x01234567); break;
|
|
|
|
|
CASE_TEST(htobe64); EXPECT_EQ(1, htobe64(is_le ? 0x0123456789000000 : 0x8967452301), 0x8967452301); break;
|
|
|
|
|
CASE_TEST(htole64); EXPECT_EQ(1, htole64(is_le ? 0x0123456789 : 0x8967452301000000), 0x0123456789); break;
|
|
|
|
|
|
|
|
|
|
case __LINE__:
|
|
|
|
|
return ret; /* must be last */
|
|
|
|
|
@@ -1646,33 +1760,60 @@ int run_stdlib(int min, int max)
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define EXPECT_VFPRINTF(c, expected, fmt, ...) \
|
|
|
|
|
ret += expect_vfprintf(llen, c, expected, fmt, ##__VA_ARGS__)
|
|
|
|
|
#define EXPECT_VFPRINTF(cond, expected, fmt, ...) \
|
|
|
|
|
do { if (!(cond)) result(llen, SKIPPED); else ret += expect_vfprintf(llen, expected, fmt, ##__VA_ARGS__); } while (0)
|
|
|
|
|
|
|
|
|
|
static int expect_vfprintf(int llen, int c, const char *expected, const char *fmt, ...)
|
|
|
|
|
#define VFPRINTF_LEN 25
|
|
|
|
|
static int expect_vfprintf(int llen, const char *expected, const char *fmt, ...)
|
|
|
|
|
{
|
|
|
|
|
char buf[100];
|
|
|
|
|
char buf[VFPRINTF_LEN + 80];
|
|
|
|
|
unsigned int cmp_len;
|
|
|
|
|
va_list args;
|
|
|
|
|
ssize_t w;
|
|
|
|
|
int ret;
|
|
|
|
|
ssize_t written, expected_len;
|
|
|
|
|
|
|
|
|
|
/* Fill and terminate buf[] to check for overlong/absent writes */
|
|
|
|
|
memset(buf, 0xa5, sizeof(buf) - 1);
|
|
|
|
|
buf[sizeof(buf) - 1] = 0;
|
|
|
|
|
|
|
|
|
|
va_start(args, fmt);
|
|
|
|
|
/* Only allow writing 21 bytes, to test truncation */
|
|
|
|
|
w = vsnprintf(buf, 21, fmt, args);
|
|
|
|
|
/* Limit buffer length to test truncation */
|
|
|
|
|
written = vsnprintf(buf, VFPRINTF_LEN + 1, fmt, args);
|
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
|
|
if (w != c) {
|
|
|
|
|
llen += printf(" written(%d) != %d", (int)w, c);
|
|
|
|
|
llen += printf(" \"%s\"", buf);
|
|
|
|
|
|
|
|
|
|
expected_len = strlen(expected);
|
|
|
|
|
if (expected_len > VFPRINTF_LEN) {
|
|
|
|
|
/* Indicate truncated in test output */
|
|
|
|
|
llen += printf("+");
|
|
|
|
|
cmp_len = VFPRINTF_LEN;
|
|
|
|
|
} else {
|
|
|
|
|
cmp_len = expected_len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (memcmp(expected, buf, cmp_len) || buf[cmp_len]) {
|
|
|
|
|
llen += printf(" should be \"%.*s\"", VFPRINTF_LEN, expected);
|
|
|
|
|
result(llen, FAIL);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llen += printf(" \"%s\" = \"%s\"", expected, buf);
|
|
|
|
|
ret = strncmp(expected, buf, c);
|
|
|
|
|
if (written != expected_len) {
|
|
|
|
|
llen += printf(" written(%d) != %d", (int)written, (int)expected_len);
|
|
|
|
|
result(llen, FAIL);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result(llen, ret ? FAIL : OK);
|
|
|
|
|
return ret;
|
|
|
|
|
/* Check for any overwrites after the actual data. */
|
|
|
|
|
while (++cmp_len < sizeof(buf) - 1) {
|
|
|
|
|
if ((unsigned char)buf[cmp_len] != 0xa5) {
|
|
|
|
|
llen += printf(" overwrote buf[%d] with 0x%x", cmp_len, buf[cmp_len]);
|
|
|
|
|
result(llen, FAIL);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result(llen, OK);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int test_scanf(void)
|
|
|
|
|
@@ -1742,23 +1883,6 @@ static int test_scanf(void)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int test_strerror(void)
|
|
|
|
|
{
|
|
|
|
|
char buf[100];
|
|
|
|
|
ssize_t ret;
|
|
|
|
|
|
|
|
|
|
memset(buf, 'A', sizeof(buf));
|
|
|
|
|
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
ret = snprintf(buf, sizeof(buf), "%m");
|
|
|
|
|
if (is_nolibc) {
|
|
|
|
|
if (ret < 6 || memcmp(buf, "errno=", 6))
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int test_printf_error(void)
|
|
|
|
|
{
|
|
|
|
|
int fd, ret, saved_errno;
|
|
|
|
|
@@ -1781,6 +1905,29 @@ static int test_printf_error(void)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int test_asprintf(void)
|
|
|
|
|
{
|
|
|
|
|
char *str;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
ret = asprintf(&str, "foo%s", "bar");
|
|
|
|
|
if (ret == -1)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
if (ret != 6) {
|
|
|
|
|
free(str);
|
|
|
|
|
return 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (memcmp(str, "foobar", 6) != 0) {
|
|
|
|
|
free(str);
|
|
|
|
|
return 3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(str);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int run_printf(int min, int max)
|
|
|
|
|
{
|
|
|
|
|
int test;
|
|
|
|
|
@@ -1793,24 +1940,58 @@ static int run_printf(int min, int max)
|
|
|
|
|
* test numbers.
|
|
|
|
|
*/
|
|
|
|
|
switch (test + __LINE__ + 1) {
|
|
|
|
|
CASE_TEST(empty); EXPECT_VFPRINTF(0, "", ""); break;
|
|
|
|
|
CASE_TEST(simple); EXPECT_VFPRINTF(3, "foo", "foo"); break;
|
|
|
|
|
CASE_TEST(string); EXPECT_VFPRINTF(3, "foo", "%s", "foo"); break;
|
|
|
|
|
CASE_TEST(number); EXPECT_VFPRINTF(4, "1234", "%d", 1234); break;
|
|
|
|
|
CASE_TEST(negnumber); EXPECT_VFPRINTF(5, "-1234", "%d", -1234); break;
|
|
|
|
|
CASE_TEST(unsigned); EXPECT_VFPRINTF(5, "12345", "%u", 12345); break;
|
|
|
|
|
CASE_TEST(char); EXPECT_VFPRINTF(1, "c", "%c", 'c'); break;
|
|
|
|
|
CASE_TEST(hex); EXPECT_VFPRINTF(1, "f", "%x", 0xf); break;
|
|
|
|
|
CASE_TEST(pointer); EXPECT_VFPRINTF(3, "0x1", "%p", (void *) 0x1); break;
|
|
|
|
|
CASE_TEST(uintmax_t); EXPECT_VFPRINTF(20, "18446744073709551615", "%ju", 0xffffffffffffffffULL); break;
|
|
|
|
|
CASE_TEST(intmax_t); EXPECT_VFPRINTF(20, "-9223372036854775807", "%jd", 0x8000000000000001LL); break;
|
|
|
|
|
CASE_TEST(truncation); EXPECT_VFPRINTF(25, "01234567890123456789", "%s", "0123456789012345678901234"); break;
|
|
|
|
|
CASE_TEST(string_width); EXPECT_VFPRINTF(10, " 1", "%10s", "1"); break;
|
|
|
|
|
CASE_TEST(number_width); EXPECT_VFPRINTF(10, " 1", "%10d", 1); break;
|
|
|
|
|
CASE_TEST(width_trunc); EXPECT_VFPRINTF(25, " ", "%25d", 1); break;
|
|
|
|
|
CASE_TEST(empty); EXPECT_VFPRINTF(1, "", ""); break;
|
|
|
|
|
CASE_TEST(simple); EXPECT_VFPRINTF(1, "foo", "foo"); break;
|
|
|
|
|
CASE_TEST(string); EXPECT_VFPRINTF(1, "foo", "%s", "foo"); break;
|
|
|
|
|
CASE_TEST(number); EXPECT_VFPRINTF(1, "1234", "%d", 1234); break;
|
|
|
|
|
CASE_TEST(negnumber); EXPECT_VFPRINTF(1, "-1234", "%d", -1234); break;
|
|
|
|
|
CASE_TEST(num_sign); EXPECT_VFPRINTF(1, "| 1|+2|+3|+4|5|", "|% d|%+d|% +d|%+ d|%#d|", 1, 2, 3, 4, 5); break;
|
|
|
|
|
CASE_TEST(unsigned); EXPECT_VFPRINTF(1, "12345", "%u", 12345); break;
|
|
|
|
|
CASE_TEST(signed_max); EXPECT_VFPRINTF(1, "2147483647", "%i", ~0u >> 1); break;
|
|
|
|
|
CASE_TEST(signed_min); EXPECT_VFPRINTF(1, "-2147483648", "%i", (~0u >> 1) + 1); break;
|
|
|
|
|
CASE_TEST(unsigned_max); EXPECT_VFPRINTF(1, "4294967295", "%u", ~0u); break;
|
|
|
|
|
CASE_TEST(char); EXPECT_VFPRINTF(1, "|c|d| e|", "|%c|%.0c|%4c|", 'c', 'd', 'e'); break;
|
|
|
|
|
CASE_TEST(octal); EXPECT_VFPRINTF(1, "|17| 0033||", "|%o|%6.4o|%.0o|", 017, 033, 0); break;
|
|
|
|
|
CASE_TEST(octal_max); EXPECT_VFPRINTF(1, "1777777777777777777777", "%llo", ~0ULL); break;
|
|
|
|
|
CASE_TEST(octal_alt); EXPECT_VFPRINTF(1, "|0|01|02|034|0|0|", "|%#o|%#o|%#02o|%#02o|%#.0o|%0-#o|", 0, 1, 2, 034, 0, 0); break;
|
|
|
|
|
CASE_TEST(hex_nolibc); EXPECT_VFPRINTF(is_nolibc, "|f|d|", "|%x|%X|", 0xf, 0xd); break;
|
|
|
|
|
CASE_TEST(hex_libc); EXPECT_VFPRINTF(!is_nolibc, "|f|D|", "|%x|%X|", 0xf, 0xd); break;
|
|
|
|
|
CASE_TEST(hex_alt); EXPECT_VFPRINTF(1, "|0x1| 0x2| 0|", "|%#x|%#5x|%#5x|", 1, 2, 0); break;
|
|
|
|
|
CASE_TEST(hex_alt_prec); EXPECT_VFPRINTF(1, "| 0x02|0x03| 0x123|", "|%#5.2x|%#04x|%#6.2x|", 2, 3, 0x123); break;
|
|
|
|
|
CASE_TEST(hex_0_alt); EXPECT_VFPRINTF(1, "|0|0000| 00|", "|%#x|%#04x|%#5.2x|", 0, 0, 0); break;
|
|
|
|
|
CASE_TEST(pointer); EXPECT_VFPRINTF(1, "0x1", "%p", (void *) 0x1); break;
|
|
|
|
|
CASE_TEST(pointer_NULL); EXPECT_VFPRINTF(is_nolibc || is_glibc, "|(nil)|(nil)|", "|%p|%.4p|", (void *)0, (void *)0); break;
|
|
|
|
|
CASE_TEST(string_NULL); EXPECT_VFPRINTF(is_nolibc || is_glibc, "|(null)||(null)|", "|%s|%.5s|%.6s|", (void *)0, (void *)0, (void *)0); break;
|
|
|
|
|
CASE_TEST(percent); EXPECT_VFPRINTF(1, "a%d42%69%", "a%%d%d%%%d%%", 42, 69); break;
|
|
|
|
|
CASE_TEST(perc_qual); EXPECT_VFPRINTF(is_nolibc || is_glibc, "a%d2", "a%-14l%d%d", 2); break;
|
|
|
|
|
CASE_TEST(invalid); EXPECT_VFPRINTF(is_nolibc || is_glibc, "a%12yx3%y42%P", "a%12yx%d%y%d%P", 3, 42); break;
|
|
|
|
|
CASE_TEST(intmax_max); EXPECT_VFPRINTF(1, "9223372036854775807", "%lld", ~0ULL >> 1); break;
|
|
|
|
|
CASE_TEST(intmax_min); EXPECT_VFPRINTF(is_nolibc || is_glibc, "-9223372036854775808", "%Li", (~0ULL >> 1) + 1); break;
|
|
|
|
|
CASE_TEST(uintmax_max); EXPECT_VFPRINTF(1, "18446744073709551615", "%ju", ~0ULL); break;
|
|
|
|
|
CASE_TEST(truncation); EXPECT_VFPRINTF(1, "012345678901234567890123456789", "%s", "012345678901234567890123456789"); break;
|
|
|
|
|
CASE_TEST(string_width); EXPECT_VFPRINTF(1, " 1", "%10s", "1"); break;
|
|
|
|
|
CASE_TEST(string_trunc); EXPECT_VFPRINTF(1, " 12345", "%10.5s", "1234567890"); break;
|
|
|
|
|
CASE_TEST(string_var); EXPECT_VFPRINTF(1, "| ab|ef | ij|kl |", "|%*.*s|%*.*s|%*.*s|%*.*s|", 3, 2, "abcd", -3, 2, "efgh", 3, -1, "ij", -3, -1, "kl"); break;
|
|
|
|
|
CASE_TEST(number_width); EXPECT_VFPRINTF(1, " 1", "%10d", 1); break;
|
|
|
|
|
CASE_TEST(number_left); EXPECT_VFPRINTF(1, "|-5 |", "|%-8d|", -5); break;
|
|
|
|
|
CASE_TEST(string_align); EXPECT_VFPRINTF(1, "|foo |", "|%-8s|", "foo"); break;
|
|
|
|
|
CASE_TEST(width_trunc); EXPECT_VFPRINTF(1, " 1", "%30d", 1); break;
|
|
|
|
|
CASE_TEST(width_tr_lft); EXPECT_VFPRINTF(1, "1 ", "%-30d", 1); break;
|
|
|
|
|
CASE_TEST(number_pad); EXPECT_VFPRINTF(1, "0000000005", "%010d", 5); break;
|
|
|
|
|
CASE_TEST(number_pad); EXPECT_VFPRINTF(1, "|0000000005|0x1234|", "|%010d|%#01x|", 5, 0x1234); break;
|
|
|
|
|
CASE_TEST(num_pad_neg); EXPECT_VFPRINTF(1, "-000000005", "%010d", -5); break;
|
|
|
|
|
CASE_TEST(num_pad_hex); EXPECT_VFPRINTF(1, "00fffffffb", "%010x", -5); break;
|
|
|
|
|
CASE_TEST(num_pad_trunc);EXPECT_VFPRINTF(is_nolibc, " 0000000000000000000000000000005", "%035d", 5); break; /* max 31 '0' can be added */
|
|
|
|
|
CASE_TEST(num_p_tr_libc);EXPECT_VFPRINTF(!is_nolibc, "00000000000000000000000000000000005", "%035d", 5); break;
|
|
|
|
|
CASE_TEST(number_prec); EXPECT_VFPRINTF(1, " 00005", "%10.5d", 5); break;
|
|
|
|
|
CASE_TEST(num_prec_neg); EXPECT_VFPRINTF(1, " -00005", "%10.5d", -5); break;
|
|
|
|
|
CASE_TEST(number_var); EXPECT_VFPRINTF(1, "| -00005|5 |", "|%*.*d|%*.*d|", 10, 5, -5, -2, -10, 5); break;
|
|
|
|
|
CASE_TEST(num_0_prec_0); EXPECT_VFPRINTF(1, "|| |+||||", "|%.0d|% .0d|%+.0d|%.0u|%.0x|%#.0x|", 0, 0, 0, 0, 0, 0); break;
|
|
|
|
|
CASE_TEST(errno); errno = 22; EXPECT_VFPRINTF(is_nolibc, "errno=22", "%m"); break;
|
|
|
|
|
CASE_TEST(errno-neg); errno = -22; EXPECT_VFPRINTF(is_nolibc, "errno=-22 ", "%-12m"); break;
|
|
|
|
|
CASE_TEST(scanf); EXPECT_ZR(1, test_scanf()); break;
|
|
|
|
|
CASE_TEST(strerror); EXPECT_ZR(1, test_strerror()); break;
|
|
|
|
|
CASE_TEST(printf_error); EXPECT_ZR(1, test_printf_error()); break;
|
|
|
|
|
CASE_TEST(asprintf); EXPECT_ZR(1, test_asprintf()); break;
|
|
|
|
|
case __LINE__:
|
|
|
|
|
return ret; /* must be last */
|
|
|
|
|
/* note: do not set any defaults so as to permit holes above */
|
|
|
|
|
|