source: mainline/uspace/lib/c/generic/tmpfile.c@ 1d2f85e

Last change on this file since 1d2f85e was 08e103d4, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

Use clearer naming for string length functions

This and the following commit change the names of functions, as well as
their documentation, to use unambiguous terms "bytes" and "code points"
instead of ambiguous terms "size", "length", and "characters".

  • Property mode set to 100644
File size: 3.8 KB
Line 
1/*
2 * Copyright (c) 2018 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libc
30 * @{
31 */
32/** @file Temporary files
33 */
34
35#include <errno.h>
36#include <fibril_synch.h>
37#include <stdio.h>
38#include <str.h>
39#include <tmpfile.h>
40#include <vfs/vfs.h>
41
42static size_t tmpfile_cnt = 0;
43static FIBRIL_MUTEX_INITIALIZE(tmpfile_lock);
44
45/** Create and open file suitable as temporary file based on template.
46 *
47 * This is designed to allow creating temporary files compatible with POSIX
48 * mk(s)temp and tempnam, as well as for the use of ISO C tmpfile, tmpnam.
49 *
50 * @param templ
51 * @param create If @c false, only construct file name
52 *
53 * @return If @a create is true, open file descriptor on success (and
54 * @a *templ is filled in with actual file name),
55 * if @a create is false, zero on success. -1 on failure.
56 */
57int __tmpfile_templ(char *templ, bool create)
58{
59 size_t tsize;
60 char *p;
61 int file;
62 errno_t rc;
63
64 tsize = str_bytes(templ);
65 if (tsize < 6)
66 return -1;
67
68 p = templ + tsize - 6;
69 if (str_cmp(p, "XXXXXX") != 0)
70 return -1;
71
72 fibril_mutex_lock(&tmpfile_lock);
73
74 while (tmpfile_cnt < 1000000) {
75 snprintf(p, 6 + 1, "%06zu", tmpfile_cnt);
76 if (create) {
77 /* Try creating file */
78 rc = vfs_lookup(templ, WALK_MUST_CREATE |
79 WALK_REGULAR, &file);
80 if (rc == EOK) {
81 rc = vfs_open(file, MODE_READ | MODE_WRITE);
82 if (rc == EOK) {
83 ++tmpfile_cnt;
84 fibril_mutex_unlock(&tmpfile_lock);
85 return file;
86 }
87
88 vfs_put(file);
89 }
90 } else {
91 /* Test if file exists */
92 rc = vfs_lookup(templ, 0, &file);
93 if (rc != EOK) {
94 ++tmpfile_cnt;
95 fibril_mutex_unlock(&tmpfile_lock);
96 return 0;
97 }
98
99 vfs_put(file);
100 }
101
102 ++tmpfile_cnt;
103 }
104
105 fibril_mutex_unlock(&tmpfile_lock);
106 return -1;
107}
108
109/** Create and open temporary (unnamed) file.
110 *
111 * @return Open file descriptor on success, -1 on failure.
112 */
113int __tmpfile(void)
114{
115 int file;
116 char namebuf[L_tmpnam];
117
118 str_cpy(namebuf, L_tmpnam, "/tmp/tmp.XXXXXX");
119
120 file = __tmpfile_templ(namebuf, true);
121 if (file < 0)
122 return -1;
123
124 (void) vfs_unlink_path(namebuf);
125 return file;
126}
127
128/** Construct temporary file name.
129 *
130 * @param namebuf Buffer that can hold at least L_tmpnam bytes
131 * @return @a namebuf on success, @c NULL on failure
132 */
133char *__tmpnam(char *namebuf)
134{
135 int rc;
136
137 str_cpy(namebuf, L_tmpnam, "/tmp/tmp.XXXXXX");
138
139 rc = __tmpfile_templ(namebuf, false);
140 if (rc < 0)
141 return NULL;
142
143 return namebuf;
144}
145
146/** @}
147 */
Note: See TracBrowser for help on using the repository browser.