how to simulate "mkdir -p /home/blah1/blah2/blah3" in "c" where only /home exist

I'm trying to make use of mkdir(char *pathname, S_IRWXU) to create the directories.

but it only creates one directory at a time. so I have to separate the tokens for "/home/blah1/blah2/blah3" as "home blah1 blah2 blah3" using delimiter "/", but it is again hectic to create such directory structure.

I know Linux command "mkdir -p /home/blah1/blah2/blah3" would create all the sub-directories if it doesn't exist.

how to achieve the same "mkdir -p /home/blah1/blah2/blah3" in "c" where only /home exist

I'm using Redhat Linux 9 on Intel board 915GLVG

Here's the code for how it's done in Solaris, as you can see you do have to tokenize and create the structure.

I see nothing :confused:

The easiest way (ok hardly pure C):

system("mkdir -p /home/blah1/blah2/blah3");

Good point I forgot the code:

[highlight=c]

            if \(mkdir\(arg, mode\) < 0\)
            \{
                    if \(!pflag || !\(errno == ENOENT || errno == EEXIST || errno == ENOTDIR\)\)
                    \{
                            error\(ERROR_system\(0\), "%s:", arg\);
                            continue;
                    \}
                    if \(errno == EEXIST\)
                            continue;

                    /*
                     * -p option, preserve intermediates
                     * first eliminate trailing /'s
                     */

                    n = strlen\(arg\);
                    while \(n > 0 && arg[--n] == '/'\);
                    arg[n \+ 1] = 0;
                    for \(name = arg, n = *arg; n;\)
                    \{
                            /* skip over slashes */
                            while \(*arg == '/'\)
                                    arg\+\+;
                            /* skip to next component */
                            while \(\(n = *arg\) && n != '/'\)
                                    arg\+\+;
                            *arg = 0;
                            if \(mkdir\(name, n ? dmode : mode\) < 0 && errno != EEXIST && access\(name, F_OK\) < 0\)
                            \{
                                    *arg = n;
                                    error\(ERROR_system\(0\), "%s:", name\);
                                    break;
                            \}
                            if \(!\(*arg = n\) && \(mode & \(S\_ISVTX|S\_ISUID|S_ISGID\)\)\)
                            \{
                                    if \(stat\(name, &st\)\)
                                    \{
                                            error\(ERROR_system\(0\), "%s: cannot stat", name\);
                                            break;
                                    \}
                                    if \(\(st.st_mode & \(S\_ISVTX|S\_ISUID|S_ISGID\)\) != \(mode & \(S\_ISVTX|S\_ISUID|S_ISGID\)\) && chmod\(name, mode\)\)
                                    \{
                                            error\(ERROR_system\(0\), "%s: cannot change mode from %s to %s", name, fmtperm\(st.st_mode & \(S\_ISVTX|S\_ISUID|S_ISGID\)\), fmtperm\(mode\)\);
                                            break;
                                    \}
                            \}
                    \}
            \}

[/highlight]

The best way is probably to iterate and call mkdir and chdir every time.
I'm actually in the process of doing something similar, and that's the way I'll go.
Constructing the (full) path every time is quite annoying, while changing the working
directory should be more easy.

S.

Why not just append to the string instead of recreating every time?

That solution introduces an effect that impacts the entire process it's running in: the changing of the current directory.

If you do something like that you will then have what's almost certainly an undocumented and definitely an unnecessary dependency on the internal implementation of what should in theory be reusable code. Unless you fully document all the internals of such calls, then you'll only have an unnecessary dependency.

And you'll outright break multithreaded apps because threads other than the one calling a mkdir() call that changes the current directory will have the current directory modified right out from under their processing.

There is nothing to recreate.

I m doing a sequence of

mkdir(dir);
chdir(dir)
for(subdir to create)
mkdir(subdir[i]);
chdir("..");

and so on, which in my case seems perfect, as I have to create a director hierarchy from a structure (list of list).

In his case, it could do something similar.

---------- Post updated at 01:50 AM ---------- Previous update was at 01:44 AM ----------

Hmm.. Although I thought about the change of the current directory ( I use chdir(".."); to restore the current directory), I honestly didn't think about the multithreading problem. Thanks for the heads up.

S.

You're welcome. And yes, I learned that one that hard way.