xref: /dragonfly/contrib/lvm2/dist/libdm/libdm-file.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
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 <fcntl.h>
21 #include <dirent.h>
22 
_create_dir_recursive(const char * dir)23 static int _create_dir_recursive(const char *dir)
24 {
25           char *orig, *s;
26           int rc, r = 0;
27 
28           log_verbose("Creating directory \"%s\"", dir);
29           /* Create parent directories */
30           orig = s = dm_strdup(dir);
31           while ((s = strchr(s, '/')) != NULL) {
32                     *s = '\0';
33                     if (*orig) {
34                               rc = mkdir(orig, 0777);
35                               if (rc < 0 && errno != EEXIST) {
36                                         if (errno != EROFS)
37                                                   log_sys_error("mkdir", orig);
38                                         goto out;
39                               }
40                     }
41                     *s++ = '/';
42           }
43 
44           /* Create final directory */
45           rc = mkdir(dir, 0777);
46           if (rc < 0 && errno != EEXIST) {
47                     if (errno != EROFS)
48                               log_sys_error("mkdir", orig);
49                     goto out;
50           }
51 
52           r = 1;
53 out:
54           dm_free(orig);
55           return r;
56 }
57 
dm_create_dir(const char * dir)58 int dm_create_dir(const char *dir)
59 {
60           struct stat info;
61 
62           if (!*dir)
63                     return 1;
64 
65           if (stat(dir, &info) < 0)
66                     return _create_dir_recursive(dir);
67 
68           if (S_ISDIR(info.st_mode))
69                     return 1;
70 
71           log_error("Directory \"%s\" not found", dir);
72           return 0;
73 }
74 
dm_fclose(FILE * stream)75 int dm_fclose(FILE *stream)
76 {
77           int prev_fail = ferror(stream);
78           int fclose_fail = fclose(stream);
79 
80           /* If there was a previous failure, but fclose succeeded,
81              clear errno, since ferror does not set it, and its value
82              may be unrelated to the ferror-reported failure.  */
83           if (prev_fail && !fclose_fail)
84                     errno = 0;
85 
86           return prev_fail || fclose_fail ? EOF : 0;
87 }
88