]>
Commit | Line | Data |
---|---|---|
f0c76e30 | 1 | ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-06:01.texindex.asc |
2 | ||
3 | Index: contrib/texinfo/util/texindex.c | |
4 | =================================================================== | |
5 | RCS file: /home/ncvs/src/contrib/texinfo/util/texindex.c,v | |
6 | retrieving revision 1.1.1.8 | |
7 | diff -u -p -I__FBSDID -r1.1.1.8 texindex.c | |
8 | --- contrib/texinfo/util/texindex.c 23 May 2005 10:46:22 -0000 1.1.1.8 | |
9 | +++ contrib/texinfo/util/texindex.c 8 Jan 2006 23:31:32 -0000 | |
10 | @@ -384,17 +384,33 @@ For more information about these matters | |
11 | usage (1); | |
12 | } | |
13 | \f | |
14 | +static char **tv; | |
15 | +static int tv_alloc; | |
16 | +static int tv_used; | |
17 | + | |
18 | +static int | |
19 | +findtempname (char *tempname) | |
20 | +{ | |
21 | + int i; | |
22 | + | |
23 | + for (i = 0; i < tv_used; i++) | |
24 | + if (strcmp (tv[i], tempname) == 0) | |
25 | + return (1); | |
26 | + return (0); | |
27 | +} | |
28 | + | |
29 | /* Return a name for temporary file COUNT. */ | |
30 | ||
31 | static char * | |
32 | maketempname (int count) | |
33 | { | |
34 | static char *tempbase = NULL; | |
35 | + char *tempname; | |
36 | char tempsuffix[10]; | |
37 | + int fd; | |
38 | ||
39 | if (!tempbase) | |
40 | { | |
41 | - int fd; | |
42 | tempbase = concat (tempdir, "txidxXXXXXX"); | |
43 | ||
44 | fd = mkstemp (tempbase); | |
45 | @@ -403,7 +419,52 @@ maketempname (int count) | |
46 | } | |
47 | ||
48 | sprintf (tempsuffix, ".%d", count); | |
49 | - return concat (tempbase, tempsuffix); | |
50 | + tempname = concat (tempbase, tempsuffix); | |
51 | + /* | |
52 | + * The open logic becomes a bit convoluted. If open(2) fails due to EEXIST, | |
53 | + * it's likely because somebody attempted to race us, or because we have | |
54 | + * already created this file. | |
55 | + */ | |
56 | + fd = open (tempname, O_CREAT|O_EXCL|O_WRONLY, 0600); | |
57 | + if (fd == -1) | |
58 | + { | |
59 | + /* | |
60 | + * If errno is not EEXIST, then open failed for some other reason, so | |
61 | + * we should terminate. If errno == EEXIST AND we didn't create this | |
62 | + * file, terminate. Otherwise, it's safe to say that errno == EEXIST | |
63 | + * because we already created it, in this event, we can just return. | |
64 | + */ | |
65 | + if (errno != EEXIST || | |
66 | + (errno == EEXIST && findtempname (tempname) == 0)) | |
67 | + pfatal_with_name (tempname); | |
68 | + return (tempname); | |
69 | + } | |
70 | + else if (fd > 0) | |
71 | + { | |
72 | + close (fd); | |
73 | + } | |
74 | + if (tv == NULL) | |
75 | + { | |
76 | + tv_alloc = 16; | |
77 | + tv = calloc (tv_alloc, sizeof (char *)); | |
78 | + if (tv == NULL) | |
79 | + { | |
80 | + fprintf (stderr, "calloc failed\n"); | |
81 | + exit (1); | |
82 | + } | |
83 | + } | |
84 | + else if (tv_used == tv_alloc) | |
85 | + { | |
86 | + tv_alloc += 4; | |
87 | + tv = realloc (tv, tv_alloc * sizeof (char *)); | |
88 | + if (tv == NULL) | |
89 | + { | |
90 | + fprintf (stderr, "realloc failed"); | |
91 | + exit (1); | |
92 | + } | |
93 | + } | |
94 | + tv[tv_used++] = strdup (tempname); | |
95 | + return tempname; | |
96 | } | |
97 | ||
98 |