Line data Source code
1 : /*
2 : mkdir -p
3 :
4 : Copyright (C) Amitay Isaacs 2014
5 : Copyright (C) Martin Schwenke 2014
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program; if not, see <http://www.gnu.org/licenses/>.
19 : */
20 : #include "replace.h"
21 : #include <sys/stat.h>
22 : #include <libgen.h>
23 : #include "mkdir_p.h"
24 :
25 16372 : int mkdir_p(const char *dir, int mode)
26 : {
27 : char t[PATH_MAX];
28 : ssize_t len;
29 : int ret;
30 :
31 16372 : if (strcmp(dir, "/") == 0) {
32 0 : return 0;
33 : }
34 :
35 16372 : if (strcmp(dir, ".") == 0) {
36 0 : return 0;
37 : }
38 :
39 : /* Try to create directory */
40 16372 : ret = mkdir(dir, mode);
41 : /* Succeed if that worked or if it already existed */
42 16372 : if (ret == 0 || errno == EEXIST) {
43 16353 : return 0;
44 : }
45 : /* Fail on anything else except ENOENT */
46 19 : if (errno != ENOENT) {
47 0 : return ret;
48 : }
49 :
50 : /* Create ancestors */
51 19 : len = strlen(dir);
52 19 : ret = snprintf(t, sizeof(t), "%s", dir);
53 19 : if (ret != len) {
54 0 : errno = ENAMETOOLONG;
55 0 : return -1;
56 : }
57 :
58 19 : ret = mkdir_p(dirname(t), mode);
59 19 : if (ret != 0) {
60 0 : return ret;
61 : }
62 :
63 : /* Create directory */
64 19 : ret = mkdir(dir, mode);
65 19 : if ((ret == -1) && (errno == EEXIST)) {
66 0 : ret = 0;
67 : }
68 :
69 19 : return ret;
70 : }
|