diff options
-rw-r--r-- | regress/lib/libc/mkstemp/mkstemp_test.c | 113 |
1 files changed, 87 insertions, 26 deletions
diff --git a/regress/lib/libc/mkstemp/mkstemp_test.c b/regress/lib/libc/mkstemp/mkstemp_test.c index d8311cbf351..fd133d83689 100644 --- a/regress/lib/libc/mkstemp/mkstemp_test.c +++ b/regress/lib/libc/mkstemp/mkstemp_test.c @@ -3,8 +3,9 @@ * * Public domain. * - * Verify that mkstemp() doesn't overrun or underrun the template buffer - * and that it can generate names that don't contain any X's + * Verify that mkstemp() and mkstemps() doesn't overrun or underrun + * the template buffer and that it can generate names that don't + * contain any X's */ #include <sys/param.h> @@ -20,12 +21,48 @@ #define MAX_TEMPLATE_LEN 10 #define MAX_TRIES 100 +#define SUFFIX ".suff" +#define SLEN (sizeof SUFFIX - 1) + long pg; -void -try(char *p, const char *prefix, int len) +/* + * verify that a path generated by mkstemp() or mkstemp() looks like a + * reasonable expansion of the template and matches the fd. Returns true + * if all the X's were replaced with non-X's + */ +int +check(int fd, char const *path, char const *prefix, size_t plen, + char const *suffix, size_t slen, int tlen) { struct stat sb, fsb; + char const *p; + + if (fd < 0) + err(1, "mkstemp"); + if (stat(path, &sb)) + err(1, "stat(%s)", path); + if (fstat(fd, &fsb)) + err(1, "fstat(%d==%s)", fd, path); + if (sb.st_dev != fsb.st_dev || sb.st_ino != fsb.st_ino) + errx(1, "stat mismatch"); + close(fd); + if (memcmp(path, prefix, plen) != 0) + errx(1, "prefix changed! %s vs %s", prefix, path); + if (memcmp(path + plen + tlen, suffix, slen + 1) != 0) + errx(1, "suffix changed! %s vs %s", suffix, path); + for (p = path + plen; p < path + plen + tlen; p++) + if (*p == '\0') + errx(1, "unexpected truncation"); + else if (*p == 'X') + return 0; + return 1; +} + + +void +try_mkstemp(char *p, char const *prefix, int len) +{ char *q; size_t plen = strlen(prefix); int tries, fd; @@ -35,24 +72,27 @@ try(char *p, const char *prefix, int len) memset(p + plen, 'X', len); p[plen + len] = '\0'; fd = mkstemp(p); - if (fd < 0) - err(1, "mkstemp"); - if (stat(p, &sb)) - err(1, "stat(%s)", p); - if (fstat(fd, &fsb)) - err(1, "fstat(%d==%s)", fd, p); - if (sb.st_dev != fsb.st_dev || sb.st_ino != fsb.st_ino) - errx(1, "stat mismatch"); - close(fd); - for (q = p + plen; *q != 'X'; q++) { - if (*q == '\0') { - if (q != p + plen + len) - errx(1, "unexpected truncation"); - return; - } - } - if (q >= p + plen + len) - errx(1, "overrun?"); + if (check(fd, p, prefix, plen, "", 0, len)) + return; + } + errx(1, "exceeded MAX_TRIES"); +} + +void +try_mkstemps(char *p, char const *prefix, int len, char const *suffix) +{ + char *q; + size_t plen = strlen(prefix); + size_t slen = strlen(suffix); + int tries, fd; + + for (tries = 0; tries < MAX_TRIES; tries++) { + memcpy(p, prefix, plen); + memset(p + plen, 'X', len); + memcpy(p + plen + len, suffix, slen + 1); + fd = mkstemps(p, slen); + if (check(fd, p, prefix, plen, suffix, slen, len)) + return; } errx(1, "exceeded MAX_TRIES"); } @@ -82,13 +122,34 @@ main(void) i = MAX_TEMPLATE_LEN + 1; while (i-- > 1) { /* try first at the start of a page, no prefix */ - try(p, "", i); + try_mkstemp(p, "", i); /* now at the end of the page, no prefix */ - try(p + pg - i - 1, "", i); + try_mkstemp(p + pg - i - 1, "", i); /* start of the page, prefixed with the cwd */ - try(p, cwd, i); + try_mkstemp(p, cwd, i); /* how about at the end of the page, prefixed with cwd? */ - try(p + pg - i - 1 - clen, cwd, i); + try_mkstemp(p + pg - clen - i - 1, cwd, i); + + /* again, with mkstemps() and an empty suffix */ + /* try first at the start of a page, no prefix */ + try_mkstemps(p, "", i, ""); + /* now at the end of the page, no prefix */ + try_mkstemps(p + pg - i - 1, "", i, ""); + /* start of the page, prefixed with the cwd */ + try_mkstemps(p, cwd, i, ""); + /* how about at the end of the page, prefixed with cwd? */ + try_mkstemps(p + pg - clen - i - 1, cwd, i, ""); + + /* mkstemps() and a non-empty suffix */ + /* try first at the start of a page, no prefix */ + try_mkstemps(p, "", i, SUFFIX); + /* now at the end of the page, no prefix */ + try_mkstemps(p + pg - i - SLEN - 1, "", i, SUFFIX); + /* start of the page, prefixed with the cwd */ + try_mkstemps(p, cwd, i, SUFFIX); + /* how about at the end of the page, prefixed with cwd? */ + try_mkstemps(p + pg - clen - i - SLEN - 1, cwd, i, SUFFIX); + } return 0; |