1*241eb37eSConrad Meyer /*
2*241eb37eSConrad Meyer * Copyright (c) 2017 Dell EMC Isilon
3*241eb37eSConrad Meyer * All rights reserved.
4*241eb37eSConrad Meyer *
5*241eb37eSConrad Meyer * Redistribution and use in source and binary forms, with or without
6*241eb37eSConrad Meyer * modification, are permitted provided that the following conditions
7*241eb37eSConrad Meyer * are met:
8*241eb37eSConrad Meyer * 1. Redistributions of source code must retain the above copyright
9*241eb37eSConrad Meyer * notice, this list of conditions and the following disclaimer.
10*241eb37eSConrad Meyer * 2. Redistributions in binary form must reproduce the above copyright
11*241eb37eSConrad Meyer * notice, this list of conditions and the following disclaimer in the
12*241eb37eSConrad Meyer * documentation and/or other materials provided with the distribution.
13*241eb37eSConrad Meyer *
14*241eb37eSConrad Meyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*241eb37eSConrad Meyer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*241eb37eSConrad Meyer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*241eb37eSConrad Meyer * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*241eb37eSConrad Meyer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*241eb37eSConrad Meyer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*241eb37eSConrad Meyer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*241eb37eSConrad Meyer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*241eb37eSConrad Meyer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*241eb37eSConrad Meyer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*241eb37eSConrad Meyer * SUCH DAMAGE.
25*241eb37eSConrad Meyer */
26*241eb37eSConrad Meyer
27*241eb37eSConrad Meyer #include <sys/param.h>
28*241eb37eSConrad Meyer #include <errno.h>
29*241eb37eSConrad Meyer #include <fcntl.h>
30*241eb37eSConrad Meyer #include <glob.h>
31*241eb37eSConrad Meyer #include <stdio.h>
32*241eb37eSConrad Meyer #include <stdlib.h>
33*241eb37eSConrad Meyer #include <string.h>
34*241eb37eSConrad Meyer #include <time.h>
35*241eb37eSConrad Meyer #include <unistd.h>
36*241eb37eSConrad Meyer
37*241eb37eSConrad Meyer #include <atf-c.h>
38*241eb37eSConrad Meyer
39*241eb37eSConrad Meyer /*
40*241eb37eSConrad Meyer * Derived from Russ Cox' pathological case test program used for the
41*241eb37eSConrad Meyer * https://research.swtch.com/glob article.
42*241eb37eSConrad Meyer */
43*241eb37eSConrad Meyer ATF_TC_WITHOUT_HEAD(glob_pathological_test);
ATF_TC_BODY(glob_pathological_test,tc)44*241eb37eSConrad Meyer ATF_TC_BODY(glob_pathological_test, tc)
45*241eb37eSConrad Meyer {
46*241eb37eSConrad Meyer struct timespec t, t2;
47*241eb37eSConrad Meyer glob_t g;
48*241eb37eSConrad Meyer const char *longname = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
49*241eb37eSConrad Meyer "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
50*241eb37eSConrad Meyer char pattern[1000], *p;
51*241eb37eSConrad Meyer double dt;
52*241eb37eSConrad Meyer unsigned i, j, k, mul;
53*241eb37eSConrad Meyer int fd, rc;
54*241eb37eSConrad Meyer
55*241eb37eSConrad Meyer fd = open(longname, O_CREAT | O_RDWR, 0666);
56*241eb37eSConrad Meyer ATF_REQUIRE(fd >= 0);
57*241eb37eSConrad Meyer
58*241eb37eSConrad Meyer /*
59*241eb37eSConrad Meyer * Test up to 100 a* groups. Exponential implementations typically go
60*241eb37eSConrad Meyer * bang at i=7 or 8.
61*241eb37eSConrad Meyer */
62*241eb37eSConrad Meyer for (i = 0; i < 100; i++) {
63*241eb37eSConrad Meyer /*
64*241eb37eSConrad Meyer * Create a*...b pattern with i 'a*' groups.
65*241eb37eSConrad Meyer */
66*241eb37eSConrad Meyer p = pattern;
67*241eb37eSConrad Meyer for (k = 0; k < i; k++) {
68*241eb37eSConrad Meyer *p++ = 'a';
69*241eb37eSConrad Meyer *p++ = '*';
70*241eb37eSConrad Meyer }
71*241eb37eSConrad Meyer *p++ = 'b';
72*241eb37eSConrad Meyer *p = '\0';
73*241eb37eSConrad Meyer
74*241eb37eSConrad Meyer clock_gettime(CLOCK_REALTIME, &t);
75*241eb37eSConrad Meyer for (j = 0; j < mul; j++) {
76*241eb37eSConrad Meyer memset(&g, 0, sizeof g);
77*241eb37eSConrad Meyer rc = glob(pattern, 0, 0, &g);
78*241eb37eSConrad Meyer if (rc == GLOB_NOSPACE || rc == GLOB_ABORTED) {
79*241eb37eSConrad Meyer ATF_REQUIRE_MSG(rc == GLOB_NOMATCH,
80*241eb37eSConrad Meyer "an unexpected error occurred: "
81*241eb37eSConrad Meyer "rc=%d errno=%d", rc, errno);
82*241eb37eSConrad Meyer /* NORETURN */
83*241eb37eSConrad Meyer }
84*241eb37eSConrad Meyer
85*241eb37eSConrad Meyer ATF_CHECK_MSG(rc == GLOB_NOMATCH,
86*241eb37eSConrad Meyer "A bogus match occurred: '%s' ~ '%s'", pattern,
87*241eb37eSConrad Meyer g.gl_pathv[0]);
88*241eb37eSConrad Meyer globfree(&g);
89*241eb37eSConrad Meyer }
90*241eb37eSConrad Meyer clock_gettime(CLOCK_REALTIME, &t2);
91*241eb37eSConrad Meyer
92*241eb37eSConrad Meyer t2.tv_sec -= t.tv_sec;
93*241eb37eSConrad Meyer t2.tv_nsec -= t.tv_nsec;
94*241eb37eSConrad Meyer dt = t2.tv_sec + (double)t2.tv_nsec/1e9;
95*241eb37eSConrad Meyer dt /= mul;
96*241eb37eSConrad Meyer
97*241eb37eSConrad Meyer ATF_CHECK_MSG(dt < 1, "glob(3) took far too long: %d %.9f", i,
98*241eb37eSConrad Meyer dt);
99*241eb37eSConrad Meyer
100*241eb37eSConrad Meyer if (dt >= 0.0001)
101*241eb37eSConrad Meyer mul = 1;
102*241eb37eSConrad Meyer }
103*241eb37eSConrad Meyer }
104*241eb37eSConrad Meyer
ATF_TP_ADD_TCS(tp)105*241eb37eSConrad Meyer ATF_TP_ADD_TCS(tp)
106*241eb37eSConrad Meyer {
107*241eb37eSConrad Meyer
108*241eb37eSConrad Meyer ATF_TP_ADD_TC(tp, glob_pathological_test);
109*241eb37eSConrad Meyer
110*241eb37eSConrad Meyer return (atf_no_error());
111*241eb37eSConrad Meyer }
112