summaryrefslogtreecommitdiff
path: root/src/regress/lib/libc/mkstemp/mkstemp_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/regress/lib/libc/mkstemp/mkstemp_test.c')
-rw-r--r--src/regress/lib/libc/mkstemp/mkstemp_test.c165
1 files changed, 165 insertions, 0 deletions
diff --git a/src/regress/lib/libc/mkstemp/mkstemp_test.c b/src/regress/lib/libc/mkstemp/mkstemp_test.c
new file mode 100644
index 0000000000..ef973b061b
--- /dev/null
+++ b/src/regress/lib/libc/mkstemp/mkstemp_test.c
@@ -0,0 +1,165 @@
1/*
2 * Copyright (c) 2010 Philip Guenther <guenther@openbsd.org>
3 *
4 * Public domain.
5 *
6 * Verify that mkstemp() and mkstemps() doesn't overrun or underrun
7 * the template buffer and that it can generate names that don't
8 * contain any X's
9 */
10
11#include <sys/param.h>
12#include <sys/mman.h>
13#include <sys/stat.h>
14
15#include <err.h>
16#include <errno.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <unistd.h>
21
22#define MAX_TEMPLATE_LEN 10
23#define MAX_TRIES 100
24#define MIN_Xs 6
25
26#define SUFFIX ".suff"
27#define SLEN (sizeof SUFFIX - 1)
28
29long pg;
30
31/*
32 * verify that a path generated by mkstemp() or mkstemp() looks like a
33 * reasonable expansion of the template and matches the fd. Returns true
34 * if all the X's were replaced with non-X's
35 */
36int
37check(int fd, char const *path, char const *prefix, size_t plen,
38 char const *suffix, size_t slen, int tlen)
39{
40 struct stat sb, fsb;
41 char const *p;
42
43 if (tlen < MIN_Xs) {
44 if (fd >= 0)
45 errx(1, "mkstemp(%s) succeed with too few Xs", path);
46 if (errno != EINVAL)
47 err(1, "mkstemp(%s) failed with wrong errno", path);
48 return 1;
49 }
50 if (fd < 0)
51 err(1, "mkstemp(%s)", path);
52 if (stat(path, &sb))
53 err(1, "stat(%s)", path);
54 if (fstat(fd, &fsb))
55 err(1, "fstat(%d==%s)", fd, path);
56 if (sb.st_dev != fsb.st_dev || sb.st_ino != fsb.st_ino)
57 errx(1, "stat mismatch");
58 close(fd);
59 if (memcmp(path, prefix, plen) != 0)
60 errx(1, "prefix changed! %s vs %s", prefix, path);
61 if (memcmp(path + plen + tlen, suffix, slen + 1) != 0)
62 errx(1, "suffix changed! %s vs %s", suffix, path);
63 for (p = path + plen; p < path + plen + tlen; p++)
64 if (*p == '\0')
65 errx(1, "unexpected truncation");
66 else if (*p == 'X')
67 return 0;
68 return 1;
69}
70
71
72void
73try_mkstemp(char *p, char const *prefix, int len)
74{
75 char *q;
76 size_t plen = strlen(prefix);
77 int tries, fd;
78
79 for (tries = 0; tries < MAX_TRIES; tries++) {
80 memcpy(p, prefix, plen);
81 memset(p + plen, 'X', len);
82 p[plen + len] = '\0';
83 fd = mkstemp(p);
84 if (check(fd, p, prefix, plen, "", 0, len))
85 return;
86 }
87 errx(1, "exceeded MAX_TRIES");
88}
89
90void
91try_mkstemps(char *p, char const *prefix, int len, char const *suffix)
92{
93 char *q;
94 size_t plen = strlen(prefix);
95 size_t slen = strlen(suffix);
96 int tries, fd;
97
98 for (tries = 0; tries < MAX_TRIES; tries++) {
99 memcpy(p, prefix, plen);
100 memset(p + plen, 'X', len);
101 memcpy(p + plen + len, suffix, slen + 1);
102 fd = mkstemps(p, slen);
103 if (check(fd, p, prefix, plen, suffix, slen, len))
104 return;
105 }
106 errx(1, "exceeded MAX_TRIES");
107}
108
109int
110main(void)
111{
112 struct stat sb, fsb;
113 char cwd[MAXPATHLEN + 1];
114 char *p;
115 size_t clen;
116 int i;
117
118 pg = sysconf(_SC_PAGESIZE);
119 if (getcwd(cwd, sizeof cwd - 1) == NULL)
120 err(1, "getcwd");
121 clen = strlen(cwd);
122 cwd[clen++] = '/';
123 cwd[clen] = '\0';
124 p = mmap(NULL, pg * 3, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0);
125 if (p == NULL)
126 err(1, "mmap");
127 if (mprotect(p, pg, PROT_NONE) || mprotect(p + pg * 2, pg, PROT_NONE))
128 err(1, "mprotect");
129 p += pg;
130
131 i = MAX_TEMPLATE_LEN + 1;
132 while (i-- > 0) {
133 /* try first at the start of a page, no prefix */
134 try_mkstemp(p, "", i);
135 /* now at the end of the page, no prefix */
136 try_mkstemp(p + pg - i - 1, "", i);
137 /* start of the page, prefixed with the cwd */
138 try_mkstemp(p, cwd, i);
139 /* how about at the end of the page, prefixed with cwd? */
140 try_mkstemp(p + pg - clen - i - 1, cwd, i);
141
142 /* again, with mkstemps() and an empty suffix */
143 /* try first at the start of a page, no prefix */
144 try_mkstemps(p, "", i, "");
145 /* now at the end of the page, no prefix */
146 try_mkstemps(p + pg - i - 1, "", i, "");
147 /* start of the page, prefixed with the cwd */
148 try_mkstemps(p, cwd, i, "");
149 /* how about at the end of the page, prefixed with cwd? */
150 try_mkstemps(p + pg - clen - i - 1, cwd, i, "");
151
152 /* mkstemps() and a non-empty suffix */
153 /* try first at the start of a page, no prefix */
154 try_mkstemps(p, "", i, SUFFIX);
155 /* now at the end of the page, no prefix */
156 try_mkstemps(p + pg - i - SLEN - 1, "", i, SUFFIX);
157 /* start of the page, prefixed with the cwd */
158 try_mkstemps(p, cwd, i, SUFFIX);
159 /* how about at the end of the page, prefixed with cwd? */
160 try_mkstemps(p + pg - clen - i - SLEN - 1, cwd, i, SUFFIX);
161
162 }
163
164 return 0;
165}