I wanted to build an awesome place for people to discuss module specific issues, but I don't have any more time for this, and there are much better places to discuss Perl-related issues. I'd recommend asking your question on Stack Overflow or on Perl Monks.
If you are looking for a Perl tutorial or Perl-related news, I hope these links will serve you well.
Posted on 2010-06-02 04:31:07.605136-07 by martind
large file support 4GB
Hi there!

I've stumbled across a problem with Net:SSH2 stat()-ing large files via sftp. When a file exceeds 4095MB, stat() fails to correctly report the file size. Instead a size of 0 or 18446744071562067968 is shown. See [1] for the simple test.

I guess the type returned by libssh2 is not properly converted. In the library the type libssh2_uint64_t is used to hold the file size, which is a typedef to unsigned long long:

include/libssh2.h: typedef unsigned long long libssh2_uint64_t;
include/libssh2_sftp.h: struct _LIBSSH2_SFTP_ATTRIBUTES { /* If flags & ATTR_* bit is set, then the value in this struct will be * meaningful Otherwise it should be ignored */ unsigned long flags; libssh2_uint64_t filesize; unsigned long uid, gid; unsigned long permissions; unsigned long atime, mtime; };
In SSH2.xs the size is written to a hash:
/* create a hash from an SFTP attributes structure */ static HV* hv_from_attrs(LIBSSH2_SFTP_ATTRIBUTES* attrs) { HV* hv = newHV(); debug("hv_from_attrs: attrs->flags = %d\n", attrs->flags); if (attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) hv_store(hv, "size", 4, newSVuv(attrs->filesize), 0/*hash*/); /* [...] */ return hv; }

Can anyone tell me, if the newSVuv() properly works with an unsigned long long? AFAIK it is only meant for unsigned integers.

Would it make sense as a workaround to split the file size into two values like in [2]?

Thanks for any hints,

Martin

[1] http://www.libssh2.org/mail/libssh2-devel-archive-2010-05/0015.shtml

[2] http://devcentral.f5.com/weblogs/joe/archive/2005/06/06/553.aspx

Direct Responses: Write a response