![]() |
|
|||
File indexing completed on 2025-05-11 08:24:15
0001 /** 0002 * @file 0003 * 0004 * @ingroup LibIO 0005 * 0006 * @brief rtems_mkdir() implementation. 0007 * 0008 * The implementation is based on FreeBSD 'bin/mkdir/mkdir.c' revision 163213. 0009 */ 0010 0011 /*- 0012 * Copyright (c) 2010 embedded brains GmbH & Co. KG 0013 * 0014 * Copyright (c) 1983, 1992, 1993 0015 * The Regents of the University of California. All rights reserved. 0016 * 0017 * Redistribution and use in source and binary forms, with or without 0018 * modification, are permitted provided that the following conditions 0019 * are met: 0020 * 1. Redistributions of source code must retain the above copyright 0021 * notice, this list of conditions and the following disclaimer. 0022 * 2. Redistributions in binary form must reproduce the above copyright 0023 * notice, this list of conditions and the following disclaimer in the 0024 * documentation and/or other materials provided with the distribution. 0025 * 4. Neither the name of the University nor the names of its contributors 0026 * may be used to endorse or promote products derived from this software 0027 * without specific prior written permission. 0028 * 0029 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 0030 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0031 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 0032 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 0033 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 0034 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 0035 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 0036 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 0037 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 0038 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 0039 * SUCH DAMAGE. 0040 */ 0041 0042 #ifdef HAVE_CONFIG_H 0043 #include "config.h" 0044 #endif 0045 0046 #include <sys/types.h> 0047 #include <sys/stat.h> 0048 0049 #include <errno.h> 0050 #include <stdlib.h> 0051 #include <string.h> 0052 #include <unistd.h> 0053 0054 #include <rtems/libio.h> 0055 0056 /* 0057 * Returns 1 if a directory has been created, 0058 * 2 if it already existed, and 0 on failure. 0059 */ 0060 static int 0061 build(char *path, mode_t omode) 0062 { 0063 struct stat sb; 0064 mode_t numask, oumask; 0065 int first, last, retval; 0066 char *p; 0067 0068 p = path; 0069 oumask = 0; 0070 retval = 1; 0071 if (p[0] == '/') /* Skip leading '/'. */ 0072 ++p; 0073 for (first = 1, last = 0; !last ; ++p) { 0074 if (p[0] == '\0') 0075 last = 1; 0076 else if (p[0] != '/') 0077 continue; 0078 *p = '\0'; 0079 if (!last && p[1] == '\0') 0080 last = 1; 0081 if (first) { 0082 /* 0083 * POSIX 1003.2: 0084 * For each dir operand that does not name an existing 0085 * directory, effects equivalent to those caused by the 0086 * following command shall occcur: 0087 * 0088 * mkdir -p -m $(umask -S),u+wx $(dirname dir) && 0089 * mkdir [-m mode] dir 0090 * 0091 * We change the user's umask and then restore it, 0092 * instead of doing chmod's. 0093 */ 0094 oumask = umask(0); 0095 numask = oumask & ~(S_IWUSR | S_IXUSR); 0096 (void)umask(numask); 0097 first = 0; 0098 } 0099 if (last) 0100 (void)umask(oumask); 0101 if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0) { 0102 if (errno == EEXIST || errno == EISDIR) { 0103 if (stat(path, &sb) < 0) { 0104 retval = 0; 0105 break; 0106 } else if (!S_ISDIR(sb.st_mode)) { 0107 if (last) 0108 errno = EEXIST; 0109 else 0110 errno = ENOTDIR; 0111 retval = 0; 0112 break; 0113 } 0114 if (last) 0115 retval = 2; 0116 } else { 0117 retval = 0; 0118 break; 0119 } 0120 } 0121 if (!last) 0122 *p = '/'; 0123 } 0124 if (!first && !last) 0125 (void)umask(oumask); 0126 return (retval); 0127 } 0128 0129 int 0130 rtems_mkdir(const char *path, mode_t mode) 0131 { 0132 int success = 0; 0133 char *dup_path = strdup(path); 0134 0135 if (dup_path != NULL) { 0136 success = build(dup_path, mode); 0137 free(dup_path); 0138 } 0139 0140 return success != 0 ? 0 : -1; 0141 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |