added qse_fs_setattr() and related functions
This commit is contained in:
		
							
								
								
									
										30
									
								
								qse/configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								qse/configure
									
									
									
									
										vendored
									
									
								
							| @ -18650,7 +18650,7 @@ _ACEOF | |||||||
| fi | fi | ||||||
| done | done | ||||||
|  |  | ||||||
| for ac_func in lseek64 stat64 fstat64 lstat64 ftruncate64 readdir64 dirfd | for ac_func in lseek64 ftruncate64 readdir64 dirfd | ||||||
| do : | do : | ||||||
|   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` |   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` | ||||||
| ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" | ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" | ||||||
| @ -18662,7 +18662,31 @@ _ACEOF | |||||||
| fi | fi | ||||||
| done | 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 : | do : | ||||||
|   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` |   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` | ||||||
| ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" | ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" | ||||||
| @ -18686,7 +18710,7 @@ _ACEOF | |||||||
| fi | fi | ||||||
| done | done | ||||||
|  |  | ||||||
| for ac_func in utime utimes futimes lutimes futimens | for ac_func in utime utimes futimes lutimes futimens utimensat | ||||||
| do : | do : | ||||||
|   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` |   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` | ||||||
| ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" | ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" | ||||||
|  | |||||||
| @ -145,10 +145,12 @@ AC_CHECK_FUNCS([mbrlen mbrtowc wcrtomb]) | |||||||
| AC_CHECK_FUNCS([mbsnrtowcs mbsrtowcs wcsnrtombs wcsrtombs]) | AC_CHECK_FUNCS([mbsnrtowcs mbsrtowcs wcsnrtombs wcsrtombs]) | ||||||
| AC_CHECK_FUNCS([wctype iswctype wctrans towctrans]) | AC_CHECK_FUNCS([wctype iswctype wctrans towctrans]) | ||||||
| AC_CHECK_FUNCS([isblank iswblank]) | AC_CHECK_FUNCS([isblank iswblank]) | ||||||
| AC_CHECK_FUNCS([lseek64 stat64 fstat64 lstat64 ftruncate64 readdir64 dirfd]) | AC_CHECK_FUNCS([lseek64 ftruncate64 readdir64 dirfd]) | ||||||
| AC_CHECK_FUNCS([lstat fchmod fsync ftruncate]) | 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([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([sysconf prctl fdopendir setrlimit getrlimit getpgid getpgrp]) | ||||||
| AC_CHECK_FUNCS([backtrace backtrace_symbols]) | AC_CHECK_FUNCS([backtrace backtrace_symbols]) | ||||||
| AC_CHECK_FUNCS([fork vfork posix_spawn gettid nanosleep select]) | AC_CHECK_FUNCS([fork vfork posix_spawn gettid nanosleep select]) | ||||||
|  | |||||||
| @ -203,6 +203,15 @@ | |||||||
| /* Define to 1 if you have the `fchmod' function. */ | /* Define to 1 if you have the `fchmod' function. */ | ||||||
| #undef HAVE_FCHMOD | #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. */ | /* Define to 1 if you have the <fcntl.h> header file. */ | ||||||
| #undef HAVE_FCNTL_H | #undef HAVE_FCNTL_H | ||||||
|  |  | ||||||
| @ -236,9 +245,18 @@ | |||||||
| /* Define to 1 if you have the `fork' function. */ | /* Define to 1 if you have the `fork' function. */ | ||||||
| #undef HAVE_FORK | #undef HAVE_FORK | ||||||
|  |  | ||||||
|  | /* Define to 1 if you have the `fstat' function. */ | ||||||
|  | #undef HAVE_FSTAT | ||||||
|  |  | ||||||
| /* Define to 1 if you have the `fstat64' function. */ | /* Define to 1 if you have the `fstat64' function. */ | ||||||
| #undef HAVE_FSTAT64 | #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. */ | /* Define to 1 if you have the `fsync' function. */ | ||||||
| #undef HAVE_FSYNC | #undef HAVE_FSYNC | ||||||
|  |  | ||||||
| @ -356,9 +374,6 @@ | |||||||
| /* Define to 1 if you have the `lseek64' function. */ | /* Define to 1 if you have the `lseek64' function. */ | ||||||
| #undef HAVE_LSEEK64 | #undef HAVE_LSEEK64 | ||||||
|  |  | ||||||
| /* Define to 1 if you have the `lstat' function. */ |  | ||||||
| #undef HAVE_LSTAT |  | ||||||
|  |  | ||||||
| /* Define to 1 if you have the `lstat64' function. */ | /* Define to 1 if you have the `lstat64' function. */ | ||||||
| #undef HAVE_LSTAT64 | #undef HAVE_LSTAT64 | ||||||
|  |  | ||||||
| @ -745,6 +760,9 @@ | |||||||
| /* Define to 1 if you have the `utime' function. */ | /* Define to 1 if you have the `utime' function. */ | ||||||
| #undef HAVE_UTIME | #undef HAVE_UTIME | ||||||
|  |  | ||||||
|  | /* Define to 1 if you have the `utimensat' function. */ | ||||||
|  | #undef HAVE_UTIMENSAT | ||||||
|  |  | ||||||
| /* Define to 1 if you have the `utimes' function. */ | /* Define to 1 if you have the `utimes' function. */ | ||||||
| #undef HAVE_UTIMES | #undef HAVE_UTIMES | ||||||
|  |  | ||||||
|  | |||||||
| @ -140,6 +140,28 @@ struct qse_fs_attr_t | |||||||
|  |  | ||||||
| typedef struct qse_fs_attr_t 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; | typedef struct qse_fs_t qse_fs_t; | ||||||
|  |  | ||||||
| enum qse_fs_trait_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_FORCE     = (1 << 2), | ||||||
| 	QSE_FS_CPFILE_PRESERVE  = (1 << 3), | 	QSE_FS_CPFILE_PRESERVE  = (1 << 3), | ||||||
| 	QSE_FS_CPFILE_REPLACE   = (1 << 4), | 	QSE_FS_CPFILE_REPLACE   = (1 << 4), | ||||||
| 	QSE_FS_CPFILE_SYMLINK   = (1 << 5), | 	QSE_FS_CPFILE_NOTGTDIR  = (1 << 5), /* no target directory */ | ||||||
| 	QSE_FS_CPFILE_NOTGTDIR  = (1 << 6), /* no target directory */ |  | ||||||
|  | 	QSE_FS_CPFILE_SYMLINK   = (1 << 15), | ||||||
|  |  | ||||||
| 	QSE_FS_CPFILE_ALL = (QSE_FS_CPFILE_GLOB | QSE_FS_CPFILE_RECURSIVE | | 	QSE_FS_CPFILE_ALL = (QSE_FS_CPFILE_GLOB | QSE_FS_CPFILE_RECURSIVE | | ||||||
| 	                     QSE_FS_CPFILE_FORCE | QSE_FS_CPFILE_PRESERVE | | 	                     QSE_FS_CPFILE_FORCE | QSE_FS_CPFILE_PRESERVE | | ||||||
| 	                     QSE_FS_CPFILE_REPLACE | QSE_FS_CPFILE_SYMLINK | | 	                     QSE_FS_CPFILE_REPLACE | QSE_FS_CPFILE_NOTGTDIR | | ||||||
| 	                     QSE_FS_CPFILE_NOTGTDIR) | 	                     QSE_FS_CPFILE_SYMLINK) | ||||||
| }; | }; | ||||||
| typedef enum qse_fs_cpfile_flag_t qse_fs_cpfile_flag_t; | 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 | 	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_EXPORT int qse_fs_getattrmbs ( | ||||||
| 	qse_fs_t*            fs, | 	qse_fs_t*            fs, | ||||||
| 	const qse_mchar_t*   path, | 	const qse_mchar_t*   path, | ||||||
| 	qse_fs_attr_t*       attr | 	qse_fs_attr_t*       attr, | ||||||
|  | 	int                  flags | ||||||
| ); | ); | ||||||
|  |  | ||||||
| QSE_EXPORT int qse_fs_getattrwcs ( | QSE_EXPORT int qse_fs_getattrwcs ( | ||||||
| 	qse_fs_t*            fs, | 	qse_fs_t*            fs, | ||||||
| 	const qse_wchar_t*   path, | 	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) | #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 | #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 | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| QSE_EXPORT int qse_fs_move ( | QSE_EXPORT int qse_fs_move ( | ||||||
| 	qse_fs_t*         fs, | 	qse_fs_t*         fs, | ||||||
| 	const qse_char_t* oldpath, | 	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) | #	define qse_fs_deldir(fs,path,flags)  qse_fs_deldirwcs(fs,path,flags) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #if defined(__cplusplus) | #if defined(__cplusplus) | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -114,20 +114,6 @@ | |||||||
| #	define QSE_LSEEK(handle,offset,whence) lseek(handle,offset,whence) | #	define QSE_LSEEK(handle,offset,whence) lseek(handle,offset,whence) | ||||||
| #endif | #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) | #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) | #	define QSE_FTRUNCATE(handle,size) syscall(SYS_ftruncate64,handle,size) | ||||||
| #elif defined(SYS_ftruncate) && defined(QSE_USE_SYSCALL) | #elif defined(SYS_ftruncate) && defined(QSE_USE_SYSCALL) | ||||||
| @ -138,18 +124,6 @@ | |||||||
| #	define QSE_FTRUNCATE(handle,size) ftruncate(handle,size) | #	define QSE_FTRUNCATE(handle,size) ftruncate(handle,size) | ||||||
| #endif | #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) | #if defined(SYS_fsync) && defined(QSE_USE_SYSCALL) | ||||||
| #	define QSE_FSYNC(handle) syscall(SYS_fsync,handle) | #	define QSE_FSYNC(handle) syscall(SYS_fsync,handle) | ||||||
| #else | #else | ||||||
| @ -285,12 +259,36 @@ | |||||||
| #	define QSE_CHMOD(path,mode) chmod(path,mode) | #	define QSE_CHMOD(path,mode) chmod(path,mode) | ||||||
| #endif | #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) | #if defined(SYS_chown) && defined(QSE_USE_SYSCALL) | ||||||
| #	define QSE_CHOWN(path,owner,group) syscall(SYS_chown,path,owner,group) | #	define QSE_CHOWN(path,owner,group) syscall(SYS_chown,path,owner,group) | ||||||
| #else | #else | ||||||
| #	define QSE_CHOWN(path,owner,group) chown(path,owner,group) | #	define QSE_CHOWN(path,owner,group) chown(path,owner,group) | ||||||
| #endif | #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) | #if defined(SYS_chroot) && defined(QSE_USE_SYSCALL) | ||||||
| #	define QSE_CHROOT(path) syscall(SYS_chroot,path) | #	define QSE_CHROOT(path) syscall(SYS_chroot,path) | ||||||
| #else | #else | ||||||
| @ -309,6 +307,35 @@ | |||||||
| #	define QSE_LINK(oldpath,newpath) link(oldpath,newpath) | #	define QSE_LINK(oldpath,newpath) link(oldpath,newpath) | ||||||
| #endif | #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) | #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) | #	define QSE_LSTAT(path,stbuf) syscall(SYS_lstat,path,stbuf) | ||||||
| 	typedef struct stat64 qse_lstat_t; | 	typedef struct stat64 qse_lstat_t; | ||||||
| @ -323,6 +350,21 @@ | |||||||
| 	typedef struct stat qse_lstat_t; | 	typedef struct stat qse_lstat_t; | ||||||
| #endif | #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) | #if defined(SYS_access) && defined(QSE_USE_SYSCALL) | ||||||
| #	define QSE_ACCESS(path,mode) syscall(SYS_access,path,mode) | #	define QSE_ACCESS(path,mode) syscall(SYS_access,path,mode) | ||||||
| #else | #else | ||||||
| @ -348,20 +390,6 @@ | |||||||
| #	define QSE_RMDIR(path) rmdir(path) | #	define QSE_RMDIR(path) rmdir(path) | ||||||
| #endif | #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) | #if defined(SYS_symlink) && defined(QSE_USE_SYSCALL) | ||||||
| #	define QSE_SYMLINK(oldpath,newpath) syscall(SYS_symlink,oldpath,newpath) | #	define QSE_SYMLINK(oldpath,newpath) syscall(SYS_symlink,oldpath,newpath) | ||||||
| #else | #else | ||||||
| @ -410,6 +438,12 @@ | |||||||
| #	define QSE_FUTIMENS(fd,t) futimens(fd,t) | #	define QSE_FUTIMENS(fd,t) futimens(fd,t) | ||||||
| #endif | #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 ===== */ | /* ===== DIRECTORY - not really system calls ===== */ | ||||||
| #define QSE_OPENDIR(name) opendir(name) | #define QSE_OPENDIR(name) opendir(name) | ||||||
| #define QSE_CLOSEDIR(dir) closedir(dir) | #define QSE_CLOSEDIR(dir) closedir(dir) | ||||||
|  | |||||||
| @ -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 */ | 		/* length must include the parameters also */ | ||||||
| 		proxy->qpath_len_in_reqfwdbuf = QSE_STR_LEN(proxy->reqfwdbuf) - proxy->qpath_pos_in_reqfwdbuf; | 		proxy->qpath_len_in_reqfwdbuf = QSE_STR_LEN(proxy->reqfwdbuf) - proxy->qpath_pos_in_reqfwdbuf; | ||||||
|  |  | ||||||
| #if 0 | #if 1 | ||||||
| { | { | ||||||
| /* EXPERIMENTAL */ | /* EXPERIMENTAL */ | ||||||
| /* KT FILTERING WORKAROUND POC. KT seems to check the Host: the first packet | /* KT FILTERING WORKAROUND POC. KT seems to check the Host: the first packet | ||||||
|  | |||||||
| @ -27,7 +27,164 @@ | |||||||
| #include "fs-prv.h" | #include "fs-prv.h" | ||||||
| #include "../cmn/mem-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) | #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; | 	return -1; | ||||||
|  |  | ||||||
| #else | #else | ||||||
| 	#if defined(HAVE_LSTAT) | 	if (flags & QSE_FS_SETATTR_TIME) | ||||||
| 	qse_lstat_t st; |  | ||||||
| 	#else |  | ||||||
| 	qse_stat_t st; |  | ||||||
| 	#endif |  | ||||||
|  |  | ||||||
| 	#if defined(HAVE_LSTAT) |  | ||||||
| 	if (QSE_LSTAT (fspath, &st) == -1)  |  | ||||||
| 	{ | 	{ | ||||||
| 		fs->errnum = qse_fs_syserrtoerrnum (fs, errno); | 	#if defined(HAVE_FUTIMENS) && defined(HAVE_STRUCT_TIMESPEC) | ||||||
| 		return -1; | 		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 | 	#else | ||||||
| 	/* is this ok to use stat? */ | 		fs->errnum = QSE_FS_ENOIMPL; | ||||||
| 	if (QSE_STAT (fspath, &st) == -1)  | 		return -1; | ||||||
|  | 	#endif | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (flags & QSE_FS_SETATTR_OWNER) | ||||||
| 	{ | 	{ | ||||||
| 		fs->errnum = qse_fs_syserrtoerrnum (fs, errno); | 	#if defined(HAVE_FCHOWN) | ||||||
| 		return -1; | 		if (QSE_FCHOWN (fd, attr->uid, attr->gid) <= -1)  | ||||||
| 	} | 		{ | ||||||
| 	#endif | 			fs->errnum = qse_fs_syserrtoerrnum (fs, errno); | ||||||
|  | 			return -1; | ||||||
| 	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 | 	#else | ||||||
| 		attr->atime.sec = st.st_atime; | 		fs->errnum = QSE_FS_ENOIMPL; | ||||||
| 		attr->mtime.sec = st.st_mtime; | 		return -1; | ||||||
| 		attr->ctime.sec = st.st_ctime; |  | ||||||
| 	#endif | 	#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; | 	return 0; | ||||||
| #endif | #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; | 	qse_fs_char_t* fspath; | ||||||
| 	int ret; | 	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); | 	fspath = qse_fs_makefspathformbs (fs, path); | ||||||
| 	if (!fspath) return -1; | 	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); | 	qse_fs_freefspathformbs (fs, path, fspath); | ||||||
| 	return ret; | 	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; | 	qse_fs_char_t* fspath; | ||||||
| 	int ret; | 	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); | 	fspath = qse_fs_makefspathforwcs (fs, path); | ||||||
| 	if (!fspath) return -1; | 	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); | 	qse_fs_freefspathforwcs (fs, path, fspath); | ||||||
| 	return ret; | 	return ret; | ||||||
|  | |||||||
| @ -38,10 +38,8 @@ | |||||||
| struct cpfile_t | struct cpfile_t | ||||||
| { | { | ||||||
| 	int flags; | 	int flags; | ||||||
|  |  | ||||||
| 	qse_fs_char_t* src_fspath; | 	qse_fs_char_t* src_fspath; | ||||||
| 	qse_fs_char_t* dst_fspath; | 	qse_fs_char_t* dst_fspath; | ||||||
|  |  | ||||||
| 	qse_fs_attr_t src_attr; | 	qse_fs_attr_t src_attr; | ||||||
| 	qse_fs_attr_t dst_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); | 	qse_fs_freefspath (fs, QSE_NULL, cpfile->dst_fspath); | ||||||
| 	cpfile->dst_fspath = fstmp; | 	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 */ | 		/* attribute on the new destination is not available */ | ||||||
| 		cpfile->flags &= ~CPFILE_DST_ATTR; | 		cpfile->flags &= ~CPFILE_DST_ATTR; | ||||||
| @ -280,17 +279,6 @@ static int copy_file_in_fs (qse_fs_t* fs, cpfile_t* cpfile) | |||||||
| 				goto oops; | 				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) | 		#elif defined(HAVE_UTIMES) | ||||||
|  |  | ||||||
| 			QSE_MEMSET (&tv, 0, QSE_SIZEOF(tv)); | 			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; | 				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 | 		#else | ||||||
| 		#	error none of futimens, futimes, utime, utimes exist | 		#	error none of futimens, futimes, utime, utimes exist | ||||||
| 		#endif | 		#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. | 	/* error if the source file can't be stat'ed. | ||||||
| 	 * ok if the destination 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; | /* TODO: check on flags to getattrsys() */ | ||||||
| 	if (qse_fs_sysgetattr (fs, cpfile->dst_fspath, &cpfile->dst_attr) >= 0) cpfile->flags |= CPFILE_DST_ATTR; | 	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; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -634,3 +634,198 @@ oops: | |||||||
| 	clear_cpfile (fs, &cpfile); | 	clear_cpfile (fs, &cpfile); | ||||||
| 	return -1; | 	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 | ||||||
|  | |||||||
| @ -143,10 +143,18 @@ void qse_fs_freefspathforwcs ( | |||||||
| #	define qse_fs_freefspath(fs,path,fspath) qse_fs_freefspathforwcs(fs,path,fspath); | #	define qse_fs_freefspath(fs,path,fspath) qse_fs_freefspathforwcs(fs,path,fspath); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| int qse_fs_sysgetattr ( | int qse_fs_getattrsys ( | ||||||
| 	qse_fs_t*            fs, | 	qse_fs_t*            fs, | ||||||
| 	const qse_fs_char_t* fspath, | 	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 ( | int qse_fs_syscpfile ( | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user