Skip to content

Commit 7cc12ba

Browse files
committed
Make ancestor directories before writing htoprc
... and don't create config directories when reading the htop config. The new subroutine for creating directories can also work with custom paths specified in HTOPRC environment variable. Signed-off-by: Kang-Che Sung <[email protected]>
1 parent ac1f59c commit 7cc12ba

File tree

1 file changed

+43
-4
lines changed

1 file changed

+43
-4
lines changed

Settings.c

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,41 @@ static bool Settings_read(Settings* this, const char* fileName, const Machine* h
563563
return didReadAny;
564564
}
565565

566+
static int makeAncestorDirectories(char* filePath) {
567+
// The caller is expected to set the umask before calling this function.
568+
// In particular, if the umask contains S_IWUSR or S_IXUSR bit then the
569+
// making of subdirectories within the ancestor can fail.
570+
571+
// 0755 is the maximum permission we can give to directories at this phase.
572+
const mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
573+
574+
bool hasDirectory = false;
575+
int savedErr = errno;
576+
577+
char *p = filePath;
578+
while (true) {
579+
while (*p == '/')
580+
p++;
581+
582+
while (*p && *p != '/')
583+
p++;
584+
585+
if (!*p)
586+
break;
587+
588+
*p = '\0';
589+
bool ok = !mkdir(filePath, mode);
590+
*p = '/';
591+
if (ok) {
592+
hasDirectory = true;
593+
errno = savedErr;
594+
} else if (hasDirectory) {
595+
return -errno;
596+
}
597+
}
598+
return 0;
599+
}
600+
566601
typedef ATTR_FORMAT(printf, 2, 3) int (*OutputFunc)(FILE*, const char*,...);
567602

568603
static void writeFields(OutputFunc of, FILE* fp,
@@ -649,9 +684,15 @@ int Settings_write(const Settings* this, bool onCrash) {
649684
} else if (!this->writeConfig) {
650685
return 0;
651686
} else {
652-
/* create tempfile with mode 0600 */
653-
mode_t cur_umask = umask(S_IXUSR | S_IRWXG | S_IRWXO);
687+
// Prepare temp filename
654688
xAsprintf(&tmpFilename, "%s.tmp.XXXXXX", this->filename);
689+
690+
// Create ancestor directories with mode 0700
691+
mode_t cur_umask = umask(S_IRWXG | S_IRWXO);
692+
makeAncestorDirectories(tmpFilename);
693+
694+
// Create temp file with mode 0600
695+
umask(S_IXUSR | S_IRWXG | S_IRWXO);
655696
int fdtmp = mkstemp(tmpFilename);
656697
umask(cur_umask);
657698
if (fdtmp == -1) {
@@ -851,8 +892,6 @@ Settings* Settings_new(const Machine* host, Hashtable* dynamicMeters, Hashtable*
851892
configDir = String_cat(home, CONFIGDIR);
852893
htopDir = String_cat(home, CONFIGDIR "/htop");
853894
}
854-
(void) mkdir(configDir, 0700);
855-
(void) mkdir(htopDir, 0700);
856895
free(htopDir);
857896
free(configDir);
858897

0 commit comments

Comments
 (0)