2004-05-26 06:23:01 +04:00
|
|
|
/*
|
2004-11-22 04:38:40 +03:00
|
|
|
* Copyright (c) 2004-2005 The Trustees of Indiana University.
|
|
|
|
* All rights reserved.
|
|
|
|
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
|
|
|
* All rights reserved.
|
2004-11-28 23:09:25 +03:00
|
|
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
|
|
|
* University of Stuttgart. All rights reserved.
|
2005-03-24 15:43:37 +03:00
|
|
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
|
|
|
* All rights reserved.
|
2004-11-22 04:38:40 +03:00
|
|
|
* $COPYRIGHT$
|
|
|
|
*
|
|
|
|
* Additional copyrights may follow
|
|
|
|
*
|
2004-05-26 06:23:01 +04:00
|
|
|
* $HEADER$
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2005-07-04 05:59:52 +04:00
|
|
|
#include "ompi_config.h"
|
2004-05-26 06:23:01 +04:00
|
|
|
|
|
|
|
#include <string.h>
|
2004-10-20 05:03:09 +04:00
|
|
|
#ifdef HAVE_UNISTD_H
|
2004-05-26 06:23:01 +04:00
|
|
|
#include <unistd.h>
|
2004-10-20 05:03:09 +04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_LIBGEN_H
|
2004-05-26 06:23:01 +04:00
|
|
|
#include <libgen.h>
|
2004-10-20 05:03:09 +04:00
|
|
|
#endif
|
2004-06-15 23:37:05 +04:00
|
|
|
#include <stdlib.h>
|
2004-05-26 06:23:01 +04:00
|
|
|
|
2004-05-26 23:00:47 +04:00
|
|
|
#include "include/constants.h"
|
2005-07-04 05:59:52 +04:00
|
|
|
#include "opal/util/os_create_dirpath.h"
|
2004-05-26 06:23:01 +04:00
|
|
|
#include "util/sys_info.h"
|
2005-07-04 04:13:44 +04:00
|
|
|
#include "opal/util/argv.h"
|
2004-05-26 06:23:01 +04:00
|
|
|
|
2005-07-04 05:59:52 +04:00
|
|
|
int opal_os_create_dirpath(const char *path, const mode_t mode)
|
2004-05-26 06:23:01 +04:00
|
|
|
{
|
|
|
|
struct stat buf;
|
2004-11-04 16:35:15 +03:00
|
|
|
char **parts, *tmp;
|
|
|
|
int i, len;
|
|
|
|
|
2004-06-17 07:26:28 +04:00
|
|
|
if (NULL == path) { /* protect ourselves from errors */
|
2004-06-07 19:33:53 +04:00
|
|
|
return(OMPI_ERROR);
|
2004-05-26 06:23:01 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (0 == stat(path, &buf)) { /* already exists */
|
|
|
|
if (mode == (mode & buf.st_mode)) { /* has correct mode */
|
2004-06-07 19:33:53 +04:00
|
|
|
return(OMPI_SUCCESS);
|
2004-05-26 06:23:01 +04:00
|
|
|
}
|
2004-05-27 20:26:36 +04:00
|
|
|
if (0 == chmod(path, (buf.st_mode | mode))) { /* successfully change mode */
|
2004-06-07 19:33:53 +04:00
|
|
|
return(OMPI_SUCCESS);
|
2004-05-26 06:23:01 +04:00
|
|
|
}
|
2004-06-07 19:33:53 +04:00
|
|
|
return(OMPI_ERROR); /* can't set correct mode */
|
2004-05-26 06:23:01 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* quick -- try to make directory */
|
|
|
|
if (0 == mkdir(path, mode)) {
|
2004-06-07 19:33:53 +04:00
|
|
|
return(OMPI_SUCCESS);
|
2004-05-26 06:23:01 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* didnt work, so now have to build our way down the tree */
|
|
|
|
/* ensure system info is valid */
|
2005-03-14 23:57:21 +03:00
|
|
|
orte_sys_info();
|
2004-05-26 06:23:01 +04:00
|
|
|
|
2004-11-04 16:35:15 +03:00
|
|
|
/* Split the requested path up into its individual parts */
|
2004-05-26 06:23:01 +04:00
|
|
|
|
2005-07-04 04:13:44 +04:00
|
|
|
parts = opal_argv_split(path, orte_system_info.path_sep[0]);
|
2004-05-26 06:23:01 +04:00
|
|
|
|
2004-11-04 16:35:15 +03:00
|
|
|
/* Ensure to allocate enough space for tmp: the strlen of the
|
|
|
|
incoming path + 1 (for \0) */
|
2004-05-26 06:23:01 +04:00
|
|
|
|
2004-11-04 16:35:15 +03:00
|
|
|
tmp = malloc(strlen(path) + 1);
|
|
|
|
tmp[0] = '\0';
|
|
|
|
|
|
|
|
/* Iterate through all the subdirectory names in the path,
|
|
|
|
building up a directory name. Check to see if that dirname
|
|
|
|
exists. If it doesn't, create it. */
|
|
|
|
|
|
|
|
/* Notes about stat(): Windows has funny definitions of what will
|
|
|
|
return 0 from stat(). "C:" will return failure, while "C:\"
|
|
|
|
will return success. Similarly, "C:\foo" will return success,
|
|
|
|
while "C:\foo\" will return failure (assuming that a folder
|
|
|
|
named "foo" exists under C:\).
|
|
|
|
|
|
|
|
POSIX implementations of stat() are generally a bit more
|
|
|
|
forgiving; most will return true for "/foo" and "/foo/"
|
|
|
|
(assuming /foo exists). But we might as well abide by the same
|
|
|
|
rules as Windows and generally disallow checking for names
|
|
|
|
ending with path_sep (the only possible allowable one is
|
|
|
|
checking for "/", which is the root directory, and is
|
|
|
|
guaranteed to exist on valid POSIX filesystems, and is
|
|
|
|
therefore not worth checking for). */
|
|
|
|
|
2005-07-04 04:13:44 +04:00
|
|
|
len = opal_argv_count(parts);
|
2004-11-04 16:35:15 +03:00
|
|
|
for (i = 0; i < len; ++i) {
|
|
|
|
if (i == 0) {
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
/* In the Windows case, check for "<drive>:" case (i.e.,
|
|
|
|
an absolute pathname). If this is the case, ensure
|
|
|
|
that it ends in a path_sep. */
|
|
|
|
|
|
|
|
if (2 == strlen(parts[0]) && isalpha(parts[0][0]) &&
|
|
|
|
':' == parts[0][1]) {
|
|
|
|
strcat(tmp, parts[i]);
|
2005-03-14 23:57:21 +03:00
|
|
|
strcat(tmp, orte_system_info.path_sep);
|
2004-11-04 16:35:15 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Otherwise, it's a relative path. Per the comment
|
|
|
|
above, we don't want a '\' at the end, so just append
|
|
|
|
this part. */
|
|
|
|
|
|
|
|
else {
|
|
|
|
strcat(tmp, parts[i]);
|
|
|
|
}
|
2004-11-03 19:13:58 +03:00
|
|
|
#else
|
2004-11-04 16:35:15 +03:00
|
|
|
/* If in POSIX-land, ensure that we never end a directory
|
|
|
|
name with path_sep */
|
|
|
|
|
|
|
|
if ('/' == path[0]) {
|
2005-03-14 23:57:21 +03:00
|
|
|
strcat(tmp, orte_system_info.path_sep);
|
2004-11-04 16:35:15 +03:00
|
|
|
}
|
|
|
|
strcat(tmp, parts[i]);
|
2004-11-03 03:30:46 +03:00
|
|
|
#endif
|
2004-11-04 16:35:15 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* If it's not the first part, ensure that there's a
|
|
|
|
preceeding path_sep and then append this part */
|
|
|
|
|
|
|
|
else {
|
2005-03-14 23:57:21 +03:00
|
|
|
if (orte_system_info.path_sep[0] != tmp[strlen(tmp) - 1]) {
|
|
|
|
strcat(tmp, orte_system_info.path_sep);
|
2004-11-04 16:35:15 +03:00
|
|
|
}
|
|
|
|
strcat(tmp, parts[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now that we finally have the name to check, check it.
|
|
|
|
Create it if it doesn't exist. */
|
|
|
|
|
|
|
|
if (0 != stat(tmp, &buf)) {
|
2004-11-14 19:55:39 +03:00
|
|
|
if (0 != mkdir(tmp, mode) && 0 != stat(tmp, &buf)) {
|
2005-07-04 04:13:44 +04:00
|
|
|
opal_argv_free(parts);
|
2004-11-04 16:35:15 +03:00
|
|
|
free(tmp);
|
|
|
|
return OMPI_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* All done */
|
2004-05-26 06:23:01 +04:00
|
|
|
|
2005-07-04 04:13:44 +04:00
|
|
|
opal_argv_free(parts);
|
2004-11-04 16:35:15 +03:00
|
|
|
free(tmp);
|
|
|
|
return OMPI_SUCCESS;
|
2004-05-26 06:23:01 +04:00
|
|
|
}
|