Closed monwarez closed 3 months ago
A quick search lead to this structure for statvfs64 (which is simply statfs64) on Linux
struct statfs64
{
__SWORD_TYPE f_type;
__SWORD_TYPE f_bsize;
__fsblkcnt64_t f_blocks;
__fsblkcnt64_t f_bfree;
__fsblkcnt64_t f_bavail;
__fsfilcnt64_t f_files;
__fsfilcnt64_t f_ffree;
__fsid_t f_fsid;
__SWORD_TYPE f_namelen;
__SWORD_TYPE f_frsize;
__SWORD_TYPE f_flags;
__SWORD_TYPE f_spare[4];
};
While on FreeBSD it is
struct statvfs {
fsblkcnt_t f_bavail; /* Number of blocks */
fsblkcnt_t f_bfree;
fsblkcnt_t f_blocks;
fsfilcnt_t f_favail; /* Number of files (e.g., inodes) */
fsfilcnt_t f_ffree;
fsfilcnt_t f_files;
unsigned long f_bsize; /* Size of blocks counted above */
unsigned long f_flag;
unsigned long f_frsize; /* Size of fragments */
unsigned long f_fsid; /* Not meaningful */
unsigned long f_namemax; /* Same as pathconf(_PC_NAME_MAX) */
};
And an exemple code for a failback with statvfs (I randomly search some repo)
/* Return information about the filesystem on which FILE resides. */
int
__statvfs64 (const char *file, struct statvfs64 *buf)
{
struct statfs64 fsbuf;
int res = __statfs64 (file, &fsbuf);
#ifndef __ASSUME_STATFS64
if (res < 0 && errno == ENOSYS)
{
struct statvfs buf32;
res = statvfs (file, &buf32);
if (res == 0)
{
buf->f_bsize = buf32.f_bsize;
buf->f_frsize = buf32.f_frsize;
buf->f_blocks = buf32.f_blocks;
buf->f_bfree = buf32.f_bfree;
buf->f_bavail = buf32.f_bavail;
buf->f_files = buf32.f_files;
buf->f_ffree = buf32.f_ffree;
buf->f_favail = buf32.f_favail;
buf->f_fsid = buf32.f_fsid;
buf->f_flag = buf32.f_flag;
buf->f_namemax = buf32.f_namemax;
memcpy (buf->__f_spare, buf32.__f_spare, sizeof (buf32.__f_spare));
}
}
#endif
if (res == 0)
/* Convert the result. */
__internal_statvfs64 (file, buf, &fsbuf, -1);
return res;
}
statvfs64 was implemented in https://github.com/shkhln/libc6-shim/commit/0545d82d17440201c04edef4c4d0f62b2caa9493.
When trying to launch dota2 under wine (I am using a too recent amd graphics cards, so I cannot have gpu acceleration on linuxulator), it will simply abort when a game is launch (at the hero selection part). Apparently just before loading the hero selection screen, dota2 inspect the base directory of the steam games folder by using statvfs64 (I guess it is wine that use it for some windows api).
Having a dummy implementation that return an error is not sufficient since dota2 will just abort, so we need to have some kind of result. I simply use the non extended variant to accomplish this goal. A more elegant way would have been to create the correct structure for statvfs and then copy it for the statvfs64, but I am too lazy and it seems to works.
Note that while it is possible to play dota2 games with wine, it may crash randomly (I get some futex error if I recall). So not really ready for competitive play (I was able to rejoin the game each time, so I guess it is some kind of ok).