fix(fs): resolve temporary directory and handle errors correctly

This commit is contained in:
maelstrom 2026-05-22 09:36:56 +02:00
commit 66dc722e13
2 changed files with 48 additions and 30 deletions

View file

@ -1,12 +1,25 @@
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stddef.h>
#include <linux/limits.h>
#include <limits.h>
#include "onus/fs.h"
int main() {
char tmp[PATH_MAX];
int status = onus_fs_make_tmp(tmp, sizeof(tmp), NULL);
printf("Got status: %d. Path: %s\n", status, tmp);
// onus_fs_del_tmp(tmp);
char tmp[PATH_MAX], tmpfile[PATH_MAX];
FILE *f;
int status;
status = onus_fs_make_tmp(tmp, sizeof(tmp), NULL);
printf("onus_fs_make_tmp: %d. Path: %s\n", status, tmp);
/* TODO: Unsafe code */
sprintf(tmpfile, "%s/test.txt", tmp);
f = fopen(tmpfile, "w");
printf("fopen: %d\n", f ? 0 : errno);
if (f) fclose(f);
status = onus_fs_del_tmp(tmp);
printf("onus_fs_del_tmp: %d\n", status);
return 0;
}

View file

@ -7,27 +7,43 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
/* TODO: Add def for windows */
static const char *kTemporaryDirectoryPathDefault = "/tmp";
int onus_fs_make_tmp(char *path, onus_size_t path_sz, const char *suffix) {
char *npath = NULL;
char *npath = NULL, *tmpdpath = NULL;
const char *tmpdir;
int ret;
if (suffix == NULL) suffix = "";
npath = malloc(strlen(suffix) + 1 + 6);
sprintf(npath, "%sXXXXXX", suffix);
npath = mkdtemp(npath);
/* Determine temporary directory path */
tmpdir = getenv("TMPDIR");
if (tmpdir == NULL) tmpdir = kTemporaryDirectoryPathDefault;
tmpdpath = malloc(PATH_MAX);
if (errno == EACCES) {
ret = ONUS_E_PERMISSION_ERROR;
goto end;
} else if (errno != 0) {
if (realpath(tmpdir, tmpdpath) == NULL) {
ret = ONUS_E_FS_ERROR;
goto end;
}
if (suffix == NULL) suffix = "";
npath = malloc(strlen(tmpdpath) + strlen(suffix) + 8);
sprintf(npath, "%s/%sXXXXXX", tmpdpath, suffix);
if (mkdtemp(npath) == NULL) {
if (errno == EACCES) {
ret = ONUS_E_PERMISSION_ERROR;
goto end;
} else if (errno != 0) {
ret = ONUS_E_FS_ERROR;
goto end;
}
}
if (onus_nstrcpy(path, npath, path_sz) + 1 > path_sz) {
ret = ONUS_E_BUFFER_TOO_SMALL;
goto clean;
goto clean; /* Automatically delete dir on error */
}
ret = ONUS_SUCCESS;
@ -37,30 +53,19 @@ clean:
end:
if (npath)
free(npath);
if (tmpdpath)
free(tmpdpath);
return ret;
}
static int unlink_cb(const char *filename, const struct stat *status, int flag,
struct FTW *info) {
if (!remove(filename))
int err;
if (remove(filename))
return ONUS_E_FS_ERROR;
return 0;
}
/**
* Deletes a temporary directory created using onus_fs_make_tmp. Does not
* perform any checks to guarantee it was created using said function. Be
* careful when using as it could erase non-temporary directories if misused.
* (Will not delete files mounted in subdirectories, and will return
* ONUS_E_FS_ERR instead)
*
* Will stilll return success if the directory is missing, as the user may
* choose to delete it while the program is running
* @param path: Path to temporary directory to delete
* @returns ONUS_SUCCESS if directory was deleted successfully, or no longer
* exists, ONUS_E_PERMISSION_ERROR if failed to delete the requested path,
* ONUS_E_FS_ERR for unspecified file system errors
*/
int onus_fs_del_tmp(const char *path) {
int err;