diff options
author | Steve Bennett <steveb@workware.net.au> | 2021-07-15 14:15:08 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2022-04-14 11:18:01 +1000 |
commit | 81e1890c0f595c474cabcaa83f66882005336d93 (patch) | |
tree | 75e9fe03c05b9780c1a34039e508121bb6cfced6 | |
parent | 703ac20adb9daff423eea44f4af548f485a97254 (diff) | |
download | jimtcl-81e1890c0f595c474cabcaa83f66882005336d93.zip jimtcl-81e1890c0f595c474cabcaa83f66882005336d93.tar.gz jimtcl-81e1890c0f595c474cabcaa83f66882005336d93.tar.bz2 |
aio: TIP 603 - Implement stat of an open file handle
Although the interface is different ('$handle stat' vs 'chan configure -stat')
the behaviour is the same.
Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r-- | jim-aio.c | 24 | ||||
-rw-r--r-- | jim-file.c | 12 | ||||
-rw-r--r-- | jim_tcl.txt | 5 | ||||
-rw-r--r-- | jimiocompat.h | 8 | ||||
-rw-r--r-- | tests/file.test | 18 |
5 files changed, 62 insertions, 5 deletions
@@ -121,6 +121,7 @@ /* no fdopen() with ANSIC, so can't support these */ #undef HAVE_PIPE #undef HAVE_SOCKETPAIR +#undef Jim_FileStat #endif #if defined(HAVE_SOCKETS) && !defined(JIM_BOOTSTRAP) @@ -1426,6 +1427,20 @@ static int aio_cmd_onexception(Jim_Interp *interp, int argc, Jim_Obj *const *arg } #endif +#if defined(jim_ext_file) && defined(Jim_FileStat) +static int aio_cmd_stat(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + jim_stat_t sb; + AioFile *af = Jim_CmdPrivData(interp); + + if (Jim_FileStat(af->fd, &sb) == -1) { + JimAioSetError(interp, NULL); + return JIM_ERR; + } + return Jim_FileStoreStatData(interp, argc == 0 ? NULL : argv[0], &sb); +} +#endif + #if defined(JIM_SSL) && !defined(JIM_BOOTSTRAP) static int aio_cmd_ssl(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { @@ -1803,6 +1818,15 @@ static const jim_subcmd_type aio_command_table[] = { 1, /* Description: Sets buffering */ }, +#if defined(jim_ext_file) && defined(Jim_FileStat) + { "stat", + "?var?", + aio_cmd_stat, + 0, + 1, + /* Description: 'file stat' on the open file */ + }, +#endif #ifdef jim_ext_eventloop { "readable", "?readable-script?", @@ -140,11 +140,13 @@ static const char *JimGetFileType(int mode) /* *---------------------------------------------------------------------- * - * StoreStatData -- + * Jim_FileStoreStatData -- * * This is a utility procedure that breaks out the fields of a * "stat" structure and stores them in textual form into the - * elements of an associative array. + * elements of an associative array (dict). + * The result is also returned as the Tcl result. + * If varName is NULL, the result is only returned, not stored. * * Results: * Returns a standard Tcl return value. If an error occurs then @@ -161,7 +163,7 @@ static void AppendStatElement(Jim_Interp *interp, Jim_Obj *listObj, const char * Jim_ListAppendElement(interp, listObj, Jim_NewIntObj(interp, value)); } -static int StoreStatData(Jim_Interp *interp, Jim_Obj *varName, const jim_stat_t *sb) +int Jim_FileStoreStatData(Jim_Interp *interp, Jim_Obj *varName, const jim_stat_t *sb) { /* Just use a list to store the data */ Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); @@ -849,7 +851,7 @@ static int file_cmd_lstat(Jim_Interp *interp, int argc, Jim_Obj *const *argv) if (file_lstat(interp, argv[0], &sb) != JIM_OK) { return JIM_ERR; } - return StoreStatData(interp, argc == 2 ? argv[1] : NULL, &sb); + return Jim_FileStoreStatData(interp, argc == 2 ? argv[1] : NULL, &sb); } #else #define file_cmd_lstat file_cmd_stat @@ -862,7 +864,7 @@ static int file_cmd_stat(Jim_Interp *interp, int argc, Jim_Obj *const *argv) if (file_stat(interp, argv[0], &sb) != JIM_OK) { return JIM_ERR; } - return StoreStatData(interp, argc == 2 ? argv[1] : NULL, &sb); + return Jim_FileStoreStatData(interp, argc == 2 ? argv[1] : NULL, &sb); } static const jim_subcmd_type file_command_table[] = { diff --git a/jim_tcl.txt b/jim_tcl.txt index f84101f..442b34a 100644 --- a/jim_tcl.txt +++ b/jim_tcl.txt @@ -67,6 +67,7 @@ Changes between 0.80 and 0.81 10. `open` now supports POSIX-style access arguments 11. TIP 526, `expr` now only allows a single argument (unless --compat is enabled) 12. `try` now supports trap to match on errorcode +13. TIP 603, `aio stat` is now supported to stat a file handle Changes between 0.79 and 0.80 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -4963,6 +4964,10 @@ aio +$handle *sockname*+:: Returns the bound address or path of the socket. See 'getsockname(2)'. ++$handle *stat* ?varName?+:: + Implements the same functionality as `file stat` for a filehandle. + Only available on platforms that support 'fstat(2)' or equivalent. + +$handle *sockopt* '?name value?'+:: With no arguments, returns a dictionary of socket options currently set for the handle (will be empty for a non-socket). With +'name'+ and +'value'+, sets the socket option diff --git a/jimiocompat.h b/jimiocompat.h index e44e6d5..5ac7576 100644 --- a/jimiocompat.h +++ b/jimiocompat.h @@ -67,10 +67,12 @@ int Jim_OpenForRead(const char *filename); typedef struct _stat64 jim_stat_t; #define Jim_Stat __stat64 + #define Jim_FileStat _fstat64 #else typedef struct stat jim_stat_t; #define Jim_Stat stat + #define Jim_FileStat fstat #if defined(HAVE_UNISTD_H) #include <unistd.h> @@ -89,4 +91,10 @@ int Jim_OpenForRead(const char *filename); #endif #endif +/* jim-file.c */ +/* Note that this is currently an internal function only. + * It does not form part of the public Jim API + */ +int Jim_FileStoreStatData(Jim_Interp *interp, Jim_Obj *varName, const jim_stat_t *sb); + #endif diff --git a/tests/file.test b/tests/file.test index 2347e5b..cf54c05 100644 --- a/tests/file.test +++ b/tests/file.test @@ -8,8 +8,10 @@ testConstraint filelstat [string match "wrong # args:*" $msg] testConstraint unix [expr {$tcl_platform(platform) eq "unix"}] if {[testConstraint jim]} { testConstraint mtimeset [expr {!$tcl_platform(bootstrap)}] + testConstraint aiostat [expr {!$tcl_platform(bootstrap)}] } else { testConstraint mtimeset 1 + testConstraint aiostat 0 } test join-1.1 "One name" { @@ -171,6 +173,22 @@ test stat-1.7 {file stat no variable} jim { set a(type) } {file} +test aio-stat-1.1 {file stat via an open file descriptor} {jim aiostat} { + set filename [info script] + set fstat [file stat $filename] + set f [open $filename] + set aiostat [$f stat] + $f close + set ok 1 + foreach field {size type mode mtime} { + if {$fstat($field) != $aiostat($field)} { + puts "error: $field: file stat:$fstat($field) != aio stat:$aiostat($field)" + set ok 0 + } + } + set ok +} {1} + test ext-1.1 {file ext} -body { file ext } -returnCodes error -result {wrong # args: should be "file extension name"} |