]> git.ipfire.org Git - thirdparty/util-linux.git/blob - lib/fileutils.c
Merge branch 'tests-hwclock' of https://github.com/rudimeier/util-linux
[thirdparty/util-linux.git] / lib / fileutils.c
1 /*
2 * Copyright (C) 2012 Sami Kerola <kerolasa@iki.fi>
3 */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <sys/stat.h>
8 #include <unistd.h>
9 #include <sys/time.h>
10 #include <sys/resource.h>
11
12 #include "c.h"
13 #include "fileutils.h"
14 #include "pathnames.h"
15 #include "xalloc.h"
16
17 /* Create open temporary file in safe way. Please notice that the
18 * file permissions are -rw------- by default. */
19 int xmkstemp(char **tmpname, char *dir)
20 {
21 char *localtmp;
22 char *tmpenv;
23 mode_t old_mode;
24 int fd;
25
26 /* Some use cases must be capable of being moved atomically
27 * with rename(2), which is the reason why dir is here. */
28 if (dir != NULL)
29 tmpenv = dir;
30 else
31 tmpenv = getenv("TMPDIR");
32
33 if (tmpenv)
34 xasprintf(&localtmp, "%s/%s.XXXXXX", tmpenv,
35 program_invocation_short_name);
36 else
37 xasprintf(&localtmp, "%s/%s.XXXXXX", _PATH_TMP,
38 program_invocation_short_name);
39 old_mode = umask(077);
40 fd = mkostemp(localtmp, O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC);
41 umask(old_mode);
42 if (fd == -1) {
43 free(localtmp);
44 localtmp = NULL;
45 }
46 *tmpname = localtmp;
47 return fd;
48 }
49
50 /*
51 * portable getdtablesize()
52 */
53 int get_fd_tabsize(void)
54 {
55 int m;
56
57 #if defined(HAVE_GETDTABLESIZE)
58 m = getdtablesize();
59 #elif defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
60 struct rlimit rl;
61
62 getrlimit(RLIMIT_NOFILE, &rl);
63 m = rl.rlim_cur;
64 #elif defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
65 m = sysconf(_SC_OPEN_MAX);
66 #else
67 m = OPEN_MAX;
68 #endif
69 return m;
70 }
71
72 #ifdef TEST_PROGRAM
73 int main(void)
74 {
75 FILE *f;
76 char *tmpname;
77 f = xfmkstemp(&tmpname, NULL);
78 unlink(tmpname);
79 free(tmpname);
80 fclose(f);
81 return EXIT_FAILURE;
82 }
83 #endif
84
85
86 int mkdir_p(const char *path, mode_t mode)
87 {
88 char *p, *dir;
89 int rc = 0;
90
91 if (!path || !*path)
92 return -EINVAL;
93
94 dir = p = strdup(path);
95 if (!dir)
96 return -ENOMEM;
97
98 if (*p == '/')
99 p++;
100
101 while (p && *p) {
102 char *e = strchr(p, '/');
103 if (e)
104 *e = '\0';
105 if (*p) {
106 rc = mkdir(dir, mode);
107 if (rc && errno != EEXIST)
108 break;
109 rc = 0;
110 }
111 if (!e)
112 break;
113 *e = '/';
114 p = e + 1;
115 }
116
117 free(dir);
118 return rc;
119 }
120
121 /* returns basename and keeps dirname in the @path, if @path is "/" (root)
122 * then returns empty string */
123 char *stripoff_last_component(char *path)
124 {
125 char *p = path ? strrchr(path, '/') : NULL;
126
127 if (!p)
128 return NULL;
129 *p = '\0';
130 return p + 1;
131 }