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 752970 : int mkdir_p(const char *dir, int mode) 26 : { 27 0 : char t[PATH_MAX]; 28 0 : ssize_t len; 29 0 : int ret; 30 : 31 752970 : if (strcmp(dir, "/") == 0) { 32 0 : return 0; 33 : } 34 : 35 752970 : if (strcmp(dir, ".") == 0) { 36 0 : return 0; 37 : } 38 : 39 : /* Try to create directory */ 40 752970 : ret = mkdir(dir, mode); 41 : /* Succeed if that worked or if it already existed */ 42 752970 : if (ret == 0 || errno == EEXIST) { 43 752927 : return 0; 44 : } 45 : /* Fail on anything else except ENOENT */ 46 43 : if (errno != ENOENT) { 47 0 : return ret; 48 : } 49 : 50 : /* Create ancestors */ 51 43 : len = strlen(dir); 52 43 : ret = snprintf(t, sizeof(t), "%s", dir); 53 43 : if (ret != len) { 54 0 : errno = ENAMETOOLONG; 55 0 : return -1; 56 : } 57 : 58 43 : ret = mkdir_p(dirname(t), mode); 59 43 : if (ret != 0) { 60 0 : return ret; 61 : } 62 : 63 : /* Create directory */ 64 43 : ret = mkdir(dir, mode); 65 43 : if ((ret == -1) && (errno == EEXIST)) { 66 0 : ret = 0; 67 : } 68 : 69 43 : return ret; 70 : }