+#define WX_USR (S_IWUSR | S_IXUSR)
+
+#define CLEANUP_CWD \
+ do \
+ { \
+ /* We're done operating on basename_dir. \
+ Restore working directory. */ \
+ if (do_chdir) \
+ { \
+ if (restore_cwd (&cwd) != 0) \
+ { \
+ int _saved_errno = errno; \
+ error (0, errno, \
+ _("failed to return to initial working directory")); \
+ free_cwd (&cwd); \
+ errno = _saved_errno; \
+ return 1; \
+ } \
+ free_cwd (&cwd); \
+ } \
+ } \
+ while (0)
+
+#define CLEANUP \
+ do \
+ { \
+ umask (oldmask); \
+ CLEANUP_CWD; \
+ } \
+ while (0)
+
+/* Attempt to create directory DIR (aka DIRPATH) with the specified MODE.
+ If CREATED_DIR_P is non-NULL, set *CREATED_DIR_P if this
+ function creates DIR and clear it otherwise. Give a diagnostic and
+ return false if DIR cannot be created or cannot be determined to
+ exist already. Use DIRPATH in any diagnostic, not DIR.
+ Note that if DIR already exists, this function returns true
+ (indicating success) and clears *CREATED_DIR_P. */
+
+bool
+make_dir (const char *dir, const char *dirpath, mode_t mode,
+ bool *created_dir_p)
+{
+ bool ok = true;
+ bool created_dir;
+
+ created_dir = (mkdir (dir, mode) == 0);
+
+ if (!created_dir)
+ {
+ struct stat stats;
+ int saved_errno = errno;
+
+ /* The mkdir and stat calls below may appear to be reversed.
+ They are not. It is important to call mkdir first and then to
+ call stat (to distinguish the three cases) only if mkdir fails.
+ The alternative to this approach is to `stat' each directory,
+ then to call mkdir if it doesn't exist. But if some other process
+ were to create the directory between the stat & mkdir, the mkdir
+ would fail with EEXIST. */
+
+ if (stat (dir, &stats))
+ {
+ error (0, saved_errno, _("cannot create directory %s"),
+ quote (dirpath));
+ ok = false;
+ }
+ else if (!S_ISDIR (stats.st_mode))
+ {
+ error (0, 0, _("%s exists but is not a directory"), quote (dirpath));
+ ok = false;
+ }
+ else
+ {
+ /* DIR (aka DIRPATH) already exists and is a directory. */
+ }
+ }
+
+ if (created_dir_p)
+ *created_dir_p = created_dir;
+
+ return ok;
+}