Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Libretro
tyrquake
Commits
d39218b3
Commit
d39218b3
authored
Sep 22, 2015
by
Libretro-Admin
Browse files
Add retro_stat.c
parent
4a28bbe5
Changes
5
Hide whitespace changes
Inline
Side-by-side
Makefile.common
View file @
d39218b3
...
...
@@ -76,7 +76,9 @@ SOURCES_C := \
$(CORE_DIR)
/common/world.c
ifneq
($(STATIC_LINKING),1)
SOURCES_C
+=
$(CORE_DIR)
/libretro-common/file/retro_dirent.c
SOURCES_C
+=
\
$(CORE_DIR)
/libretro-common/file/retro_dirent.c
\
$(CORE_DIR)
/libretro-common/file/retro_stat.c
endif
SOURCES_C
+=
$(CORE_DIR)
/common/net_none.c
libretro-common/file/retro_dirent.c
View file @
d39218b3
/* Copyright (C) 2010-2015 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (retro_dirent.c).
* ---------------------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge,
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <stdio.h>
#if defined(_WIN32)
#ifdef _MSC_VER
#define setmode _setmode
#endif
#ifdef _XBOX
#include <xtl.h>
#define INVALID_FILE_ATTRIBUTES -1
#else
#include <io.h>
#include <fcntl.h>
#include <direct.h>
#include <windows.h>
#endif
# include <compat/posix_string.h>
# ifdef _MSC_VER
# define setmode _setmode
# endif
# ifdef _XBOX
# include <xtl.h>
# define INVALID_FILE_ATTRIBUTES -1
# else
# include <io.h>
# include <fcntl.h>
# include <direct.h>
# include <windows.h>
# endif
#elif defined(VITA)
#include <psp2/io/fcntl.h>
#include <psp2/io/dirent.h>
#
include <psp2/io/fcntl.h>
#
include <psp2/io/dirent.h>
#else
#if defined(PSP)
#include <pspiofilemgr.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#
if defined(PSP)
#
include <pspiofilemgr.h>
#
endif
#
include <sys/types.h>
#
include <sys/stat.h>
#
include <dirent.h>
#
include <unistd.h>
#endif
#ifdef __CELLOS_LV2__
...
...
@@ -31,6 +55,8 @@
#endif
#include <boolean.h>
#include <retro_stat.h>
#include <retro_dirent.h>
struct
RDIR
{
...
...
@@ -144,22 +170,13 @@ bool retro_dirent_is_dir(struct RDIR *rdir, const char *path)
const
struct
dirent
*
entry
=
(
const
struct
dirent
*
)
rdir
->
entry
;
if
(
entry
->
d_type
==
DT_DIR
)
return
true
;
else
if
(
entry
->
d_type
==
DT_UNKNOWN
/* This can happen on certain file systems. */
||
entry
->
d_type
==
DT_LNK
)
{
struct
stat
buf
;
if
(
stat
(
path
,
&
buf
)
<
0
)
return
false
;
return
S_ISDIR
(
buf
.
st_mode
);
}
/* This can happen on certain file systems. */
if
(
entry
->
d_type
==
DT_UNKNOWN
||
entry
->
d_type
==
DT_LNK
)
return
path_is_directory
(
path
);
return
false
;
#else
/* dirent struct doesn't have d_type, do it the slow way ... */
struct
stat
buf
;
if
(
stat
(
path
,
&
buf
)
<
0
)
return
false
;
return
S_ISDIR
(
buf
.
st_mode
);
#else
/* dirent struct doesn't have d_type, do it the slow way ... */
return
path_is_directory
(
path
);
#endif
}
...
...
libretro-common/file/retro_stat.c
0 → 100644
View file @
d39218b3
/* Copyright (C) 2010-2015 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (retro_stat.c).
* ---------------------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge,
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#if defined(_WIN32)
#ifdef _MSC_VER
#define setmode _setmode
#endif
#ifdef _XBOX
#include <xtl.h>
#define INVALID_FILE_ATTRIBUTES -1
#else
#include <io.h>
#include <fcntl.h>
#include <direct.h>
#include <windows.h>
#endif
#elif defined(VITA)
#define SCE_ERROR_ERRNO_EEXIST 0x80010011
#include <psp2/io/fcntl.h>
#include <psp2/io/dirent.h>
#include <psp2/io/stat.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#endif
#if defined(PSP)
#include <pspkernel.h>
#endif
#ifdef __HAIKU__
#include <kernel/image.h>
#endif
#if (defined(__CELLOS_LV2__) && !defined(__PSL1GHT__)) || defined(__QNX__) || defined(PSP)
#include <unistd.h>
/* stat() is defined here */
#endif
#include <file/file_path.h>
#include <retro_miscellaneous.h>
#if defined(__CELLOS_LV2__)
#include <cell/cell_fs.h>
#endif
#if defined(VITA)
#define FIO_SO_ISDIR PSP2_S_ISDIR
#endif
/**
* path_is_directory:
* @path : path
*
* Checks if path is a directory.
*
* Returns: true (1) if path is a directory, otherwise false (0).
*/
bool
path_is_directory
(
const
char
*
path
)
{
#if defined(VITA) || defined(PSP)
SceIoStat
buf
;
if
(
sceIoGetstat
(
path
,
&
buf
)
<
0
)
return
false
;
return
FIO_SO_ISDIR
(
buf
.
st_mode
);
#elif defined(__CELLOS_LV2__)
CellFsStat
buf
;
if
(
cellFsStat
(
path
,
&
buf
)
<
0
)
return
false
;
return
((
buf
.
st_mode
&
S_IFMT
)
==
S_IFDIR
);
#elif defined(_WIN32)
DWORD
ret
=
GetFileAttributes
(
path
);
return
(
ret
&
FILE_ATTRIBUTE_DIRECTORY
)
&&
(
ret
!=
INVALID_FILE_ATTRIBUTES
);
#else
struct
stat
buf
;
if
(
stat
(
path
,
&
buf
)
<
0
)
return
false
;
return
S_ISDIR
(
buf
.
st_mode
);
#endif
}
/**
* path_mkdir_norecurse:
* @dir : directory
*
* Create directory on filesystem.
*
* Returns: true (1) if directory could be created, otherwise false (0).
**/
static
bool
path_mkdir_norecurse
(
const
char
*
dir
)
{
int
ret
;
#if defined(_WIN32)
ret
=
_mkdir
(
dir
);
#elif defined(IOS)
ret
=
mkdir
(
dir
,
0755
);
#elif defined(VITA) || defined(PSP)
ret
=
sceIoMkdir
(
dir
,
0777
);
#else
ret
=
mkdir
(
dir
,
0750
);
#endif
/* Don't treat this as an error. */
#if defined(VITA)
if
((
ret
==
SCE_ERROR_ERRNO_EEXIST
)
&&
path_is_directory
(
dir
))
ret
=
0
;
#else
if
(
ret
<
0
&&
errno
==
EEXIST
&&
path_is_directory
(
dir
))
ret
=
0
;
#endif
if
(
ret
<
0
)
printf
(
"mkdir(%s) error: %s.
\n
"
,
dir
,
strerror
(
errno
));
return
ret
==
0
;
}
/**
* path_mkdir:
* @dir : directory
*
* Create directory on filesystem.
*
* Returns: true (1) if directory could be created, otherwise false (0).
**/
bool
path_mkdir
(
const
char
*
dir
)
{
const
char
*
target
=
NULL
;
/* Use heap. Real chance of stack overflow if we recurse too hard. */
char
*
basedir
=
strdup
(
dir
);
bool
ret
=
false
;
if
(
!
basedir
)
return
false
;
path_parent_dir
(
basedir
);
if
(
!*
basedir
||
!
strcmp
(
basedir
,
dir
))
goto
end
;
if
(
path_is_directory
(
basedir
))
{
target
=
dir
;
ret
=
path_mkdir_norecurse
(
dir
);
}
else
{
target
=
basedir
;
ret
=
path_mkdir
(
basedir
);
if
(
ret
)
{
target
=
dir
;
ret
=
path_mkdir_norecurse
(
dir
);
}
}
end:
if
(
target
&&
!
ret
)
printf
(
"Failed to create directory:
\"
%s
\"
.
\n
"
,
target
);
free
(
basedir
);
return
ret
;
}
bool
stat_is_valid
(
const
char
*
path
)
{
#if defined(VITA) || defined(PSP)
SceIoStat
buf
;
if
(
sceIoGetstat
(
path
,
&
buf
)
<
0
)
return
false
;
return
true
;
#elif defined(__CELLOS_LV2__)
CellFsStat
buf
;
if
(
cellFsStat
(
path
,
&
buf
)
<
0
)
return
false
;
return
true
;
#elif defined(_WIN32)
DWORD
ret
=
GetFileAttributes
(
path
);
return
(
ret
!=
INVALID_FILE_ATTRIBUTES
);
#else
struct
stat
buf
;
if
(
stat
(
path
,
&
buf
)
<
0
)
return
false
;
return
true
;
#endif
}
libretro-common/include/file/file_path.h
0 → 100644
View file @
d39218b3
/* Copyright (C) 2010-2015 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (file_path.h).
* ---------------------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge,
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __LIBRETRO_SDK_FILE_PATH_H
#define __LIBRETRO_SDK_FILE_PATH_H
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <sys/types.h>
#include <boolean.h>
#include <retro_inline.h>
#ifdef __cplusplus
extern
"C"
{
#endif
/* Order in this enum is equivalent to negative sort order in filelist
* (i.e. DIRECTORY is on top of PLAIN_FILE) */
enum
{
RARCH_FILETYPE_UNSET
,
RARCH_PLAIN_FILE
,
RARCH_COMPRESSED_FILE_IN_ARCHIVE
,
RARCH_COMPRESSED_ARCHIVE
,
RARCH_DIRECTORY
,
RARCH_FILE_UNSUPPORTED
};
/**
* path_is_compressed_file:
* @path : path
*
* Checks if path is a compressed file.
*
* Returns: true (1) if path is a compressed file, otherwise false (0).
**/
bool
path_is_compressed_file
(
const
char
*
path
);
/**
* path_contains_compressed_file:
* @path : path
*
* Checks if path contains a compressed file.
*
* Currently we only check for hash symbol (#) inside the pathname.
* If path is ever expanded to a general URI, we should check for that here.
*
* Example: Somewhere in the path there might be a compressed file
* E.g.: /path/to/file.7z#mygame.img
*
* Returns: true (1) if path contains compressed file, otherwise false (0).
**/
bool
path_contains_compressed_file
(
const
char
*
path
);
/**
* path_file_exists:
* @path : path
*
* Checks if a file already exists at the specified path (@path).
*
* Returns: true (1) if file already exists, otherwise false (0).
*/
bool
path_file_exists
(
const
char
*
path
);
/**
* path_get_extension:
* @path : path
*
* Gets extension of file. Only '.'s
* after the last slash are considered.
*
* Returns: extension part from the path.
*/
const
char
*
path_get_extension
(
const
char
*
path
);
/**
* path_remove_extension:
* @path : path
*
* Removes the extension from the path and returns the result.
* Removes all text after and including the last '.'.
* Only '.'s after the last slash are considered.
*
* Returns: path with the extension part removed.
*/
char
*
path_remove_extension
(
char
*
path
);
/**
* path_basename:
* @path : path
*
* Get basename from @path.
*
* Returns: basename from path.
**/
const
char
*
path_basename
(
const
char
*
path
);
/**
* path_basedir:
* @path : path
*
* Extracts base directory by mutating path.
* Keeps trailing '/'.
**/
void
path_basedir
(
char
*
path
);
/**
* path_parent_dir:
* @path : path
*
* Extracts parent directory by mutating path.
* Assumes that path is a directory. Keeps trailing '/'.
**/
void
path_parent_dir
(
char
*
path
);
/**
* path_resolve_realpath:
* @buf : buffer for path
* @size : size of buffer
*
* Turns relative paths into absolute path.
* If relative, rebases on current working dir.
**/
void
path_resolve_realpath
(
char
*
buf
,
size_t
size
);
/**
* path_is_absolute:
* @path : path
*
* Checks if @path is an absolute path or a relative path.
*
* Returns: true (1) if path is absolute, false (1) if path is relative.
**/
bool
path_is_absolute
(
const
char
*
path
);
/**
* fill_pathname:
* @out_path : output path
* @in_path : input path
* @replace : what to replace
* @size : buffer size of output path
*
* FIXME: Verify
*
* Replaces filename extension with 'replace' and outputs result to out_path.
* The extension here is considered to be the string from the last '.'
* to the end.
*
* Only '.'s after the last slash are considered as extensions.
* If no '.' is present, in_path and replace will simply be concatenated.
* 'size' is buffer size of 'out_path'.
* E.g.: in_path = "/foo/bar/baz/boo.c", replace = ".asm" =>
* out_path = "/foo/bar/baz/boo.asm"
* E.g.: in_path = "/foo/bar/baz/boo.c", replace = "" =>
* out_path = "/foo/bar/baz/boo"
*/
void
fill_pathname
(
char
*
out_path
,
const
char
*
in_path
,
const
char
*
replace
,
size_t
size
);
/**
* fill_dated_filename:
* @out_filename : output filename
* @ext : extension of output filename
* @size : buffer size of output filename
*
* Creates a 'dated' filename prefixed by 'RetroArch', and
* concatenates extension (@ext) to it.
*
* E.g.:
* out_filename = "RetroArch-{month}{day}-{Hours}{Minutes}.{@ext}"
**/
void
fill_dated_filename
(
char
*
out_filename
,
const
char
*
ext
,
size_t
size
);
/**
* fill_pathname_noext:
* @out_path : output path
* @in_path : input path
* @replace : what to replace
* @size : buffer size of output path
*
* Appends a filename extension 'replace' to 'in_path', and outputs
* result in 'out_path'.
*
* Assumes in_path has no extension. If an extension is still
* present in 'in_path', it will be ignored.
*
*/
void
fill_pathname_noext
(
char
*
out_path
,
const
char
*
in_path
,
const
char
*
replace
,
size_t
size
);
/**
* fill_pathname_dir:
* @in_dir : input directory path
* @in_basename : input basename to be appended to @in_dir
* @replace : replacement to be appended to @in_basename
* @size : size of buffer
*
* Appends basename of 'in_basename', to 'in_dir', along with 'replace'.
* Basename of in_basename is the string after the last '/' or '\\',
* i.e the filename without directories.
*
* If in_basename has no '/' or '\\', the whole 'in_basename' will be used.
* 'size' is buffer size of 'in_dir'.
*
* E.g..: in_dir = "/tmp/some_dir", in_basename = "/some_content/foo.c",
* replace = ".asm" => in_dir = "/tmp/some_dir/foo.c.asm"
**/
void
fill_pathname_dir
(
char
*
in_dir
,
const
char
*
in_basename
,
const
char
*
replace
,
size_t
size
);
/**
* fill_pathname_base:
* @out : output path
* @in_path : input path
* @size : size of output path
*
* Copies basename of @in_path into @out_path.
**/
void
fill_pathname_base
(
char
*
out_path
,
const
char
*
in_path
,
size_t
size
);
/**
* fill_pathname_basedir:
* @out_dir : output directory
* @in_path : input path
* @size : size of output directory
*
* Copies base directory of @in_path into @out_path.
* If in_path is a path without any slashes (relative current directory),
* @out_path will get path "./".
**/
void
fill_pathname_basedir
(
char
*
out_path
,
const
char
*
in_path
,
size_t
size
);
/**
* fill_pathname_parent_dir:
* @out_dir : output directory
* @in_dir : input directory
* @size : size of output directory
*
* Copies parent directory of @in_dir into @out_dir.
* Assumes @in_dir is a directory. Keeps trailing '/'.
**/
void
fill_pathname_parent_dir
(
char
*
out_dir
,
const
char
*
in_dir
,
size_t
size
);
/**
* fill_pathname_resolve_relative:
* @out_path : output path
* @in_refpath : input reference path
* @in_path : input path
* @size : size of @out_path
*
* Joins basedir of @in_refpath together with @in_path.
* If @in_path is an absolute path, out_path = in_path.
* E.g.: in_refpath = "/foo/bar/baz.a", in_path = "foobar.cg",
* out_path = "/foo/bar/foobar.cg".
**/
void
fill_pathname_resolve_relative
(
char
*
out_path
,
const
char
*
in_refpath
,
const
char
*
in_path
,
size_t
size
);
/**
* fill_pathname_join:
* @out_path : output path
* @dir : directory
* @path : path
* @size : size of output path
*
* Joins a directory (@dir) and path (@path) together.
* Makes sure not to get two consecutive slashes
* between directory and path.
**/
void
fill_pathname_join
(
char
*
out_path
,
const
char
*
dir
,
const
char
*
path
,
size_t
size
);
/**
* fill_pathname_join_delim:
* @out_path : output path
* @dir : directory
* @path : path
* @delim : delimiter