如何从 statfs 获取 f_type?

How do I get f_type from statfs?

我需要从 statfs 得到 f_type。我尝试修补 Filesys::Df:

---
 Df.pm       | 6 +++---
 Makefile.PL | 7 +------
 XS_statfs   | 1 +
 3 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/Df.pm b/Df.pm
index b24bd9c..986082a 100644
--- a/Df.pm
+++ b/Df.pm
@@ -28,7 +28,7 @@ my %fs = ();
    ($block_size) ||
        ($block_size = 1024);

-   my ($frsize, $blocks, $bfree, $bavail, $files, $ffree, $favail);
+   my ($frsize, $blocks, $bfree, $bavail, $files, $ffree, $favail, $ftype);

    #### If open filehandle call fstatvfs or fstatfs
    if(defined(fileno($dir))) {
@@ -36,7 +36,7 @@ my %fs = ();
    }

    else {
-       ($frsize, $blocks, $bfree, $bavail, $files, $ffree, $favail) = _df($dir);
+       ($frsize, $blocks, $bfree, $bavail, $files, $ffree, $favail, $ftype) = _df($dir);
    }


@@ -199,7 +199,7 @@ my %fs = ();
         #        $fs{user_files}  = undef;
         #}

-
+    $fs{type} = $ftype;
    return(\%fs);
 }

diff --git a/Makefile.PL b/Makefile.PL
index 6a89ec4..e91cbb3 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -21,12 +21,7 @@ if($Config{osname} =~ /^MSWin/i) {
    die "You might try Filesys::DfPortable instead.\n";
 }

-#### Check for the existance of statvfs
-if(check_statvfs()) {
-   ####$define .= "-DDF_STATVFS ";
-   copy_xs("XS_statvfs", $xs_file);
-   print "Building with statvfs ....\n";
-}
+# force statfs

 #### Check for the existance of statfs
 elsif(check_statfs()) {
diff --git a/XS_statfs b/XS_statfs
index 856c646..ef801c3 100644
--- a/XS_statfs
+++ b/XS_statfs
@@ -45,6 +45,7 @@ _df(dir)
        PUSHs(sv_2mortal(newSVnv((double)st.f_ffree)));
        /* No favail */
        PUSHs(sv_2mortal(newSVnv((double)st.f_ffree)));
+       PUSHs(sv_2mortal(newSVnv((double)st.f_type)));
    }

    else {
-- 
2.21.0

接着是

perl Makefile.PL ; make ; perl -Mblib -MFilesys::Df=df -E'say df("/")->{type}'

但是那会崩溃

panic: XSUB Filesys::Df::_df (Df.c) failed to extend arg stack: base=11d3b10, sp=11d3b50, hwm=11d3b48

如何解决这个问题?

XPUSH* 不同,PUSH* 不能确保堆栈上有足够的空间。

PUSHs

Push an SV onto the stack. The stack must have room for this element. Does not handle 'set' magic. Does not use TARG. See also PUSHmortal, XPUSHs, and XPUSHmortal.

void PUSHs(SV* sv)

要确保有足够的 space 用于返回的附加值,只需替换

EXTEND(sp, 7)

EXTEND(sp, 8)

EXTEND

Used to extend the argument stack for an XSUB's return values. Once used, guarantees that there is room for at least nitems to be pushed onto the stack.

void EXTEND(SP, SSize_t nitems)

提示:

PUSHs(sv_2mortal(newSVnv((double)st.f_type)));

应该是

PUSHs(sv_2mortal(newSVnv((NV)st.f_type)));

可以缩短为

mPUSHs(newSVnv((NV)st.f_type));

可以缩短为

mPUSHn((NV)st.f_type);

我知道您正在创建一个最小补丁并且您正在努力保持一致性,但这可能会使您和其他读者在其他情况下受益。