mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-02-13 19:52:20 +00:00
libast: robustness fixes for temporary files and streams
From an OpenSUSE patch: https://build.opensuse.org/package/view_file/shells/ksh/ksh93-pathtemp.dif See src/lib/libast/man/path.3 for pathtemp() and src/lib/libast/man/sfio.3 for sftmp() src/lib/libast/path/pathtemp.c: - Error check fix: add an access check wrapper function that checks if a path was given and if there is enough free space on the device, setting errno appropriately in case of trouble. src/lib/libast/sfio/sftmp.c: - On Linux, use the /dev/shm shared memory objects for the new temporary file descriptor -- that is, do not access HD or SSD but only the memory based tmpfs of the POSIX SHM.
This commit is contained in:
parent
b12be093d7
commit
db71b3ad43
2 changed files with 62 additions and 3 deletions
|
@ -73,6 +73,7 @@
|
|||
#include <ls.h>
|
||||
#include <tv.h>
|
||||
#include <tm.h>
|
||||
#include <error.h>
|
||||
|
||||
#define ATTEMPT 10
|
||||
|
||||
|
@ -81,7 +82,40 @@
|
|||
#define TMP1 "/tmp"
|
||||
#define TMP2 "/var/tmp"
|
||||
|
||||
#define VALID(d) (*(d)&&!eaccess(d,W_OK|X_OK))
|
||||
static inline int xaccess(const char *path, int mode)
|
||||
{
|
||||
static size_t pgsz;
|
||||
struct statvfs vfs;
|
||||
int ret;
|
||||
|
||||
if (!pgsz)
|
||||
pgsz = strtoul(astconf("PAGESIZE",NiL,NiL),NiL,0);
|
||||
|
||||
if (!path || !*path)
|
||||
{
|
||||
errno = EFAULT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
do
|
||||
ret = statvfs(path, &vfs);
|
||||
while (ret < 0 && errno == EINTR);
|
||||
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
if (vfs.f_frsize*vfs.f_bavail < pgsz)
|
||||
{
|
||||
errno = ENOSPC;
|
||||
goto err;
|
||||
}
|
||||
|
||||
return eaccess(path, mode);
|
||||
err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define VALID(d) (*(d)&&!xaccess(d,W_OK|X_OK))
|
||||
|
||||
static struct
|
||||
{
|
||||
|
@ -182,7 +216,7 @@ pathtemp(char* buf, size_t len, const char* dir, const char* pfx, int* fdp)
|
|||
tv.tv_nsec = 0;
|
||||
else
|
||||
tvgettime(&tv);
|
||||
if (!(d = (char*)dir) || *d && eaccess(d, W_OK|X_OK))
|
||||
if (!(d = (char*)dir) || (*d && xaccess(d, W_OK|X_OK)))
|
||||
{
|
||||
if (!tmp.vec)
|
||||
{
|
||||
|
@ -227,7 +261,7 @@ pathtemp(char* buf, size_t len, const char* dir, const char* pfx, int* fdp)
|
|||
tmp.dir = tmp.vec;
|
||||
d = *tmp.dir++;
|
||||
}
|
||||
if (!d && (!*(d = astconf("TMP", NiL, NiL)) || eaccess(d, W_OK|X_OK)) && eaccess(d = TMP1, W_OK|X_OK) && eaccess(d = TMP2, W_OK|X_OK))
|
||||
if (!d && (!*(d = astconf("TMP", NiL, NiL)) || xaccess(d, W_OK|X_OK)) && xaccess(d = TMP1, W_OK|X_OK) && xaccess(d = TMP2, W_OK|X_OK))
|
||||
return 0;
|
||||
}
|
||||
if (!len)
|
||||
|
|
|
@ -20,6 +20,14 @@
|
|||
* *
|
||||
***********************************************************************/
|
||||
#include "sfhdr.h"
|
||||
#if _PACKAGE_ast
|
||||
# if defined(__linux__) && _lib_statfs
|
||||
# include <sys/statfs.h>
|
||||
# ifndef TMPFS_MAGIC
|
||||
# define TMPFS_MAGIC 0x01021994
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Create a temporary stream for read/write.
|
||||
** The stream is originally created as a memory-resident stream.
|
||||
|
@ -207,7 +215,24 @@ Sfio_t* f;
|
|||
int fd;
|
||||
|
||||
#if _PACKAGE_ast
|
||||
# if defined(__linux__) && _lib_statfs
|
||||
/*
|
||||
* Use the area of POSIX shared memory objects for the new temporary file descriptor
|
||||
* that is do not access HD or SSD but only the memory based tmpfs of the POSIX SHM
|
||||
*/
|
||||
static int doshm;
|
||||
static char *shm = "/dev/shm";
|
||||
if (!doshm)
|
||||
{
|
||||
struct statfs fs;
|
||||
if (statfs(shm, &fs) < 0 || fs.f_type != TMPFS_MAGIC || eaccess(shm, W_OK|X_OK))
|
||||
shm = NiL;
|
||||
doshm++;
|
||||
}
|
||||
if(!(file = pathtemp(NiL,PATH_MAX,shm,"sf",&fd)))
|
||||
# else
|
||||
if(!(file = pathtemp(NiL,PATH_MAX,NiL,"sf",&fd)))
|
||||
# endif
|
||||
return -1;
|
||||
_rmtmp(f, file);
|
||||
free(file);
|
||||
|
|
Loading…
Reference in a new issue