added qse_fs_setattr() and related functions

This commit is contained in:
hyung-hwan 2016-12-10 18:08:02 +00:00
parent eea7ef5405
commit 78600e6edc
9 changed files with 806 additions and 131 deletions

30
qse/configure vendored
View File

@ -18650,7 +18650,7 @@ _ACEOF
fi
done
for ac_func in lseek64 stat64 fstat64 lstat64 ftruncate64 readdir64 dirfd
for ac_func in lseek64 ftruncate64 readdir64 dirfd
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@ -18662,7 +18662,31 @@ _ACEOF
fi
done
for ac_func in lstat fchmod fsync ftruncate
for ac_func in stat64 fstat64 lstat64 fstatat64
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
done
for ac_func in fstat fstatat
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
done
for ac_func in fchmod fchmodat fchown fchownat fsync ftruncate
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@ -18686,7 +18710,7 @@ _ACEOF
fi
done
for ac_func in utime utimes futimes lutimes futimens
for ac_func in utime utimes futimes lutimes futimens utimensat
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"

View File

@ -145,10 +145,12 @@ AC_CHECK_FUNCS([mbrlen mbrtowc wcrtomb])
AC_CHECK_FUNCS([mbsnrtowcs mbsrtowcs wcsnrtombs wcsrtombs])
AC_CHECK_FUNCS([wctype iswctype wctrans towctrans])
AC_CHECK_FUNCS([isblank iswblank])
AC_CHECK_FUNCS([lseek64 stat64 fstat64 lstat64 ftruncate64 readdir64 dirfd])
AC_CHECK_FUNCS([lstat fchmod fsync ftruncate])
AC_CHECK_FUNCS([lseek64 ftruncate64 readdir64 dirfd])
AC_CHECK_FUNCS([stat64 fstat64 lstat64 fstatat64])
AC_CHECK_FUNCS([fstat fstatat])
AC_CHECK_FUNCS([fchmod fchmodat fchown fchownat fsync ftruncate])
AC_CHECK_FUNCS([timegm timelocal localtime_r gettimeofday settimeofday])
AC_CHECK_FUNCS([utime utimes futimes lutimes futimens])
AC_CHECK_FUNCS([utime utimes futimes lutimes futimens utimensat])
AC_CHECK_FUNCS([sysconf prctl fdopendir setrlimit getrlimit getpgid getpgrp])
AC_CHECK_FUNCS([backtrace backtrace_symbols])
AC_CHECK_FUNCS([fork vfork posix_spawn gettid nanosleep select])

View File

@ -203,6 +203,15 @@
/* Define to 1 if you have the `fchmod' function. */
#undef HAVE_FCHMOD
/* Define to 1 if you have the `fchmodat' function. */
#undef HAVE_FCHMODAT
/* Define to 1 if you have the `fchown' function. */
#undef HAVE_FCHOWN
/* Define to 1 if you have the `fchownat' function. */
#undef HAVE_FCHOWNAT
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
@ -236,9 +245,18 @@
/* Define to 1 if you have the `fork' function. */
#undef HAVE_FORK
/* Define to 1 if you have the `fstat' function. */
#undef HAVE_FSTAT
/* Define to 1 if you have the `fstat64' function. */
#undef HAVE_FSTAT64
/* Define to 1 if you have the `fstatat' function. */
#undef HAVE_FSTATAT
/* Define to 1 if you have the `fstatat64' function. */
#undef HAVE_FSTATAT64
/* Define to 1 if you have the `fsync' function. */
#undef HAVE_FSYNC
@ -356,9 +374,6 @@
/* Define to 1 if you have the `lseek64' function. */
#undef HAVE_LSEEK64
/* Define to 1 if you have the `lstat' function. */
#undef HAVE_LSTAT
/* Define to 1 if you have the `lstat64' function. */
#undef HAVE_LSTAT64
@ -745,6 +760,9 @@
/* Define to 1 if you have the `utime' function. */
#undef HAVE_UTIME
/* Define to 1 if you have the `utimensat' function. */
#undef HAVE_UTIMENSAT
/* Define to 1 if you have the `utimes' function. */
#undef HAVE_UTIMES

View File

@ -140,6 +140,28 @@ struct qse_fs_attr_t
typedef struct qse_fs_attr_t qse_fs_attr_t;
enum qse_fs_getattr_flag_t
{
QSE_FS_GETATTR_SYMLINK = (1 << 15)
};
typedef enum qse_fs_getattr_flag_t qse_fs_getattr_flag_t;
enum qse_fs_setattr_flag_t
{
QSE_FS_SETATTR_TIME = (1 << 0),
QSE_FS_SETATTR_OWNER = (1 << 1),
QSE_FS_SETATTR_MODE = (1 << 2),
QSE_FS_SETATTR_SYMLINK = (1 << 15) /* work on the symbolic link itself. don't follow */
};
typedef enum qse_fs_setattr_flag_t qse_fs_setattr_flag_t;
#if defined(_WIN32)
typedef void* qse_fs_handle_t;
#else
typedef int qse_fs_handle_t;
#endif
typedef struct qse_fs_t qse_fs_t;
enum qse_fs_trait_t
@ -206,13 +228,14 @@ enum qse_fs_cpfile_flag_t
QSE_FS_CPFILE_FORCE = (1 << 2),
QSE_FS_CPFILE_PRESERVE = (1 << 3),
QSE_FS_CPFILE_REPLACE = (1 << 4),
QSE_FS_CPFILE_SYMLINK = (1 << 5),
QSE_FS_CPFILE_NOTGTDIR = (1 << 6), /* no target directory */
QSE_FS_CPFILE_NOTGTDIR = (1 << 5), /* no target directory */
QSE_FS_CPFILE_SYMLINK = (1 << 15),
QSE_FS_CPFILE_ALL = (QSE_FS_CPFILE_GLOB | QSE_FS_CPFILE_RECURSIVE |
QSE_FS_CPFILE_FORCE | QSE_FS_CPFILE_PRESERVE |
QSE_FS_CPFILE_REPLACE | QSE_FS_CPFILE_SYMLINK |
QSE_FS_CPFILE_NOTGTDIR)
QSE_FS_CPFILE_REPLACE | QSE_FS_CPFILE_NOTGTDIR |
QSE_FS_CPFILE_SYMLINK)
};
typedef enum qse_fs_cpfile_flag_t qse_fs_cpfile_flag_t;
@ -317,24 +340,64 @@ QSE_EXPORT int qse_fs_pop (
const qse_char_t* name
);
QSE_EXPORT int qse_fs_getattronfd (
qse_fs_t* fs,
qse_fs_handle_t fd,
qse_fs_attr_t* attr,
int flags
);
QSE_EXPORT int qse_fs_setattronfd (
qse_fs_t* fs,
qse_fs_handle_t fd,
const qse_fs_attr_t* attr,
int flags /** bitwise-ORed #qse_fs_setattr_flag_t enumerators */
);
QSE_EXPORT int qse_fs_getattrmbs (
qse_fs_t* fs,
const qse_mchar_t* path,
qse_fs_attr_t* attr
qse_fs_attr_t* attr,
int flags
);
QSE_EXPORT int qse_fs_getattrwcs (
qse_fs_t* fs,
const qse_wchar_t* path,
qse_fs_attr_t* attr
qse_fs_attr_t* attr,
int flags
);
QSE_EXPORT int qse_fs_setattrmbs (
qse_fs_t* fs,
qse_mchar_t* path,
const qse_fs_attr_t* attr,
int flags /** bitwise-ORed #qse_fs_setattr_flag_t enumerators */
);
QSE_EXPORT int qse_fs_setattrwcs (
qse_fs_t* fs,
qse_wchar_t* path,
const qse_fs_attr_t* attr,
int flags /** bitwise-ORed #qse_fs_setattr_flag_t enumerators */
);
#if defined(QSE_CHAR_IS_MCHAR)
# define qse_fs_getattr(fs,path,attr) qse_fs_getattrmbs(fs,path,attr)
# define qse_fs_getattr(fs,path,attr,flags) qse_fs_getattrmbs(fs,path,attr,flags)
# define qse_fs_setattr(fs,path,attr,flags) qse_fssetattrmbs(fs,path,attr,flags)
#else
# define qse_fs_getattr(fs,path,attr) qse_fs_getattrwcs(fs,path,attr)
# define qse_fs_getattr(fs,path,attr,flags) qse_fs_getattrwcs(fs,path,attr,flags)
# define qse_fs_setattr(fs,path,attr,flags) qse_fssetattrwcs(fs,path,attr,flags)
#endif
QSE_EXPORT int qse_fs_move (
qse_fs_t* fs,
const qse_char_t* oldpath,
@ -408,6 +471,10 @@ QSE_EXPORT int qse_fs_deldirwcs (
# define qse_fs_deldir(fs,path,flags) qse_fs_deldirwcs(fs,path,flags)
#endif
#if defined(__cplusplus)
}
#endif

View File

@ -114,20 +114,6 @@
# define QSE_LSEEK(handle,offset,whence) lseek(handle,offset,whence)
#endif
#if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(SYS_fstat64) && defined(QSE_USE_SYSCALL)
# define QSE_FSTAT(handle,stbuf) syscall(SYS_fstat64,handle,stbuf)
typedef struct stat64 qse_fstat_t;
#elif defined(SYS_fstat) && defined(QSE_USE_SYSCALL)
# define QSE_FSTAT(handle,stbuf) syscall(SYS_fstat,handle,stbuf)
typedef struct stat qse_fstat_t;
#elif !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_FSTAT64)
# define QSE_FSTAT(handle,stbuf) fstat64(handle,stbuf)
typedef struct stat64 qse_fstat_t;
#else
# define QSE_FSTAT(handle,stbuf) fstat(handle,stbuf)
typedef struct stat qse_fstat_t;
#endif
#if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(SYS_ftruncate64) && defined(QSE_USE_SYSCALL)
# define QSE_FTRUNCATE(handle,size) syscall(SYS_ftruncate64,handle,size)
#elif defined(SYS_ftruncate) && defined(QSE_USE_SYSCALL)
@ -138,18 +124,6 @@
# define QSE_FTRUNCATE(handle,size) ftruncate(handle,size)
#endif
#if defined(SYS_fchmod) && defined(QSE_USE_SYSCALL)
# define QSE_FCHMOD(handle,mode) syscall(SYS_fchmod,handle,mode)
#else
# define QSE_FCHMOD(handle,mode) fchmod(handle,mode)
#endif
#if defined(SYS_fchown) && defined(QSE_USE_SYSCALL)
# define QSE_FCHOWN(handle,owner,group) syscall(SYS_fchown,handle,owner,group)
#else
# define QSE_FCHOWN(handle,owner,group) fchown(handle,owner,group)
#endif
#if defined(SYS_fsync) && defined(QSE_USE_SYSCALL)
# define QSE_FSYNC(handle) syscall(SYS_fsync,handle)
#else
@ -285,12 +259,36 @@
# define QSE_CHMOD(path,mode) chmod(path,mode)
#endif
#if defined(SYS_fchmod) && defined(QSE_USE_SYSCALL)
# define QSE_FCHMOD(handle,mode) syscall(SYS_fchmod,handle,mode)
#else
# define QSE_FCHMOD(handle,mode) fchmod(handle,mode)
#endif
#if defined(SYS_fchmodat) && defined(QSE_USE_SYSCALL)
# define QSE_FCHMODAT(dirfd,path,mode,flags) syscall(SYS_fchmodat,dirfd,path,mode,flags)
#else
# define QSE_FCHMODAT(dirfd,path,mode,flags) fchmodat(dirfd,path,mode,flags)
#endif
#if defined(SYS_chown) && defined(QSE_USE_SYSCALL)
# define QSE_CHOWN(path,owner,group) syscall(SYS_chown,path,owner,group)
#else
# define QSE_CHOWN(path,owner,group) chown(path,owner,group)
#endif
#if defined(SYS_fchown) && defined(QSE_USE_SYSCALL)
# define QSE_FCHOWN(handle,owner,group) syscall(SYS_fchown,handle,owner,group)
#else
# define QSE_FCHOWN(handle,owner,group) fchown(handle,owner,group)
#endif
#if defined(SYS_fchownat) && defined(QSE_USE_SYSCALL)
# define QSE_FCHOWNAT(dirfd,path,uid,gid,flags) syscall(SYS_fchownat,dirfd,path,uid,gid,flags)
#else
# define QSE_FCHOWNAT(dirfd,path,uid,gid,flags) fchownat(dirfd,path,uid,gid,flags)
#endif
#if defined(SYS_chroot) && defined(QSE_USE_SYSCALL)
# define QSE_CHROOT(path) syscall(SYS_chroot,path)
#else
@ -309,6 +307,35 @@
# define QSE_LINK(oldpath,newpath) link(oldpath,newpath)
#endif
#if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(SYS_fstat64) && defined(QSE_USE_SYSCALL)
# define QSE_FSTAT(handle,stbuf) syscall(SYS_fstat64,handle,stbuf)
typedef struct stat64 qse_fstat_t;
#elif defined(SYS_fstat) && defined(QSE_USE_SYSCALL)
# define QSE_FSTAT(handle,stbuf) syscall(SYS_fstat,handle,stbuf)
typedef struct stat qse_fstat_t;
#elif !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_FSTAT64)
# define QSE_FSTAT(handle,stbuf) fstat64(handle,stbuf)
typedef struct stat64 qse_fstat_t;
#else
# define QSE_FSTAT(handle,stbuf) fstat(handle,stbuf)
typedef struct stat qse_fstat_t;
#endif
#if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(SYS_stat64) && defined(QSE_USE_SYSCALL)
# define QSE_STAT(path,stbuf) syscall(SYS_stat64,path,stbuf)
typedef struct stat64 qse_stat_t;
#elif defined(SYS_stat) && defined(QSE_USE_SYSCALL)
# define QSE_STAT(path,stbuf) syscall(SYS_stat,path,stbuf)
typedef struct stat qse_stat_t;
#elif !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_STAT64)
# define QSE_STAT(path,stbuf) stat64(path,stbuf)
typedef struct stat64 qse_stat_t;
#else
# define QSE_STAT(path,stbuf) stat(path,stbuf)
typedef struct stat qse_stat_t;
#endif
#if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(SYS_lstat64) && defined(QSE_USE_SYSCALL)
# define QSE_LSTAT(path,stbuf) syscall(SYS_lstat,path,stbuf)
typedef struct stat64 qse_lstat_t;
@ -323,6 +350,21 @@
typedef struct stat qse_lstat_t;
#endif
#if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(SYS_fstatat64) && defined(QSE_USE_SYSCALL)
# define QSE_FSTATAT(dirfd,path,stbuf,flags) syscall(SYS_fstatat,dirfd,path,stbuf,flags)
typedef struct stat64 qse_fstatat_t;
#elif defined(SYS_fstatat) && defined(QSE_USE_SYSCALL)
# define QSE_FSTATAT(dirfd,path,stbuf,flags) syscall(SYS_fstatat,dirfd,path,stbuf,flags)
typedef struct stat qse_fstatat_t;
#elif !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_FSTATAT64)
# define QSE_FSTATAT(dirfd,path,stbuf,flags) fstatat64(dirfd,path,stbuf,flags)
typedef struct stat64 qse_fstatat_t;
#else
# define QSE_FSTATAT(dirfd,path,stbuf,flags) fstatat(dirfd,path,stbuf,flags)
typedef struct stat qse_fstatat_t;
#endif
#if defined(SYS_access) && defined(QSE_USE_SYSCALL)
# define QSE_ACCESS(path,mode) syscall(SYS_access,path,mode)
#else
@ -348,20 +390,6 @@
# define QSE_RMDIR(path) rmdir(path)
#endif
#if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(SYS_stat64) && defined(QSE_USE_SYSCALL)
# define QSE_STAT(path,stbuf) syscall(SYS_stat64,path,stbuf)
typedef struct stat64 qse_stat_t;
#elif defined(SYS_stat) && defined(QSE_USE_SYSCALL)
# define QSE_STAT(path,stbuf) syscall(SYS_stat,path,stbuf)
typedef struct stat qse_stat_t;
#elif !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_STAT64)
# define QSE_STAT(path,stbuf) stat64(path,stbuf)
typedef struct stat64 qse_stat_t;
#else
# define QSE_STAT(path,stbuf) stat(path,stbuf)
typedef struct stat qse_stat_t;
#endif
#if defined(SYS_symlink) && defined(QSE_USE_SYSCALL)
# define QSE_SYMLINK(oldpath,newpath) syscall(SYS_symlink,oldpath,newpath)
#else
@ -410,6 +438,12 @@
# define QSE_FUTIMENS(fd,t) futimens(fd,t)
#endif
#if defined(SYS_utimensat) && defined(QSE_USE_SYSCALL)
# define QSE_FUTIMENS(dirfd,path,times,flags) syscall(SYS_futimens,dirfd,path,times,flags)
#else
# define QSE_UTIMENSAT(dirfd,path,times,flags) utimensat(dirfd,path,times,flags)
#endif
/* ===== DIRECTORY - not really system calls ===== */
#define QSE_OPENDIR(name) opendir(name)
#define QSE_CLOSEDIR(dir) closedir(dir)

View File

@ -1122,7 +1122,7 @@ static int task_init_proxy (qse_httpd_t* httpd, qse_httpd_client_t* client, qse_
/* length must include the parameters also */
proxy->qpath_len_in_reqfwdbuf = QSE_STR_LEN(proxy->reqfwdbuf) - proxy->qpath_pos_in_reqfwdbuf;
#if 0
#if 1
{
/* EXPERIMENTAL */
/* KT FILTERING WORKAROUND POC. KT seems to check the Host: the first packet

View File

@ -27,7 +27,164 @@
#include "fs-prv.h"
#include "../cmn/mem-prv.h"
int qse_fs_sysgetattr (qse_fs_t* fs, const qse_fs_char_t* fspath, qse_fs_attr_t* attr)
static void stat_to_attr (const qse_stat_t* st, qse_fs_attr_t* attr)
{
QSE_MEMSET (attr, 0, QSE_SIZEOF(*attr));
if (S_ISDIR(st->st_mode)) attr->isdir = 1;
if (S_ISLNK(st->st_mode)) attr->islnk = 1;
if (S_ISREG(st->st_mode)) attr->isreg = 1;
if (S_ISBLK(st->st_mode)) attr->isblk = 1;
if (S_ISCHR(st->st_mode)) attr->ischr = 1;
attr->mode = st->st_mode;
attr->size = st->st_size;
attr->ino = st->st_ino;
attr->dev = st->st_dev;
attr->uid = st->st_uid;
attr->gid = st->st_gid;
#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
attr->atime.sec = st->st_atim.tv_sec;
attr->atime.nsec = st->st_atim.tv_nsec;
attr->mtime.sec = st->st_mtim.tv_sec;
attr->mtime.nsec = st->st_mtim.tv_nsec;
attr->ctime.sec = st->st_ctim.tv_sec;
attr->ctime.nsec = st->st_ctim.tv_nsec;
#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
attr->atime.sec = st->st_atimespec.tv_sec;
attr->atime.nsec = st->st_atimespec.tv_nsec;
attr->mtime.sec = st->st_mtimespec.tv_sec;
attr->mtime.nsec = st->st_mtimespec.tv_nsec;
attr->ctime.sec = st->st_ctimespec.tv_sec;
attr->ctime.nsec = st->st_ctimespec.tv_nsec;
#else
attr->atime.sec = st->st_atime;
attr->mtime.sec = st->st_mtime;
attr->ctime.sec = st->st_ctime;
#endif
}
int qse_fs_getattronfd (qse_fs_t* fs, qse_fs_handle_t fd, qse_fs_attr_t* attr, int flags)
{
#if defined(_WIN32)
fs->errnum = QSE_FS_ENOIMPL;
return -1;
#elif defined(__OS2__)
/* TODO */
fs->errnum = QSE_FS_ENOIMPL;
return -1;
#elif defined(__DOS__)
fs->errnum = QSE_FS_ENOIMPL;
return -1;
#elif defined(HAVE_FSTAT)
qse_fstat_t st;
if (QSE_FSTAT (fd, &st) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
stat_to_attr (&st, attr);
return 0;
#else
fs->errnum = QSE_FS_ENOIMPL;
return -1;
#endif
}
int qse_fs_getattrsys (qse_fs_t* fs, const qse_fs_char_t* fspath, qse_fs_attr_t* attr, int flags)
{
#if defined(_WIN32)
fs->errnum = QSE_FS_ENOIMPL;
return -1;
#elif defined(__OS2__)
/* TODO */
fs->errnum = QSE_FS_ENOIMPL;
return -1;
#elif defined(__DOS__)
fs->errnum = QSE_FS_ENOIMPL;
return -1;
#elif defined(HAVE_FSTATAT)
qse_fstatat_t st;
int sysflags = 0;
if (flags & QSE_FS_GETATTR_SYMLINK) sysflags |= AT_SYMLINK_NOFOLLOW;
if (QSE_FSTATAT(AT_FDCWD, fspath, &st, sysflags) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
stat_to_attr (&st, attr);
return 0;
#else
qse_stat_t st;
int x;
if (flags & QSE_FS_GETATTR_SYMLINK)
x = QSE_LSTAT (fspath, &st);
else
x = QSE_STAT (fspath, &st);
if (x <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
stat_to_attr (&st, attr);
return 0;
#endif
}
int qse_fs_getattrmbs (qse_fs_t* fs, const qse_mchar_t* path, qse_fs_attr_t* attr, int flags)
{
qse_fs_char_t* fspath;
int ret;
fspath = qse_fs_makefspathformbs (fs, path);
if (!fspath) return -1;
ret = qse_fs_getattrsys (fs, fspath, attr, flags);
qse_fs_freefspathformbs (fs, path, fspath);
return ret;
}
int qse_fs_getattrwcs (qse_fs_t* fs, const qse_wchar_t* path, qse_fs_attr_t* attr, int flags)
{
qse_fs_char_t* fspath;
int ret;
fspath = qse_fs_makefspathforwcs (fs, path);
if (!fspath) return -1;
ret = qse_fs_getattrsys (fs, fspath, attr, flags);
qse_fs_freefspathforwcs (fs, path, fspath);
return ret;
}
/* -------------------------------------------------------------------------- */
int qse_fs_setattronfd (qse_fs_t* fs, qse_fs_handle_t fd, const qse_fs_attr_t* attr, int flags)
{
#if defined(_WIN32)
@ -46,66 +203,235 @@ int qse_fs_sysgetattr (qse_fs_t* fs, const qse_fs_char_t* fspath, qse_fs_attr_t*
return -1;
#else
#if defined(HAVE_LSTAT)
qse_lstat_t st;
#else
qse_stat_t st;
#endif
#if defined(HAVE_LSTAT)
if (QSE_LSTAT (fspath, &st) == -1)
if (flags & QSE_FS_SETATTR_TIME)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#if defined(HAVE_FUTIMENS) && defined(HAVE_STRUCT_TIMESPEC)
struct timespec ts[2];
QSE_MEMSET (&ts, 0, QSE_SIZEOF(ts));
ts[0].tv_sec = attr->atime.sec;
ts[0].tv_nsec = attr->atime.nsec;
ts[1].tv_sec = attr->mtime.sec;
ts[1].tv_nsec = attr->mtime.nsec;
if (QSE_FUTIMENS (fd, ts) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#elif defined(HAVE_FUTIMES)
struct timeval tv[2];
QSE_MEMSET (&tv, 0, QSE_SIZEOF(tv));
tv[0].tv_sec = attr->atime.sec;
tv[0].tv_usec = QSE_NSEC_TO_USEC(attr->atime.nsec);
tv[1].tv_sec = attr->mtime.sec;
tv[1].tv_usec = QSE_NSEC_TO_USEC(attr->mtime.nsec);
if (QSE_FUTIMES (fspath, tv) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#else
/* is this ok to use stat? */
if (QSE_STAT (fspath, &st) == -1)
fs->errnum = QSE_FS_ENOIMPL;
return -1;
#endif
}
if (flags & QSE_FS_SETATTR_OWNER)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#endif
QSE_MEMSET (attr, 0, QSE_SIZEOF(*attr));
if (S_ISDIR(st.st_mode)) attr->isdir = 1;
if (S_ISLNK(st.st_mode)) attr->islnk = 1;
if (S_ISREG(st.st_mode)) attr->isreg = 1;
if (S_ISBLK(st.st_mode)) attr->isblk = 1;
if (S_ISCHR(st.st_mode)) attr->ischr = 1;
attr->mode = st.st_mode;
attr->size = st.st_size;
attr->ino = st.st_ino;
attr->dev = st.st_dev;
attr->uid = st.st_uid;
attr->gid = st.st_gid;
#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
attr->atime.sec = st.st_atim.tv_sec;
attr->atime.nsec = st.st_atim.tv_nsec;
attr->mtime.sec = st.st_mtim.tv_sec;
attr->mtime.nsec = st.st_mtim.tv_nsec;
attr->ctime.sec = st.st_ctim.tv_sec;
attr->ctime.nsec = st.st_ctim.tv_nsec;
#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
attr->atime.sec = st.st_atimespec.tv_sec;
attr->atime.nsec = st.st_atimespec.tv_nsec;
attr->mtime.sec = st.st_mtimespec.tv_sec;
attr->mtime.nsec = st.st_mtimespec.tv_nsec;
attr->ctime.sec = st.st_ctimespec.tv_sec;
attr->ctime.nsec = st.st_ctimespec.tv_nsec;
#if defined(HAVE_FCHOWN)
if (QSE_FCHOWN (fd, attr->uid, attr->gid) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#else
attr->atime.sec = st.st_atime;
attr->mtime.sec = st.st_mtime;
attr->ctime.sec = st.st_ctime;
fs->errnum = QSE_FS_ENOIMPL;
return -1;
#endif
}
if (flags & QSE_FS_SETATTR_MODE)
{
#if defined(HAVE_FCHMOD)
if (QSE_FCHMOD(fd, attr->mode) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#else
fs->errnum = QSE_FS_ENOIMPL;
return -1;
#endif
}
return 0;
#endif
}
int qse_fs_getattrmbs (qse_fs_t* fs, const qse_mchar_t* path, qse_fs_attr_t* attr)
int qse_fs_setattrsys (qse_fs_t* fs, qse_fs_char_t* path, const qse_fs_attr_t* attr, int flags)
{
#if defined(_WIN32)
fs->errnum = QSE_FS_ENOIMPL;
return -1;
#elif defined(__OS2__)
/* TODO */
fs->errnum = QSE_FS_ENOIMPL;
return -1;
#elif defined(__DOS__)
fs->errnum = QSE_FS_ENOIMPL;
return -1;
#else
if (flags & QSE_FS_SETATTR_TIME)
{
#if defined(HAVE_UTIMENSAT)
struct timespec ts[2];
int sysflags = 0;
if (flags & QSE_FS_SETATTR_SYMLINK) sysflags |= AT_SYMLINK_NOFOLLOW;
QSE_MEMSET (&ts, 0, QSE_SIZEOF(ts));
ts[0].tv_sec = attr->atime.sec;
ts[0].tv_nsec = attr->atime.nsec;
ts[1].tv_sec = attr->mtime.sec;
ts[1].tv_nsec = attr->mtime.nsec;
if (QSE_UTIMENSAT(AT_FDCWD, path, NULL, sysflags) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#else
if (flags & QSE_FS_SETATTR_SYMLINK)
{
#if defined(HAVE_LUTIMES)
struct timeval tv[2];
QSE_MEMSET (&tv, 0, QSE_SIZEOF(tv));
tv[0].tv_sec = attr->atime.sec;
tv[0].tv_usec = QSE_NSEC_TO_USEC(attr->atime.nsec);
tv[1].tv_sec = attr->mtime.sec;
tv[1].tv_usec = QSE_NSEC_TO_USEC(attr->mtime.nsec);
if (QSE_LUTIMES (path, tv) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#else
fs->errnum = QSE_FS_ENOIMPL;
return -1;
#endif
}
else
{
#if defined(HAVE_UTIMES)
struct timeval tv[2];
QSE_MEMSET (&tv, 0, QSE_SIZEOF(tv));
tv[0].tv_sec = attr->atime.sec;
tv[0].tv_usec = QSE_NSEC_TO_USEC(attr->atime.nsec);
tv[1].tv_sec = attr->mtime.sec;
tv[1].tv_usec = QSE_NSEC_TO_USEC(attr->mtime.nsec);
if (QSE_UTIMES (path, tv) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#elif defined(HAVE_UTIME)
struct utimbuf ub;
QSE_MEMSET (&ub, 0, QSE_SIZEOF(ub));
ub.actime = attr->atime.sec;
ub.modtime = attr->mtime.sec;
if (QSE_UTIME (path, &ub) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#else
fs->errnum = QSE_FS_ENOIMPL;
return -1;
#endif
}
#endif
}
if (flags & QSE_FS_SETATTR_OWNER)
{
#if defined(QSE_FCHOWNAT)
int sysflags = 0;
if (flags & QSE_FS_SETATTR_SYMLINK) sysflags |= AT_SYMLINK_NOFOLLOW;
if (QSE_FCHOWNAT(AT_FDCWD, path, attr->uid, attr->gid, sysflags) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#else
int x;
if (flags & QSE_FS_SETATTR_SYMLINK)
x = QSE_LCHOWN (path, attr->uid, attr->gid);
else
x = QSE_CHOWN (path, attr->uid, attr->gid);
if (x <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#endif
}
if (flags & QSE_FS_SETATTR_MODE)
{
#if defined(QSE_FCHMODAT)
int sysflags = 0;
if (flags & QSE_FS_SETATTR_SYMLINK) sysflags |= AT_SYMLINK_NOFOLLOW;
if (QSE_FCHMODAT(AT_FDCWD, path, attr->mode, sysflags) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
#else
if (flags & QSE_FS_SETATTR_SYMLINK)
{
/* not supported. symlink permission is kind of fixed.
* do nothing */
}
else
{
if (QSE_CHMOD(path, attr->mode) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
return -1;
}
}
#endif
}
return 0;
#endif
}
int qse_fs_setattrmbs (qse_fs_t* fs, qse_mchar_t* path, const qse_fs_attr_t* attr, int flags)
{
qse_fs_char_t* fspath;
int ret;
@ -113,13 +439,14 @@ int qse_fs_getattrmbs (qse_fs_t* fs, const qse_mchar_t* path, qse_fs_attr_t* att
fspath = qse_fs_makefspathformbs (fs, path);
if (!fspath) return -1;
ret = qse_fs_sysgetattr (fs, fspath, attr);
ret = qse_fs_setattrsys (fs, fspath, attr, flags);
qse_fs_freefspathformbs (fs, path, fspath);
return ret;
}
int qse_fs_getattrwcs (qse_fs_t* fs, const qse_wchar_t* path, qse_fs_attr_t* attr)
int qse_fs_setattrwcs (qse_fs_t* fs, qse_wchar_t* path, const qse_fs_attr_t* attr, int flags)
{
qse_fs_char_t* fspath;
int ret;
@ -127,7 +454,7 @@ int qse_fs_getattrwcs (qse_fs_t* fs, const qse_wchar_t* path, qse_fs_attr_t* att
fspath = qse_fs_makefspathforwcs (fs, path);
if (!fspath) return -1;
ret = qse_fs_sysgetattr (fs, fspath, attr);
ret = qse_fs_setattrsys (fs, fspath, attr, flags);
qse_fs_freefspathforwcs (fs, path, fspath);
return ret;

View File

@ -38,10 +38,8 @@
struct cpfile_t
{
int flags;
qse_fs_char_t* src_fspath;
qse_fs_char_t* dst_fspath;
qse_fs_attr_t src_attr;
qse_fs_attr_t dst_attr;
};
@ -67,7 +65,8 @@ static int merge_dstdir_and_file (qse_fs_t* fs, cpfile_t* cpfile)
qse_fs_freefspath (fs, QSE_NULL, cpfile->dst_fspath);
cpfile->dst_fspath = fstmp;
if (qse_fs_sysgetattr (fs, cpfile->dst_fspath, &cpfile->dst_attr) <= -1)
/* TODO: check on the flags to getattrsys()... */
if (qse_fs_getattrsys (fs, cpfile->dst_fspath, &cpfile->dst_attr, 0) <= -1)
{
/* attribute on the new destination is not available */
cpfile->flags &= ~CPFILE_DST_ATTR;
@ -280,17 +279,6 @@ static int copy_file_in_fs (qse_fs_t* fs, cpfile_t* cpfile)
goto oops;
}
#elif defined(HAVE_UTIME)
QSE_MEMSET (&ub, 0, QSE_SIZEOF(ub));
ub.actime = cpfile->src_attr.atime.sec;
ub.modtime = cpfile->src_attr.mtime.sec;
if (QSE_UTIME (cpfile->dst_fspath, &ub) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
goto oops;
}
#elif defined(HAVE_UTIMES)
QSE_MEMSET (&tv, 0, QSE_SIZEOF(tv));
@ -305,6 +293,17 @@ static int copy_file_in_fs (qse_fs_t* fs, cpfile_t* cpfile)
goto oops;
}
#elif defined(HAVE_UTIME)
QSE_MEMSET (&ub, 0, QSE_SIZEOF(ub));
ub.actime = cpfile->src_attr.atime.sec;
ub.modtime = cpfile->src_attr.mtime.sec;
if (QSE_UTIME (cpfile->dst_fspath, &ub) <= -1)
{
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
goto oops;
}
#else
# error none of futimens, futimes, utime, utimes exist
#endif
@ -327,8 +326,9 @@ static int prepare_cpfile (qse_fs_t* fs, cpfile_t* cpfile)
{
/* error if the source file can't be stat'ed.
* ok if the destination file can't be stat'ed */
if (qse_fs_sysgetattr (fs, cpfile->src_fspath, &cpfile->src_attr) <= -1) return -1;
if (qse_fs_sysgetattr (fs, cpfile->dst_fspath, &cpfile->dst_attr) >= 0) cpfile->flags |= CPFILE_DST_ATTR;
/* TODO: check on flags to getattrsys() */
if (qse_fs_getattrsys (fs, cpfile->src_fspath, &cpfile->src_attr, 0) <= -1) return -1;
if (qse_fs_getattrsys (fs, cpfile->dst_fspath, &cpfile->dst_attr, 0) >= 0) cpfile->flags |= CPFILE_DST_ATTR;
return 0;
}
@ -634,3 +634,198 @@ oops:
clear_cpfile (fs, &cpfile);
return -1;
}
#if 0
/* --------------------------------------------------------------------- */
/*
* Copyright (c) 1983 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
static int copy (const char* from, const char* to)
{
int fold, fnew, n, exists;
char *last, destname[MAXPATHLEN + 1], buf[MAXBSIZE];
struct stat stfrom, stto;
fold = open (from, O_RDONLY);
if (fold < 0)
{
return -1;
}
if (fstat(fold, &stfrom) < 0)
{
close(fold);
return -1;
}
if (stat(to, &stto) >= 0 && (stto.st_mode&S_IFMT) == S_IFDIR)
{
last = rindex(from, '/');
if (last) last++; else last = from;
if (strlen(to) + strlen(last) >= sizeof(destname) - 1)
{
/* name too long */
close(fold);
return(1);
}
(void) sprintf(destname, "%s/%s", to, last);
to = destname;
}
if (rflag && (stfrom.st_mode&S_IFMT) == S_IFDIR)
{
int fixmode = 0; /* cleanup mode after rcopy */
close(fold);
if (stat(to, &stto) < 0)
{
if (mkdir(to, (stfrom.st_mode & 07777) | 0700) < 0)
{
Perror(to);
return (1);
}
fixmode = 1;
}
else if ((stto.st_mode&S_IFMT) != S_IFDIR)
{
fprintf(stderr, "cp: %s: Not a directory.\n", to);
return (1);
}
else if (pflag)
{
fixmode = 1;
}
n = rcopy(from, to);
if (fixmode) chmod(to, stfrom.st_mode & 07777);
return (n);
}
if ((stfrom.st_mode&S_IFMT) == S_IFDIR)
fprintf(stderr,
"cp: %s: Is a directory (copying as plain file).\n",
from);
exists = stat(to, &stto) == 0;
if (exists)
{
if (stfrom.st_dev == stto.st_dev && stfrom.st_ino == stto.st_ino)
{
fprintf(stderr,
"cp: %s and %s are identical (not copied).\n", from, to);
close(fold);
return (1);
}
if (iflag && isatty(fileno(stdin)))
{
int i, c;
fprintf (stderr, "overwrite %s? ", to);
i = c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
if (i != 'y')
{
close(fold);
return(1);
}
}
}
fnew = creat(to, stfrom.st_mode & 07777);
if (fnew < 0)
{
Perror(to);
(void) close(fold);
return(1);
}
if (exists && pflag)
fchmod(fnew, stfrom.st_mode & 07777);
for (;;)
{
/* use vmsplice() to copy??? */
n = read(fold, buf, sizeof buf);
if (n == 0) break;
if (n < 0)
{
Perror(from);
close(fold);
close(fnew);
return (1);
}
if (write(fnew, buf, n) != n)
{
Perror(to);
close(fold);
close(fnew);
return (1);
}
}
close(fold);
close(fnew);
if (pflag) return (setimes(to, &stfrom));
return (0);
}
int rcopy(const char* from, const char* to)
{
DIR *fold = opendir(from);
struct direct *dp;
struct stat statb;
int errs = 0;
char fromname[MAXPATHLEN + 1];
if (fold == 0 || (pflag && fstat(fold->dd_fd, &statb) < 0)) {
Perror(from);
return (1);
}
for (;;)
{
dp = readdir(fold);
if (dp == 0)
{
closedir(fold);
if (pflag) return (setimes(to, &statb) + errs);
return (errs);
}
if (dp->d_ino == 0) continue;
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue;
if (strlen(from)+1+strlen(dp->d_name) >= sizeof fromname - 1)
{
fprintf(stderr, "cp: %s/%s: Name too long.\n", from, dp->d_name);
errs++;
continue;
}
sprintf(fromname, "%s/%s", from, dp->d_name);
errs += copy(fromname, to);
}
}
static int setimes(const char* path, const struct stat* statp)
{
struct timeval tv[2];
tv[0].tv_sec = statp->st_atime;
tv[1].tv_sec = statp->st_mtime;
tv[0].tv_usec = tv[1].tv_usec = 0;
if (utimes(path, tv) < 0)
{
Perror(path);
return (1);
}
return (0);
}
#endif

View File

@ -143,10 +143,18 @@ void qse_fs_freefspathforwcs (
# define qse_fs_freefspath(fs,path,fspath) qse_fs_freefspathforwcs(fs,path,fspath);
#endif
int qse_fs_sysgetattr (
int qse_fs_getattrsys (
qse_fs_t* fs,
const qse_fs_char_t* fspath,
qse_fs_attr_t* attr
qse_fs_attr_t* attr,
int flags
);
int qse_fs_setattrsys (
qse_fs_t* fs,
qse_fs_char_t* path,
const qse_fs_attr_t* attr,
int flags /** bitwise-ORed #qse_fs_setattr_flag_t enumerators */
);
int qse_fs_syscpfile (