/*
* This is adapted from FreeBSD ' s src / bin / mkdir / mkdir . c , which bears
* the following copyright notice :
*
* Copyright ( c ) 1983 , 1992 , 1993
* The Regents of the University of California . All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1 . Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2 . Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 4 . Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ` ` AS IS ' ' AND
* ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED . IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
* DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION )
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT
* LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE .
*/
#include "c.h"
#include <sys/stat.h>
/*
* pg_mkdir_p - - - create a directory and , if necessary , parent directories
*
* This is equivalent to " mkdir - p " except we don ' t complain if the target
* directory already exists .
*
* We assume the path is in canonical form , i . e . , uses / as the separator .
*
* omode is the file permissions bits for the target directory . Note that any
* parent directories that have to be created get permissions according to the
* prevailing umask , but with u + wx forced on to ensure we can create there .
* ( We declare omode as int , not mode_t , to minimize dependencies for port . h . )
*
* Returns 0 on success , - 1 ( with errno set ) on failure .
*
* Note that on failure , the path arg has been modified to show the particular
* directory level we had problems with .
*/
int
pg_mkdir_p(char *path, int omode)
{
struct stat sb;
mode_t numask,
oumask;
int last,
retval;
char *p;
retval = 0 ;
p = path;
#ifdef WIN32
/* skip network and drive specifiers for win32 */
if (strlen(p) >= 2 )
{
if (p[0 ] == '/' && p[1 ] == '/' )
{
/* network drive */
p = strstr(p + 2 , "/" );
if (p == NULL)
{
errno = EINVAL;
return -1 ;
}
}
else if (p[1 ] == ':' &&
((p[0 ] >= 'a' && p[0 ] <= 'z' ) ||
(p[0 ] >= 'A' && p[0 ] <= 'Z' )))
{
/* local drive */
p += 2 ;
}
}
#endif
/*
* POSIX 1003 . 2 : For each dir operand that does not name an existing
* directory , effects equivalent to those caused by the following command
* shall occur :
*
* mkdir - p - m $ ( umask - S ) , u + wx $ ( dirname dir ) & & mkdir [ - m mode ] dir
*
* We change the user ' s umask and then restore it , instead of doing
* chmod ' s . Note we assume umask ( ) can ' t change errno .
*/
oumask = umask(0 );
numask = oumask & ~(S_IWUSR | S_IXUSR);
(void ) umask(numask);
if (p[0 ] == '/' ) /* Skip leading '/'. */
++p;
for (last = 0 ; !last; ++p)
{
if (p[0 ] == '\0' )
last = 1 ;
else if (p[0 ] != '/' )
continue ;
*p = '\0' ;
if (!last && p[1 ] == '\0' )
last = 1 ;
if (last)
(void ) umask(oumask);
/* check for pre-existing directory */
if (stat(path, &sb) == 0 )
{
if (!S_ISDIR(sb.st_mode))
{
if (last)
errno = EEXIST;
else
errno = ENOTDIR;
retval = -1 ;
break ;
}
}
else if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0 )
{
retval = -1 ;
break ;
}
if (!last)
*p = '/' ;
}
/* ensure we restored umask */
(void ) umask(oumask);
return retval;
}
Messung V0.5 in Prozent C=77 H=99 G=88
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-08-10)
¤
*© Formatika GbR, Deutschland