diff --git a/src/modules/files/efuns.c b/src/modules/files/efuns.c index 53cb1350391b9863e32a78bac4d4d77d748ced88..f1d32cf51ff1a5a6ff71e6662af6ffd6d212f406 100644 --- a/src/modules/files/efuns.c +++ b/src/modules/files/efuns.c @@ -16,6 +16,7 @@ #include "constants.h" #include "backend.h" #include "operators.h" +#include "builtin_functions.h" #include "file_machine.h" #include "file.h" @@ -96,6 +97,122 @@ void f_file_stat(INT32 args) } } +#if defined(HAVE_STATVFS) || defined(HAVE_STATFS) || defined(HAVE_USTAT) +#ifdef HAVE_SYS_STATVFS_H +#include <sys/statvfs.h> +#endif /* HAVE_SYS_STATVFS_H */ +#ifdef HAVE_SYS_VFS_H +#include <sys/vfs.h> +#endif /* HAVE_SYS_VFS_H */ +#ifdef HAVE_SYS_MOUNT_H +#include <sys/mount.h> +#endif /* HAVE_SYS_MOUNT_H */ +#ifdef HAVE_USTAT_H +#include <ustat.h> +#endif /* HAVE_USTAT_H */ +void f_filesystem_stat(INT32 args) +{ +#ifdef HAVE_STATVFS + struct statvfs st; +#else +#ifdef HAVE_STATFS + struct statfs st; +#else +#ifdef HAVE_USTAT + struct stat statbuf; + struct ustat st; +#else +#error No stat function for filesystems. +#endif /* HAVE_USTAT */ +#endif /* HAVE_STATFS */ +#endif /* HAVE_STATVFS */ + int i; + char *s; + + if(args<1) + error("Too few arguments to filesystem_stat()\n"); + if(sp[-args].type != T_STRING) + error("Bad argument 1 to filesystem_stat()\n"); + + s = sp[-args].u.string->str; + THREADS_ALLOW(); +#ifdef HAVE_STATVFS + i = statvfs(s, &st); +#else +#ifdef HAVE_STATFS + i = statfs(s, &st); +#else +#ifdef HAVE_USTAT + if (!(i = stat(s, &statbuf))) { + i = ustat(statbuf.st_rdev, &st); + } +#else +#error No stat function for filesystems. +#endif /* HAVE_USTAT */ +#endif /* HAVE_STATFS */ +#endif /* HAVE_STATVFS */ + THREADS_DISALLOW(); + pop_n_elems(args); + if(i==-1) + { + push_int(0); + }else{ +#ifdef HAVE_STATVFS + push_text("blocksize"); + push_int(st.f_frsize); + push_text("blocks"); + push_int(st.f_blocks); + push_text("bfree"); + push_int(st.f_bfree); + push_text("bavail"); + push_int(st.f_bavail); + push_text("files"); + push_int(st.f_files); + push_text("ffree"); + push_int(st.f_ffree); + push_text("favail"); + push_int(st.f_favail); + push_text("fstype"); + push_text(st.f_basetype); + push_text("fsname"); + push_text(st.f_fstr); + f_aggregate_mapping(9*2); +#else +#ifdef HAVE_STATFS + push_text("blocksize"); + push_int(st.f_bsize); + push_text("blocks"); + push_int(st.f_blocks); + push_text("bfree"); + push_int(st.f_bfree); + push_text("bavail"); + push_int(st.f_bavail); + push_text("files"); + push_int(st.f_files); + push_text("ffree"); + push_int(st.f_ffree); + push_text("favail"); + push_int(st.f_ffree); + f_aggregate_mapping(7*2); +#else +#ifdef HAVE_USTAT + push_text("bfree"); + push_int(st.f_tfree); + push_text("ffree"); + push_int(st.f_tinode); + push_text("fsname"); + push_text(st.f_fname); + f_aggregate_mapping(3*2); +#else +#error No stat function for filesystems. +#endif /* HAVE_USTAT */ +#endif /* HAVE_STATFS */ +#endif /* HAVE_STATVFS */ + } +} + +#endif /* HAVE_STATVFS || HAVE_STATFS || HAVE_USTAT */ + void f_werror(INT32 args) { if(!args) @@ -516,7 +633,11 @@ void init_files_efuns() set_close_on_exec(2,1); add_efun("file_stat",f_file_stat, - "function(string,int|void:int *)",OPT_EXTERNAL_DEPEND); + "function(string,int|void:int *)", OPT_EXTERNAL_DEPEND); +#if defined(HAVE_STATVFS) || defined(HAVE_STATFS) || defined(HAVE_USTAT) + add_efun("filesystem_stat", f_filesystem_stat, + "function(string:mapping(string:string|int))", OPT_EXTERNAL_DEPEND); +#endif /* HAVE_STATVFS || HAVE_STATFS */ add_efun("errno",f_errno,"function(:int)",OPT_EXTERNAL_DEPEND); add_efun("werror",f_werror,"function(string:void)",OPT_SIDE_EFFECT); add_efun("rm",f_rm,"function(string:int)",OPT_SIDE_EFFECT);