static void mkdir_all_check(void) { // Check errors are reported assert(-1 == mkdir_all("/no/permission", false)); // Checks multiple / are coallesced char *tmp = tempnam(P_tmpdir, "files_check"); // mkstemp assert(tmp); assert(0 == mkdir_all(tempstr_printf("%s///y//z", tmp), false)); assert(0 == system(tempstr_printf("rm -rf %s", tmp))); }
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; }
static int file_cmd_mkdir(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { while (argc--) { char *path = Jim_StrDup(Jim_String(argv[0])); int rc = mkdir_all(path); Jim_Free(path); if (rc != 0) { Jim_SetResultFormatted(interp, "can't create directory \"%#s\": %s", argv[0], strerror(errno)); return JIM_ERR; } argv++; } return JIM_OK; }
int file_open(char const *file_name, int flags) { int fd = open(file_name, flags, 0644); SLOG(LOG_DEBUG, "Opening file %s into fd %d", file_name, fd); if (fd < 0) { if (errno == ENOENT && flags & O_CREAT) { SLOG(LOG_DEBUG, "Creating missing path for %s", file_name); if (0 != mkdir_all(file_name, true)) return -1; return file_open(file_name, flags); } SLOG(errno == EEXIST && flags & O_EXCL ? LOG_DEBUG : LOG_ERR, "Cannot open file '%s': %s", file_name, strerror(errno)); return -errno; } return fd; }
// Caller must own the capfile->lock static int capfile_open(struct capfile *capfile, char const *path, struct timeval const *now) { if (capture_files >= max_capture_files) { // not thread safe but if the test is not precise this is not a big deal SLOG(LOG_INFO, "Cannot open new capture files: %u already opened", capture_files); return -1; } if (0 != mkdir_all(path, true)) return -1; capfile->fd = file_open(path, O_WRONLY|O_TRUNC|O_CREAT|O_CLOEXEC); if (capfile->fd < 0) return -1; inc_capture_files(); capfile->file_size = 0; capfile->nb_pkts = 0; capfile->start = *now; return 0; }
/** * 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; }