commit - 44f8036e904cc038f2370d7f1736e16683f7d128
commit + 0583c4cc97a2206fc4cb5a33bc46d12b934a1c30
blob - 6b02de2bf2ad5e613b4eb9949ed3ef62ef6377b2
blob + e1d4d63874e32cdd55d0cd9b33e4d80650fab772
--- commands.c
+++ commands.c
static int
saveenvcmd(int argc, char **argv)
{
- char path[PATH_MAX];
+ char tmppath[PATH_MAX], path[PATH_MAX];
FILE *f;
char *home;
- int ret;
+ int ret, fd;
if (argc != 1) {
printf("%% usage: saveenv\n");
return 0;
}
- f = fopen(path, "w");
+ ret = snprintf(tmppath, sizeof(tmppath), "%s/.nshenv-XXXXXXXXXX", home);
+ if (ret < 0 || (size_t)ret >= sizeof(tmppath)) {
+ printf("%% path to ~/.nshenv is too long\n");
+ return 0;
+ }
+
+ fd = mkstemp(tmppath);
+ if (fd == -1) {
+ printf("%s: mkstemp %s: %s", __func__, tmppath,
+ strerror(errno));
+ return 0;
+ }
+
+
+ f = fdopen(fd, "w");
if (f == NULL) {
- printf("%% fopen %s: %s\n", path, strerror(errno));
+ printf("%% fopen %s: %s\n", tmppath, strerror(errno));
+ close(fd);
return 0;
}
if (fchmod(fileno(f), S_IRUSR | S_IWUSR) == -1)
- printf("%% chmod 600 %s: %s\n", path, strerror(errno));
+ printf("%% chmod 600 %s: %s\n", tmppath, strerror(errno));
hashtable_foreach(nsh_env, savevar, f);
+
+ if (rename(tmppath, path) == -1) {
+ printf("%% rename %s %s: %s\n", tmppath, path, strerror(errno));
+ if (unlink(tmppath) == -1)
+ printf("%% unlink %s: %s\n", tmppath, strerror(errno));
+ }
+
fclose(f);
return 0;