-----------------------------------------------------------------------------
| 700 | |
| 701 | //----------------------------------------------------------------------------- |
| 702 | bool Platform::createPath(const char *file) |
| 703 | { |
| 704 | //<Mat> needless console noise |
| 705 | //Con::warnf("creating path %s",file); |
| 706 | // if the path exists, we're done. |
| 707 | struct stat statData; |
| 708 | if( stat(file, &statData) == 0 ) |
| 709 | { |
| 710 | return true; // exists, rejoice. |
| 711 | } |
| 712 | |
| 713 | // get the parent path. |
| 714 | // we're not using basename because it's not thread safe. |
| 715 | const U32 len = dStrlen(file) + 1; |
| 716 | char parent[len]; |
| 717 | bool isDirPath = false; |
| 718 | |
| 719 | dSprintf(parent, len, "%s", file); |
| 720 | |
| 721 | if(parent[len - 2] == '/') |
| 722 | { |
| 723 | parent[len - 2] = '\0'; // cut off the trailing slash, if there is one |
| 724 | isDirPath = true; // we got a trailing slash, so file is a directory. |
| 725 | } |
| 726 | |
| 727 | // recusively create the parent path. |
| 728 | // only recurse if newpath has a slash that isn't a leading slash. |
| 729 | char *slash = dStrrchr(parent,'/'); |
| 730 | if( slash && slash != parent) |
| 731 | { |
| 732 | // snip the path just after the last slash. |
| 733 | slash[1] = '\0'; |
| 734 | // recusively create the parent path. fail if parent path creation failed. |
| 735 | if(!Platform::createPath(parent)) |
| 736 | return false; |
| 737 | } |
| 738 | |
| 739 | // create *file if it is a directory path. |
| 740 | if(isDirPath) |
| 741 | { |
| 742 | // try to create the directory |
| 743 | if( mkdir(file, 0777) != 0) // app may reside in global apps dir, and so must be writable to all. |
| 744 | return false; |
| 745 | } |
| 746 | |
| 747 | return true; |
| 748 | } |
| 749 | |
| 750 | |
| 751 | #pragma mark ---- Directories ---- |