1 /* $NetBSD: libdm-file.c,v 1.1.1.1 2008/12/22 00:18:33 haad Exp $ */ 2 3 /* 4 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. 5 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. 6 * 7 * This file is part of the device-mapper userspace tools. 8 * 9 * This copyrighted material is made available to anyone wishing to use, 10 * modify, copy, or redistribute it subject to the terms and conditions 11 * of the GNU Lesser General Public License v.2.1. 12 * 13 * You should have received a copy of the GNU Lesser General Public License 14 * along with this program; if not, write to the Free Software Foundation, 15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 */ 17 18 #include "dmlib.h" 19 20 #include <sys/file.h> 21 #include <fcntl.h> 22 #include <dirent.h> 23 24 static int _create_dir_recursive(const char *dir) 25 { 26 char *orig, *s; 27 int rc, r = 0; 28 29 log_verbose("Creating directory \"%s\"", dir); 30 /* Create parent directories */ 31 orig = s = dm_strdup(dir); 32 while ((s = strchr(s, '/')) != NULL) { 33 *s = '\0'; 34 if (*orig) { 35 rc = mkdir(orig, 0777); 36 if (rc < 0 && errno != EEXIST) { 37 if (errno != EROFS) 38 log_sys_error("mkdir", orig); 39 goto out; 40 } 41 } 42 *s++ = '/'; 43 } 44 45 /* Create final directory */ 46 rc = mkdir(dir, 0777); 47 if (rc < 0 && errno != EEXIST) { 48 if (errno != EROFS) 49 log_sys_error("mkdir", orig); 50 goto out; 51 } 52 53 r = 1; 54 out: 55 dm_free(orig); 56 return r; 57 } 58 59 int dm_create_dir(const char *dir) 60 { 61 struct stat info; 62 63 if (!*dir) 64 return 1; 65 66 if (stat(dir, &info) < 0) 67 return _create_dir_recursive(dir); 68 69 if (S_ISDIR(info.st_mode)) 70 return 1; 71 72 log_error("Directory \"%s\" not found", dir); 73 return 0; 74 } 75 76 int dm_fclose(FILE *stream) 77 { 78 int prev_fail = ferror(stream); 79 int fclose_fail = fclose(stream); 80 81 /* If there was a previous failure, but fclose succeeded, 82 clear errno, since ferror does not set it, and its value 83 may be unrelated to the ferror-reported failure. */ 84 if (prev_fail && !fclose_fail) 85 errno = 0; 86 87 return prev_fail || fclose_fail ? EOF : 0; 88 } 89