Skip to content

Commit 45d0ac8

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 <explorer09@gmail.com>
1 parent 5893df0 commit 45d0ac8

1 file changed

Lines changed: 55 additions & 5 deletions

File tree

‎Settings.c‎

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ in the source distribution for its full text.
99

1010
#include "Settings.h"
1111

12+
#include <assert.h>
1213
#include <ctype.h>
1314
#include <errno.h>
1415
#include <fcntl.h>
@@ -563,6 +564,51 @@ static bool Settings_read(Settings* this, const char* fileName, const Machine* h
563564
return didReadAny;
564565
}
565566

567+
static int makeAncestorDirectories(char* filePath, size_t len) {
568+
assert(len == strlen(filePath));
569+
570+
// The caller is expected to set the umask before calling this function.
571+
// In particular, if the umask contains S_IWUSR or S_IXUSR bit then the
572+
// making of subdirectories within the ancestor can fail.
573+
574+
int ret = 0;
575+
int savedErr = errno;
576+
577+
char *p = filePath + len;
578+
for (; p > filePath; p--) {
579+
if (*p != '/')
580+
continue;
581+
582+
*p = '\0';
583+
bool ok = !mkdir(filePath, S_IRWXU);
584+
*p = '/';
585+
if (ok)
586+
break;
587+
588+
if (errno != ENOENT)
589+
return -errno;
590+
591+
ret = -errno;
592+
}
593+
if (p <= filePath)
594+
return ret;
595+
596+
errno = savedErr;
597+
598+
while (++p < filePath + len) {
599+
assert(*p);
600+
if (*p != '/')
601+
continue;
602+
603+
*p = '\0';
604+
bool ok = !mkdir(filePath, S_IRWXU);
605+
*p = '/';
606+
if (!ok)
607+
return -errno;
608+
}
609+
return 0;
610+
}
611+
566612
typedef ATTR_FORMAT(printf, 2, 3) int (*OutputFunc)(FILE*, const char*,...);
567613

568614
static void writeFields(OutputFunc of, FILE* fp,
@@ -649,9 +695,15 @@ int Settings_write(const Settings* this, bool onCrash) {
649695
} else if (!this->writeConfig) {
650696
return 0;
651697
} else {
652-
/* create tempfile with mode 0600 */
653-
mode_t cur_umask = umask(S_IXUSR | S_IRWXG | S_IRWXO);
654-
xAsprintf(&tmpFilename, "%s.tmp.XXXXXX", this->filename);
698+
// Prepare temp filename
699+
size_t nameLen = (size_t)xAsprintf(&tmpFilename, "%s.tmp.XXXXXX", this->filename);
700+
701+
// Create ancestor directories with mode 0700
702+
mode_t cur_umask = umask(S_IRWXG | S_IRWXO);
703+
makeAncestorDirectories(tmpFilename, nameLen);
704+
705+
// Create temp file with mode 0600
706+
umask(S_IXUSR | S_IRWXG | S_IRWXO);
655707
int fdtmp = mkstemp(tmpFilename);
656708
umask(cur_umask);
657709
if (fdtmp == -1) {
@@ -851,8 +903,6 @@ Settings* Settings_new(const Machine* host, Hashtable* dynamicMeters, Hashtable*
851903
configDir = String_cat(home, CONFIGDIR);
852904
htopDir = String_cat(home, CONFIGDIR "/htop");
853905
}
854-
(void) mkdir(configDir, 0700);
855-
(void) mkdir(htopDir, 0700);
856906
free(htopDir);
857907
free(configDir);
858908

0 commit comments

Comments
 (0)