1 /*
2  * Copyright (c) 2007 Bret S. Lambert <blambert@gsipt.net>
3  *
4  * Public domain.
5  */
6 
7 #include <sys/param.h>
8 
9 #include <libgen.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <limits.h>
13 #include <errno.h>
14 
15 int
16 main(void)
17 {
18 	char path[2 * MAXPATHLEN];
19 	char dname[128];
20 	const char *dir = "junk";
21 	const char *fname = "/file.name.ext";
22 	char *str;
23 	int i;
24 
25 	/* Test normal functioning */
26 	strlcpy(path, "/", sizeof(path));
27 	strlcpy(dname, "/", sizeof(dname));
28 	strlcat(path, dir, sizeof(path));
29 	strlcat(dname, dir, sizeof(dname));
30 	strlcat(path, fname, sizeof(path));
31 	str = dirname(path);
32 	if (strcmp(str, dname) != 0)
33 		errx(1, "0: dirname(%s) = %s != %s", path, str, dname);
34 
35 	/*
36 	 * There are four states that require special handling:
37 	 *
38 	 * 1) path is NULL
39 	 * 2) path is the empty string
40 	 * 3) path is composed entirely of slashes
41 	 * 4) the resulting name is larger than MAXPATHLEN
42 	 *
43 	 * The first two cases require that a pointer
44 	 * to the string "." be returned.
45 	 *
46 	 * The third case requires that a pointer
47 	 * to the string "/" be returned.
48 	 *
49 	 * The final case requires that NULL be returned
50 	 * and errno * be set to ENAMETOOLONG.
51 	 */
52 	/* Case 1 */
53 	str = dirname(NULL);
54 	if (strcmp(str, ".") != 0)
55 		errx(1, "1: dirname(NULL) = %s != .", str);
56 
57 	/* Case 2 */
58 	strlcpy(path, "", sizeof(path));
59 	str = dirname(path);
60 	if (strcmp(str, ".") != 0)
61 		errx(1, "2: dirname(%s) = %s != .", path, str);
62 
63 	/* Case 3 */
64 	for (i = 0; i < MAXPATHLEN - 1; i++)
65 		strlcat(path, "/", sizeof(path));	/* path cleared above */
66 	str = dirname(path);
67 	if (strcmp(str, "/") != 0)
68 		errx(1, "3: dirname(%s) = %s != /", path, str);
69 
70 	/* Case 4 */
71 	strlcpy(path, "/", sizeof(path));		/* reset path */
72 	for (i = 0; i <= MAXPATHLEN; i += strlen(dir))
73 		strlcat(path, dir, sizeof(path));
74 	strlcat(path, fname, sizeof(path));
75 	str = dirname(path);
76 	if (str != NULL)
77 		errx(1, "4: dirname(%s) = %s != NULL", path, str);
78 	if (errno != ENAMETOOLONG)
79 		errx(1, "4: dirname(%s) sets errno to %d", path, errno);
80 
81 	return (0);
82 }
83