For Programmers: Free Programming Magazines  


Home > Archive > Unix Programming > July 2004 > mkdir -p









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author mkdir -p
Stu

2004-07-22, 8:57 pm

Is there any way to make the mkdir() function behave like mkdir -p. If not,
does anybody have any sample code that does this ?

Thanks
Lev Walkin

2004-07-23, 3:57 am

Stu wrote:
> Is there any way to make the mkdir() function behave like mkdir -p. If not,
> does anybody have any sample code that does this ?
>
> Thanks


http://cvsup.pt.freebsd.org/cgi-bin...type=text/plain


--
Lev Walkin
vlm@lionet.info
James Antill

2004-07-23, 3:57 am

On Thu, 22 Jul 2004 16:07:40 -0700, Stu wrote:

> Is there any way to make the mkdir() function behave like mkdir -p. If not,
> does anybody have any sample code that does this ?


Searching google for "mkdir_p const char", will give you a lot
implementations.

The basic idea is to just get a writable copy of the path, and either go
through it forwards ignoring EEXIST or try it and if you fail with
ENOENT recursively try again with the last element chopped off (the
later is much faster for long paths that are mostly there, and much
slower for long paths that are mostly not there).

--
James Antill -- james@and.org
Need an efficient and powerful string library for C?
http://www.and.org/vstr/

Lev Walkin

2004-07-23, 3:57 am

James Antill wrote:
> On Thu, 22 Jul 2004 16:07:40 -0700, Stu wrote:
>
>
>
>
> Searching google for "mkdir_p const char", will give you a lot
> implementations.
>
> The basic idea is to just get a writable copy of the path, and either go
> through it forwards ignoring EEXIST or try it and if you fail with
> ENOENT recursively try again with the last element chopped off (the
> later is much faster for long paths that are mostly there, and much
> slower for long paths that are mostly not there).


there is a better one: for long paths (more than several tokens), use
binary search to find a place where the previous component exists and
the following aren't. then, start creating from there.

--
Lev Walkin
vlm@lionet.info
Casper H.S. Dik

2004-07-23, 3:57 am

beefstu350@hotmail.com (Stu) writes:

>Is there any way to make the mkdir() function behave like mkdir -p. If not,
>does anybody have any sample code that does this ?



Solaris has "mkdirp(3GEN)" in -lgen.

Casper
--
Expressed in this posting are my opinions. They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.
Måns Rullgård

2004-07-23, 8:57 am

Lev Walkin <vlm@lionet.info> writes:

> James Antill wrote:
>
> there is a better one: for long paths (more than several tokens), use
> binary search to find a place where the previous component exists and
> the following aren't. then, start creating from there.


How long would the path need to be before this actually made any real
difference? I can't imagine many situations where there would be a
need to create long paths frequently enough for this to matter at all.

--
Måns Rullgård
mru@kth.se
Lev Walkin

2004-07-24, 3:56 am

M=E5ns Rullg=E5rd wrote:
> Lev Walkin <vlm@lionet.info> writes:
>=20
>=20
f not,[color=darkred]
>=20
>=20
> How long would the path need to be before this actually made any real
> difference? I can't imagine many situations where there would be a
> need to create long paths frequently enough for this to matter at all.


On a busy PC server, the directory creation might well cause repositionin=
g
of hard drive heads each time the directory is created. Say, it takes 10m=
s
to do so. If the path has 3 existing and 2 added components, the time to
do it sequentially would be 50 ms. Using binary search, it would take 30m=
s.
For longer paths, the effect will be greater.

--=20
Lev Walkin
vlm@lionet.info
Michael B Allen

2004-07-28, 9:05 pm

On Thu, 22 Jul 2004 19:07:40 -0400, Stu wrote:

> Is there any way to make the mkdir() function behave like mkdir -p. If
> not, does anybody have any sample code that does this ?


I wrote this function once and ended up not using it for some reason
but I think it compiles.

Mike

int
mkdirp(const char *dir, mode_t mode)
{
char buf[PATH_MAX];
char *bp = buf, *blim = buf + PATH_MAX;

while (bp < blim && *dir && *dir == '/') {
*bp++ = *dir++;
}
for ( ;; ) {
if (bp == blim) {
errno = ENAMETOOLONG;
return -1;
}

if (*dir == '\0' || *dir == '/') {
struct stat st;

*bp = '\0';
if (stat(buf, &st) == -1) {
if (errno != ENOENT) {
return -1;
}
if (mkdir(buf, mode) == -1) {
return -1;
}
}
if (*dir == '\0') {
break;
}
*bp++ = '/';
} else {
*bp++ = *dir;
}
dir++;
}

return 0;
}
James Antill

2004-07-28, 9:05 pm

On Sat, 24 Jul 2004 04:00:27 -0400, Michael B Allen wrote:

> On Thu, 22 Jul 2004 19:07:40 -0400, Stu wrote:
>
>
> I wrote this function once and ended up not using it for some reason
> but I think it compiles.
>
> Mike
>
> int
> mkdirp(const char *dir, mode_t mode)
> {
> char buf[PATH_MAX];
> char *bp = buf, *blim = buf + PATH_MAX;
>
> while (bp < blim && *dir && *dir == '/') {
> *bp++ = *dir++;
> }


I assume this is so when you pass absolute path names it doesn't try to
create ""? It still seems weird to use a while loop.


> for ( ;; ) {
> if (bp == blim) {
> errno = ENAMETOOLONG;
> return -1;
> }
>
> if (*dir == '\0' || *dir == '/') {
> struct stat st;
>
> *bp = '\0';
> if (stat(buf, &st) == -1) {
> if (errno != ENOENT) {
> return -1;
> }
> if (mkdir(buf, mode) == -1) {
> return -1;
> }


Doing it with stat/mkdir creates a race, where if two processes want to
create the same path one of them can fail. Using only mkdir() solves this
small problem (and does fewer syscalls).

--
James Antill -- james@and.org
Need an efficient and powerful string library for C?
http://www.and.org/vstr/

Michael B Allen

2004-07-28, 9:05 pm

On Sat, 24 Jul 2004 15:48:38 -0400, James Antill wrote:

> On Sat, 24 Jul 2004 04:00:27 -0400, Michael B Allen wrote:
>
>
> I assume this is so when you pass absolute path names it doesn't try to
> create ""? It still seems weird to use a while loop.


No, the '/'s are collected in buf. I think it was just supposed to achive
some entry condition for the loop.

>
> Doing it with stat/mkdir creates a race, where if two processes want to
> create the same path one of them can fail. Using only mkdir() solves
> this small problem (and does fewer syscalls).


True. That would be an improvement.

Mike
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com