feat(fs): make and delete temp directories
This commit is contained in:
parent
77d1cbf935
commit
5afb5cd843
9 changed files with 168 additions and 12 deletions
|
|
@ -1,3 +1,4 @@
|
|||
add_library(onus_common INTERFACE)
|
||||
add_library(onus::common ALIAS onus_common)
|
||||
target_include_directories(onus_common INTERFACE include)
|
||||
add_library(onuscommon)
|
||||
add_library(onus::common ALIAS onuscommon)
|
||||
target_sources(onuscommon PRIVATE src/str.c)
|
||||
target_include_directories(onuscommon PUBLIC include)
|
||||
|
|
@ -17,5 +17,16 @@
|
|||
#define ONUS_E_PERMISSION_ERROR -3
|
||||
/* Cannot access the specified file because it does not exist */
|
||||
#define ONUS_E_FILE_NOT_FOUND -4
|
||||
/* Cannot copy the string to the buffer because the buffer is too short. Often
|
||||
* this will still partially copy the data, do not rely on the buffer being
|
||||
* unmodified in this state */
|
||||
#define ONUS_E_BUFFER_TOO_SMALL -5
|
||||
/* Generic file system error */
|
||||
#define ONUS_E_FS_ERROR -7
|
||||
|
||||
/* Miscellaneous */
|
||||
|
||||
/* This function is not supported on the running platform */
|
||||
#define ONUS_E_PLATFORM_UNSUPPORTED -6
|
||||
|
||||
#endif /* __LIBONUS_ERR_H */
|
||||
6
pkg/common/include/onus/int.h
Normal file
6
pkg/common/include/onus/int.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef __LIBONUS_INT_H
|
||||
#define __LIBONUS_INT_H
|
||||
|
||||
typedef unsigned long onus_size_t;
|
||||
|
||||
#endif /* __LIBONUS_INT_H */
|
||||
19
pkg/common/include/onus/str.h
Normal file
19
pkg/common/include/onus/str.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef __LIBONUS_STR_H
|
||||
#define __LIBONUS_STR_H
|
||||
|
||||
#include "onus/int.h"
|
||||
|
||||
/**
|
||||
* Copies buffer src into dst with a maximum num characters. If the buffer is
|
||||
* too small, it is automatically NULL-terminated
|
||||
*
|
||||
* @param dst: Destination string buffer
|
||||
* @param src: Source string buffer
|
||||
* @param num: Maximum number of characters to copy from src into dst, including
|
||||
* NULL character
|
||||
* @returns Size of src, excluding NULL character. This can be compared with num
|
||||
* to determine whether copying was sucessful
|
||||
*/
|
||||
onus_size_t onus_nstrcpy(char *dst, const char *src, onus_size_t num);
|
||||
|
||||
#endif /* __LIBONUS_STR_H */
|
||||
11
pkg/common/src/str.c
Normal file
11
pkg/common/src/str.c
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#include <stddef.h>
|
||||
#include "onus/str.h"
|
||||
|
||||
onus_size_t onus_nstrcpy(char *dst, const char *src, onus_size_t num) {
|
||||
onus_size_t i = 0;
|
||||
while (*src != '\0' && i < num)
|
||||
*dst++ = *src++, i++;
|
||||
*dst = '\0';
|
||||
while(*src++ != '\0') i++;
|
||||
return i;
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
add_library(onus_fs)
|
||||
add_library(onus::fs ALIAS onus_fs)
|
||||
target_sources(onus_fs PRIVATE src/copymove.c)
|
||||
target_include_directories(onus_fs PUBLIC include)
|
||||
target_link_libraries(onus_fs PRIVATE onus::common)
|
||||
add_library(onusfs)
|
||||
add_library(onus::fs ALIAS onusfs)
|
||||
target_sources(onusfs PRIVATE src/tmp.c)
|
||||
target_include_directories(onusfs PUBLIC include)
|
||||
target_link_libraries(onusfs PRIVATE onus::common)
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef __LIBONUS_FS_H
|
||||
#define __LIBONUS_FS_H
|
||||
|
||||
#include "onus/int.h"
|
||||
|
||||
/**
|
||||
* Copies a file from one location to another, overwriting if necessary
|
||||
* @param src: Path to original file
|
||||
|
|
@ -8,7 +10,7 @@
|
|||
* @throws ONUS_E_FILE_NOT_FOUND if src does not point to an existing file, or
|
||||
* if dst does not point to a path within an existing directory
|
||||
* @throws ONUS_E_PERMISSION_ERROR if the user does not have permission to read
|
||||
* src or to write to dst
|
||||
* src or to write to dst, ONUS_E_FS_ERR for unspecified file system errors
|
||||
* @returns ONUS_SUCCESS on success
|
||||
*/
|
||||
int onus_fs_copy_file(const char *src, const char *dst);
|
||||
|
|
@ -20,9 +22,43 @@ int onus_fs_copy_file(const char *src, const char *dst);
|
|||
* @throws ONUS_E_FILE_NOT_FOUND if src does not point to an existing file, or
|
||||
* if dst does not point to a path within an existing directory
|
||||
* @throws ONUS_E_PERMISSION_ERROR if the user does not have permission to move
|
||||
* src or to write to dst
|
||||
* src or to write to dst, ONUS_E_FS_ERR for unspecified file system errors
|
||||
* @returns ONUS_SUCCESS on success
|
||||
*/
|
||||
int onus_fs_move_file(const char *src, const char *dst);
|
||||
|
||||
/**
|
||||
* Creates a temporary file directory for storing user files. Directory name is
|
||||
* randomly chosen, but may be suffixed to indicate its source
|
||||
*
|
||||
* Not all platforms automatically clean temporary directories, so you should
|
||||
* delete it using onus_fs_del_tmp
|
||||
* @param path: Output buffer to store temporary file path
|
||||
* @param path_sz: Size of output path buffer (including NULL character)
|
||||
* @param suffix: Suffix to add to temporary directory's name. If NULL, no
|
||||
* suffix will be used
|
||||
* @returns ONUS_SUCCESS on success, ONUS_E_PERMISSION_ERROR if failed to create
|
||||
* temporary directory, ONUS_E_FS_ERR for unspecified file system errors,
|
||||
* ONUS_E_BUFFER_TOO_SMALL if path is not large enough to store the temporary
|
||||
* file path (May overwrite path anyway), ONUS_E_PLATFORM_UNSUPPORTED if
|
||||
* creating temporary directories is not supported on this platform
|
||||
*/
|
||||
int onus_fs_make_tmp(char *path, onus_size_t path_sz, const char *suffix);
|
||||
|
||||
/**
|
||||
* 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 still 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);
|
||||
|
||||
#endif /* __LIBONUS_FS_H */
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
#include "onus/err.h"
|
||||
#include "onus/fs.h"
|
||||
74
pkg/fs/src/tmp.c
Normal file
74
pkg/fs/src/tmp.c
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
#define _XOPEN_SOURCE 2008
|
||||
#include "onus/err.h"
|
||||
#include "onus/fs.h"
|
||||
#include "onus/str.h"
|
||||
#include <errno.h>
|
||||
#include <ftw.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int onus_fs_make_tmp(char *path, onus_size_t path_sz, const char *suffix) {
|
||||
char *npath = NULL;
|
||||
char *tmpname = NULL;
|
||||
int ret;
|
||||
|
||||
tmpname = malloc(strlen(suffix) + 1 + 6);
|
||||
sprintf(tmpname, "%sXXXXXX", suffix);
|
||||
npath = mkdtemp(tmpname);
|
||||
|
||||
if (errno == EACCES) {
|
||||
ret = ONUS_E_PERMISSION_ERROR;
|
||||
goto clean;
|
||||
} else if (errno != 0) {
|
||||
ret = ONUS_E_FS_ERROR;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
if (onus_nstrcpy(path, npath, path_sz) + 1 > path_sz) {
|
||||
ret = ONUS_E_BUFFER_TOO_SMALL;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
ret = ONUS_SUCCESS;
|
||||
clean:
|
||||
if (npath)
|
||||
free(npath);
|
||||
if (tmpname)
|
||||
free(tmpname);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int unlink_cb(const char *filename, const struct stat *status, int flag,
|
||||
struct FTW *info) {
|
||||
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;
|
||||
|
||||
err = nftw(path, unlink_cb, 64, FTW_DEPTH | FTW_PHYS | FTW_MOUNT);
|
||||
|
||||
if (!err || err == ENOENT)
|
||||
return ONUS_SUCCESS;
|
||||
else if (err == EACCES)
|
||||
return ONUS_E_PERMISSION_ERROR;
|
||||
else
|
||||
return ONUS_E_FS_ERROR;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue