static int FileMkdirCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this, Jsi_Value **ret, Jsi_Func *funcPtr) { Jsi_Value *path = Jsi_ValueArrayIndex(interp, args, 0); Jsi_Value *vf = Jsi_ValueArrayIndex(interp, args, 1); char *spath = Jsi_ValueString(interp, path,0); int rc, force = 0; if (!spath) { Jsi_LogError("expected string"); return JSI_ERROR; } if (vf && !Jsi_ValueIsBoolean(interp, vf)) { Jsi_LogError("expected boolean"); return JSI_ERROR; } if (vf) force = vf->d.val; if (force==0) rc = MKDIR_DEFAULT(spath); else { Jsi_Value *npath = Jsi_ValueNewStringDup(interp, spath); rc = mkdir_all(interp, npath); Jsi_ValueFree(interp, npath); } if (rc != 0) { Jsi_LogError("can't create directory \"%s\": %s", spath, strerror(errno)); return JSI_ERROR; } return JSI_OK; }
static int mkdir_all(Jsi_Interp *interp, Jsi_Value *file) { int ok = 1; char *path = Jsi_ValueString(interp, file, NULL); if (!path) { Jsi_LogError("expected string"); return JSI_ERROR; } /* First time just try to make the dir */ goto first; while (ok--) { /* Must have failed the first time, so recursively make the parent and try again */ { char *slash = strrchr(path, '/'); if (slash && slash != path) { *slash = 0; if (mkdir_all(interp, file) != 0) { return -1; } *slash = '/'; } } first: if (MKDIR_DEFAULT(path) == 0) { return 0; } if (errno == ENOENT) { /* Create the parent and try again */ continue; } /* Maybe it already exists as a directory */ if (errno == EEXIST) { Jsi_StatBuf sb; if (Jsi_Stat(interp, file, &sb) == 0 && S_ISDIR(sb.st_mode)) { return 0; } /* Restore errno */ errno = EEXIST; } /* Failed */ break; } return -1; }
/** * Create directory, creating all intermediate paths if necessary. * * Returns 0 if OK or -1 on failure (and sets errno) * * Note: The path may be modified. */ static int mkdir_all(char *path) { int ok = 1; /* First time just try to make the dir */ goto first; while (ok--) { /* Must have failed the first time, so recursively make the parent and try again */ { char *slash = strrchr(path, '/'); if (slash && slash != path) { *slash = 0; if (mkdir_all(path) != 0) { return -1; } *slash = '/'; } } first: if (MKDIR_DEFAULT(path) == 0) { return 0; } if (errno == ENOENT) { /* Create the parent and try again */ continue; } /* Maybe it already exists as a directory */ if (errno == EEXIST) { struct stat sb; if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { return 0; } /* Restore errno */ errno = EEXIST; } /* Failed */ break; } return -1; }