Skip to content

Commit 04a6706

Browse files
committed
vfs: add retro_vfs_stat64_t
1 parent b7066af commit 04a6706

File tree

12 files changed

+110
-31
lines changed

12 files changed

+110
-31
lines changed

libretro-common/file/file_path_io.c

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,27 +43,35 @@
4343
#endif
4444

4545
/* TODO/FIXME - globals */
46-
static retro_vfs_stat_t path_stat_cb = retro_vfs_stat_impl;
46+
static retro_vfs_stat_t path_stat32_cb = retro_vfs_stat_impl;
47+
static retro_vfs_stat_64_t path_stat64_cb = retro_vfs_stat_64_impl;
4748
static retro_vfs_mkdir_t path_mkdir_cb = retro_vfs_mkdir_impl;
4849

4950
void path_vfs_init(const struct retro_vfs_interface_info* vfs_info)
5051
{
5152
const struct retro_vfs_interface*
5253
vfs_iface = vfs_info->iface;
5354

54-
path_stat_cb = retro_vfs_stat_impl;
55+
path_stat32_cb = retro_vfs_stat_impl;
56+
path_stat64_cb = retro_vfs_stat_64_impl;
5557
path_mkdir_cb = retro_vfs_mkdir_impl;
5658

5759
if (vfs_info->required_interface_version < PATH_REQUIRED_VFS_VERSION || !vfs_iface)
5860
return;
5961

60-
path_stat_cb = vfs_iface->stat;
62+
path_stat32_cb = vfs_iface->stat;
6163
path_mkdir_cb = vfs_iface->mkdir;
64+
65+
if (vfs_info->required_interface_version >= STAT64_REQUIRED_VFS_VERSION)
66+
path_stat64_cb = vfs_iface->stat_64;
67+
else
68+
path_stat64_cb = NULL;
6269
}
6370

6471
int path_stat(const char *path)
6572
{
66-
return path_stat_cb(path, NULL);
73+
/* Use 64‑bit stat if available, else fallback */
74+
return path_stat64_cb ? path_stat64_cb(path, NULL) : path_stat32_cb(path, NULL);
6775
}
6876

6977
/**
@@ -76,25 +84,37 @@ int path_stat(const char *path)
7684
*/
7785
bool path_is_directory(const char *path)
7886
{
79-
return (path_stat_cb(path, NULL) & RETRO_VFS_STAT_IS_DIRECTORY) != 0;
87+
if (path_stat64_cb)
88+
return (path_stat64_cb(path, NULL) & RETRO_VFS_STAT_IS_DIRECTORY) != 0;
89+
return (path_stat32_cb(path, NULL) & RETRO_VFS_STAT_IS_DIRECTORY) != 0;
8090
}
8191

8292
bool path_is_character_special(const char *path)
8393
{
84-
return (path_stat_cb(path, NULL) & RETRO_VFS_STAT_IS_CHARACTER_SPECIAL) != 0;
94+
if (path_stat64_cb)
95+
return (path_stat64_cb(path, NULL) & RETRO_VFS_STAT_IS_CHARACTER_SPECIAL) != 0;
96+
return (path_stat32_cb(path, NULL) & RETRO_VFS_STAT_IS_CHARACTER_SPECIAL) != 0;
8597
}
8698

8799
bool path_is_valid(const char *path)
88100
{
89-
return (path_stat_cb(path, NULL) & RETRO_VFS_STAT_IS_VALID) != 0;
101+
if (path_stat64_cb)
102+
return (path_stat64_cb(path, NULL) & RETRO_VFS_STAT_IS_VALID) != 0;
103+
return (path_stat32_cb(path, NULL) & RETRO_VFS_STAT_IS_VALID) != 0;
90104
}
91105

92-
int32_t path_get_size(const char *path)
106+
int64_t path_get_size(const char *path)
93107
{
94-
int32_t filesize = 0;
95-
if (path_stat_cb(path, &filesize) != 0)
108+
int64_t filesize = 0;
109+
int32_t filesize32 = 0;
110+
111+
if (path_stat64_cb && path_stat64_cb(path, &filesize) != 0)
96112
return filesize;
97113

114+
/* Fallback: 32-bit stat */
115+
if (path_stat32_cb && path_stat32_cb(path, &filesize32) != 0)
116+
return (int64_t)filesize32;
117+
98118
return -1;
99119
}
100120

libretro-common/formats/logiqx_dat/logiqx_dat.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ const char *logiqx_dat_html_code_list[][2] = {
5757
bool logiqx_dat_path_is_valid(const char *path, uint64_t *file_size)
5858
{
5959
const char *file_ext = NULL;
60-
int32_t file_size_int;
60+
int64_t file_size_int;
6161

6262
if (string_is_empty(path))
6363
return false;

libretro-common/include/file/file_path.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
RETRO_BEGIN_DECLS
3737

3838
#define PATH_REQUIRED_VFS_VERSION 3
39+
#define STAT64_REQUIRED_VFS_VERSION 4
3940

4041
void path_vfs_init(const struct retro_vfs_interface_info* vfs_info);
4142

@@ -681,7 +682,7 @@ int path_stat(const char *path);
681682

682683
bool path_is_valid(const char *path);
683684

684-
int32_t path_get_size(const char *path);
685+
int64_t path_get_size(const char *path);
685686

686687
bool is_path_accessible_using_standard_io(const char *path);
687688

libretro-common/include/libretro.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2920,6 +2920,19 @@ typedef int (RETRO_CALLCONV *retro_vfs_rename_t)(const char *old_path, const cha
29202920
*/
29212921
typedef int (RETRO_CALLCONV *retro_vfs_stat_t)(const char *path, int32_t *size);
29222922

2923+
/**
2924+
* Gets information about the given file (64-bit size).
2925+
*
2926+
* @param path The path to the file to query.
2927+
* @param[out] size The reported size of the file in bytes.
2928+
* May be \c NULL, in which case this value is ignored.
2929+
* @return A bitmask of \c RETRO_VFS_STAT flags,
2930+
* or 0 if \c path doesn't refer to a valid file.
2931+
* @see RETRO_VFS_STAT
2932+
* @since VFS API v4
2933+
*/
2934+
typedef int (RETRO_CALLCONV *retro_vfs_stat_64_t)(const char *path, int64_t *size);
2935+
29232936
/**
29242937
* Creates a directory at the given path.
29252938
*
@@ -3075,6 +3088,10 @@ struct retro_vfs_interface
30753088

30763089
/** @copydoc retro_vfs_closedir_t */
30773090
retro_vfs_closedir_t closedir;
3091+
3092+
/* VFS API v4 */
3093+
/** @copydoc retro_vfs_stat_64_t */
3094+
retro_vfs_stat_64_t stat_64;
30783095
};
30793096

30803097
/**

libretro-common/include/vfs/vfs_implementation.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ const char *retro_vfs_file_get_path_impl(libretro_vfs_implementation_file *strea
5959

6060
int retro_vfs_stat_impl(const char *path, int32_t *size);
6161

62+
int retro_vfs_stat_64_impl(const char *path, int64_t *size);
63+
6264
int retro_vfs_mkdir_impl(const char *dir);
6365

6466
libretro_vfs_implementation_dir *retro_vfs_opendir_impl(const char *dir, bool include_hidden);

libretro-common/include/vfs/vfs_implementation_saf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ int retro_vfs_file_remove_saf(const char *tree, const char *path);
8484

8585
int retro_vfs_file_rename_saf(const char *old_tree, const char *old_path, const char *new_tree, const char *new_path);
8686

87-
int retro_vfs_stat_saf(const char *tree, const char *path, int32_t *size);
87+
int retro_vfs_stat_saf(const char *tree, const char *path, int64_t *size);
8888

8989
int retro_vfs_mkdir_saf(const char *tree, const char *dir);
9090

libretro-common/vfs/vfs_implementation.c

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,7 +1040,7 @@ const char *retro_vfs_file_get_path_impl(
10401040
return stream->orig_path;
10411041
}
10421042

1043-
int retro_vfs_stat_impl(const char *path, int32_t *size)
1043+
int retro_vfs_stat_64_impl(const char *path, int64_t *size)
10441044
{
10451045
int ret = RETRO_VFS_STAT_IS_VALID;
10461046

@@ -1088,7 +1088,7 @@ int retro_vfs_stat_impl(const char *path, int32_t *size)
10881088
return 0;
10891089

10901090
if (size)
1091-
*size = (int32_t)stat_buf.st_size;
1091+
*size = (int64_t)stat_buf.st_size;
10921092

10931093
if (FIO_S_ISDIR(stat_buf.st_mode))
10941094
ret |= RETRO_VFS_STAT_IS_DIRECTORY;
@@ -1100,14 +1100,15 @@ int retro_vfs_stat_impl(const char *path, int32_t *size)
11001100
return 0;
11011101

11021102
if (size)
1103-
*size = (int32_t)stat_buf.st_size;
1103+
*size = (int64_t)stat_buf.st_size;
11041104

11051105
if ((stat_buf.st_mode & S_IFMT) == S_IFDIR)
11061106
ret |= RETRO_VFS_STAT_IS_DIRECTORY;
11071107
#elif defined(_WIN32)
11081108
/* Windows */
1109-
struct _stat stat_buf;
1109+
struct _stat64 stat_buf;
11101110
#if defined(LEGACY_WIN32)
1111+
/* 32-bit only */
11111112
char *path_local = utf8_to_local_string_alloc(path);
11121113
DWORD file_info = GetFileAttributes(path_local);
11131114

@@ -1120,7 +1121,7 @@ int retro_vfs_stat_impl(const char *path, int32_t *size)
11201121
wchar_t *path_wide = utf8_to_utf16_string_alloc(path);
11211122
DWORD file_info = GetFileAttributesW(path_wide);
11221123

1123-
_wstat(path_wide, &stat_buf);
1124+
_wstat64(path_wide, &stat_buf);
11241125

11251126
if (path_wide)
11261127
free(path_wide);
@@ -1129,7 +1130,7 @@ int retro_vfs_stat_impl(const char *path, int32_t *size)
11291130
return 0;
11301131

11311132
if (size)
1132-
*size = (int32_t)stat_buf.st_size;
1133+
*size = (int64_t)stat_buf.st_size;
11331134

11341135
if (file_info & FILE_ATTRIBUTE_DIRECTORY)
11351136
ret |= RETRO_VFS_STAT_IS_DIRECTORY;
@@ -1157,21 +1158,27 @@ int retro_vfs_stat_impl(const char *path, int32_t *size)
11571158
free(path_buf);
11581159

11591160
if (size)
1160-
*size = (int32_t)stat_buf.st_size;
1161+
*size = (int64_t)stat_buf.st_size;
11611162

11621163
if (S_ISDIR(stat_buf.st_mode))
11631164
ret |= RETRO_VFS_STAT_IS_DIRECTORY;
11641165
if (S_ISCHR(stat_buf.st_mode))
11651166
ret |= RETRO_VFS_STAT_IS_CHARACTER_SPECIAL;
11661167
#else
11671168
/* Every other platform */
1169+
#if defined(_LARGEFILE64_SOURCE)
1170+
struct stat64 stat_buf;
1171+
if (stat64(path, &stat_buf) < 0)
1172+
return 0;
1173+
#else
11681174
struct stat stat_buf;
11691175

11701176
if (stat(path, &stat_buf) < 0)
11711177
return 0;
1178+
#endif
11721179

11731180
if (size)
1174-
*size = (int32_t)stat_buf.st_size;
1181+
*size = (int64_t)stat_buf.st_size;
11751182

11761183
if (S_ISDIR(stat_buf.st_mode))
11771184
ret |= RETRO_VFS_STAT_IS_DIRECTORY;
@@ -1182,6 +1189,21 @@ int retro_vfs_stat_impl(const char *path, int32_t *size)
11821189
return ret;
11831190
}
11841191

1192+
int retro_vfs_stat_impl(const char *path, int32_t *size)
1193+
{
1194+
int64_t size64 = 0;
1195+
int ret = retro_vfs_stat_64_impl(path, size ? &size64 : NULL);
1196+
1197+
/* if a file is larger than 2 GB, size64 will hold the correct value
1198+
* but the cast to int32_t will truncate it.
1199+
* new code should migrate to retro_vfs_stat_64_t
1200+
*/
1201+
if (size)
1202+
*size = (int32_t)size64;
1203+
1204+
return ret;
1205+
}
1206+
11851207
#if defined(VITA)
11861208
#define path_mkdir_err(ret) (((ret) == SCE_ERROR_ERRNO_EEXIST))
11871209
#elif defined(PSP) || defined(PS2) || defined(_3DS) || defined(WIIU) || defined(SWITCH)
@@ -1523,7 +1545,7 @@ bool retro_vfs_dirent_is_dir_impl(libretro_vfs_implementation_dir *rdir)
15231545
{
15241546
char full[PATH_MAX_LENGTH];
15251547
const char *name = retro_vfs_dirent_get_name_impl(rdir);
1526-
int32_t sz = 0;
1548+
int64_t sz = 0;
15271549
int st = 0;
15281550

15291551
if (!name)

libretro-common/vfs/vfs_implementation_saf.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ int retro_vfs_file_rename_saf(const char *old_tree, const char *old_path, const
458458
return -1;
459459
}
460460

461-
int retro_vfs_stat_saf(const char *tree, const char *path, int32_t *size)
461+
int retro_vfs_stat_saf(const char *tree, const char *path, int64_t *size)
462462
{
463463
JNIEnv *env;
464464
jstring tree_object;
@@ -515,7 +515,7 @@ int retro_vfs_stat_saf(const char *tree, const char *path, int32_t *size)
515515
if ((*env)->ExceptionOccurred(env)) goto error;
516516

517517
if (size != NULL)
518-
*size = saf_stat_size > INT32_MAX ? INT32_MAX : (int32_t)saf_stat_size;
518+
*size = saf_stat_size > INT64_MAX ? INT64_MAX : (int64_t)saf_stat_size;
519519

520520
(*env)->PopLocalFrame(env, NULL);
521521
return saf_stat_is_directory ? RETRO_VFS_STAT_IS_VALID | RETRO_VFS_STAT_IS_DIRECTORY : RETRO_VFS_STAT_IS_VALID;

libretro-common/vfs/vfs_implementation_smb.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ int retro_vfs_closedir_smb(smb_dir_handle* dh)
599599
return 0;
600600
}
601601

602-
int retro_vfs_stat_smb(const char *path, int32_t *size)
602+
int retro_vfs_stat_smb(const char *path, int64_t *size)
603603
{
604604
char rel_path[PATH_MAX_LENGTH];
605605
struct smb2_stat_64 st;
@@ -633,7 +633,7 @@ int retro_vfs_stat_smb(const char *path, int32_t *size)
633633
}
634634

635635
if (size)
636-
*size = (int32_t)st.smb2_size;
636+
*size = (int64_t)st.smb2_size;
637637

638638
return RETRO_VFS_STAT_IS_VALID |
639639
(st.smb2_type == SMB2_TYPE_DIRECTORY ? RETRO_VFS_STAT_IS_DIRECTORY : 0);

libretro-common/vfs/vfs_implementation_smb.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ struct smbc_dirent* retro_vfs_readdir_smb(smb_dir_handle* dh);
4444
int retro_vfs_closedir_smb(smb_dir_handle* dh);
4545

4646
/* Stat */
47-
int retro_vfs_stat_smb(const char *path, int32_t *size);
47+
int retro_vfs_stat_smb(const char *path, int64_t *size);
4848

4949
/* Errors */
5050
int retro_vfs_file_error_smb(libretro_vfs_implementation_file *stream);

0 commit comments

Comments
 (0)