]> git.ipfire.org Git - thirdparty/glibc.git/blame - support/temp_file.c
support: Add create_temp_file_in_dir
[thirdparty/glibc.git] / support / temp_file.c
CommitLineData
c23de0aa 1/* Temporary file handling for tests.
d614a753 2 Copyright (C) 1998-2020 Free Software Foundation, Inc.
c23de0aa
FW
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
5a82c748 17 <https://www.gnu.org/licenses/>. */
c23de0aa
FW
18
19/* This is required to get an mkstemp which can create large files on
20 some 32-bit platforms. */
21#define _FILE_OFFSET_BITS 64
22
23#include <support/temp_file.h>
24#include <support/temp_file-internal.h>
25#include <support/support.h>
26
27#include <paths.h>
c23de0aa
FW
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
c22553ef 31#include <unistd.h>
c23de0aa
FW
32
33/* List of temporary files. */
34static struct temp_name_list
35{
706256af 36 struct temp_name_list *next;
c23de0aa 37 char *name;
c22553ef 38 pid_t owner;
c23de0aa
FW
39} *temp_name_list;
40
41/* Location of the temporary files. Set by the test skeleton via
42 support_set_test_dir. The string is not be freed. */
43static const char *test_dir = _PATH_TMP;
44
45void
46add_temp_file (const char *name)
47{
48 struct temp_name_list *newp
49 = (struct temp_name_list *) xcalloc (sizeof (*newp), 1);
50 char *newname = strdup (name);
51 if (newname != NULL)
52 {
53 newp->name = newname;
706256af 54 newp->next = temp_name_list;
c22553ef 55 newp->owner = getpid ();
706256af 56 temp_name_list = newp;
c23de0aa
FW
57 }
58 else
59 free (newp);
60}
61
62int
60854f40 63create_temp_file_in_dir (const char *base, const char *dir, char **filename)
c23de0aa
FW
64{
65 char *fname;
66 int fd;
67
60854f40 68 fname = xasprintf ("%s/%sXXXXXX", dir, base);
c23de0aa
FW
69
70 fd = mkstemp (fname);
71 if (fd == -1)
72 {
73 printf ("cannot open temporary file '%s': %m\n", fname);
74 free (fname);
75 return -1;
76 }
77
78 add_temp_file (fname);
79 if (filename != NULL)
80 *filename = fname;
81 else
82 free (fname);
83
84 return fd;
85}
86
60854f40
AZ
87int
88create_temp_file (const char *base, char **filename)
89{
90 return create_temp_file_in_dir (base, test_dir, filename);
91}
92
1ffe1ccb
FW
93char *
94support_create_temp_directory (const char *base)
95{
8adfb0ee
FW
96 char *path = xasprintf ("%s/%sXXXXXX", test_dir, base);
97 if (mkdtemp (path) == NULL)
1ffe1ccb 98 {
8adfb0ee 99 printf ("error: mkdtemp (\"%s\"): %m", path);
1ffe1ccb
FW
100 exit (1);
101 }
8adfb0ee
FW
102 add_temp_file (path);
103 return path;
1ffe1ccb
FW
104}
105
c23de0aa
FW
106/* Helper functions called by the test skeleton follow. */
107
108void
109support_set_test_dir (const char *path)
110{
111 test_dir = path;
112}
113
114void
115support_delete_temp_files (void)
116{
c22553ef 117 pid_t pid = getpid ();
c23de0aa
FW
118 while (temp_name_list != NULL)
119 {
c22553ef
FW
120 /* Only perform the removal if the path was registed in the same
121 process, as identified by the PID. (This assumes that the
122 parent process which registered the temporary file sticks
123 around, to prevent PID reuse.) */
124 if (temp_name_list->owner == pid)
125 {
126 if (remove (temp_name_list->name) != 0)
127 printf ("warning: could not remove temporary file: %s: %m\n",
128 temp_name_list->name);
129 }
c23de0aa
FW
130 free (temp_name_list->name);
131
706256af 132 struct temp_name_list *next = temp_name_list->next;
c23de0aa
FW
133 free (temp_name_list);
134 temp_name_list = next;
135 }
136}
137
138void
139support_print_temp_files (FILE *f)
140{
141 if (temp_name_list != NULL)
142 {
143 struct temp_name_list *n;
144 fprintf (f, "temp_files=(\n");
706256af 145 for (n = temp_name_list; n != NULL; n = n->next)
c23de0aa
FW
146 fprintf (f, " '%s'\n", n->name);
147 fprintf (f, ")\n");
148 }
149}