Magellan Linux

Annotation of /trunk/mkinitrd-magellan/busybox/libbb/make_directory.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 816 - (hide annotations) (download)
Fri Apr 24 18:33:46 2009 UTC (15 years, 1 month ago) by niro
File MIME type: text/plain
File size: 2522 byte(s)
-updated to busybox-1.13.4
1 niro 532 /* vi: set sw=4 ts=4: */
2     /*
3     * parse_mode implementation for busybox
4     *
5     * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
6     *
7     * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8     */
9    
10     /* Mar 5, 2003 Manuel Novoa III
11     *
12     * This is the main work function for the 'mkdir' applet. As such, it
13     * strives to be SUSv3 compliant in it's behaviour when recursively
14     * making missing parent dirs, and in it's mode setting of the final
15     * directory 'path'.
16     *
17     * To recursively build all missing intermediate directories, make
18     * sure that (flags & FILEUTILS_RECUR) is non-zero. Newly created
19     * intermediate directories will have at least u+wx perms.
20     *
21     * To set specific permissions on 'path', pass the appropriate 'mode'
22     * val. Otherwise, pass -1 to get default permissions.
23     */
24    
25     #include "libbb.h"
26    
27 niro 816 /* This function is used from NOFORK applets. It must not allocate anything */
28    
29     int FAST_FUNC bb_make_directory(char *path, long mode, int flags)
30 niro 532 {
31     mode_t mask;
32     const char *fail_msg;
33     char *s = path;
34     char c;
35     struct stat st;
36    
37     mask = umask(0);
38 niro 816 umask(mask & ~0300); /* Ensure intermediate dirs are wx */
39 niro 532
40 niro 816 while (1) {
41     c = '\0';
42 niro 532
43     if (flags & FILEUTILS_RECUR) { /* Get the parent. */
44     /* Bypass leading non-'/'s and then subsequent '/'s. */
45     while (*s) {
46     if (*s == '/') {
47     do {
48     ++s;
49     } while (*s == '/');
50 niro 816 c = *s; /* Save the current char */
51     *s = '\0'; /* and replace it with nul. */
52 niro 532 break;
53     }
54     ++s;
55     }
56     }
57    
58 niro 816 if (!c) /* Last component uses orig umask */
59     umask(mask);
60    
61 niro 532 if (mkdir(path, 0777) < 0) {
62     /* If we failed for any other reason than the directory
63 niro 816 * already exists, output a diagnostic and return -1. */
64 niro 532 if (errno != EEXIST
65 niro 816 || !(flags & FILEUTILS_RECUR)
66     || ((stat(path, &st) < 0) || !S_ISDIR(st.st_mode))
67     ) {
68 niro 532 fail_msg = "create";
69     umask(mask);
70     break;
71     }
72     /* Since the directory exists, don't attempt to change
73     * permissions if it was the full target. Note that
74 niro 816 * this is not an error condition. */
75 niro 532 if (!c) {
76     umask(mask);
77     return 0;
78     }
79     }
80    
81     if (!c) {
82 niro 816 /* Done. If necessary, update perms on the newly
83 niro 532 * created directory. Failure to update here _is_
84 niro 816 * an error. */
85     if ((mode != -1) && (chmod(path, mode) < 0)) {
86 niro 532 fail_msg = "set permissions of";
87     break;
88     }
89     return 0;
90     }
91    
92     /* Remove any inserted nul from the path (recursive mode). */
93     *s = c;
94 niro 816 } /* while (1) */
95 niro 532
96 niro 816 bb_perror_msg("cannot %s directory '%s'", fail_msg, path);
97 niro 532 return -1;
98     }