libretro: adjust psxclock description
[pcsx_rearmed.git] / deps / libretro-common / file / file_path_io.c
1 /* Copyright  (C) 2010-2020 The RetroArch team
2  *
3  * ---------------------------------------------------------------------------------------
4  * The following license statement only applies to this file (file_path_io.c).
5  * ---------------------------------------------------------------------------------------
6  *
7  * Permission is hereby granted, free of charge,
8  * to any person obtaining a copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
11  * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <time.h>
27
28 #include <sys/stat.h>
29
30 #include <boolean.h>
31 #include <file/file_path.h>
32 #include <compat/strl.h>
33 #include <compat/posix_string.h>
34 #include <retro_miscellaneous.h>
35 #include <string/stdstring.h>
36 #define VFS_FRONTEND
37 #include <vfs/vfs_implementation.h>
38
39 #ifdef _WIN32
40 #include <direct.h>
41 #else
42 #include <unistd.h> /* stat() is defined here */
43 #endif
44
45 /* TODO/FIXME - globals */
46 static retro_vfs_stat_t path_stat_cb   = retro_vfs_stat_impl;
47 static retro_vfs_mkdir_t path_mkdir_cb = retro_vfs_mkdir_impl;
48
49 void path_vfs_init(const struct retro_vfs_interface_info* vfs_info)
50 {
51    const struct retro_vfs_interface* 
52       vfs_iface           = vfs_info->iface;
53
54    path_stat_cb           = retro_vfs_stat_impl;
55    path_mkdir_cb          = retro_vfs_mkdir_impl;
56
57    if (vfs_info->required_interface_version < PATH_REQUIRED_VFS_VERSION || !vfs_iface)
58       return;
59
60    path_stat_cb           = vfs_iface->stat;
61    path_mkdir_cb          = vfs_iface->mkdir;
62 }
63
64 int path_stat(const char *path)
65 {
66    return path_stat_cb(path, NULL);
67 }
68
69 /**
70  * path_is_directory:
71  * @path               : path
72  *
73  * Checks if path is a directory.
74  *
75  * @return true if path is a directory, otherwise false.
76  */
77 bool path_is_directory(const char *path)
78 {
79    return (path_stat_cb(path, NULL) & RETRO_VFS_STAT_IS_DIRECTORY) != 0;
80 }
81
82 bool path_is_character_special(const char *path)
83 {
84    return (path_stat_cb(path, NULL) & RETRO_VFS_STAT_IS_CHARACTER_SPECIAL) != 0;
85 }
86
87 bool path_is_valid(const char *path)
88 {
89    return (path_stat_cb(path, NULL) & RETRO_VFS_STAT_IS_VALID) != 0;
90 }
91
92 int32_t path_get_size(const char *path)
93 {
94    int32_t filesize = 0;
95    if (path_stat_cb(path, &filesize) != 0)
96       return filesize;
97
98    return -1;
99 }
100
101 /**
102  * path_mkdir:
103  * @dir                : directory
104  *
105  * Create directory on filesystem.
106  * 
107  * Recursive function.
108  *
109  * @return true if directory could be created, otherwise false.
110  **/
111 bool path_mkdir(const char *dir)
112 {
113    bool norecurse     = false;
114    char     *basedir  = NULL;
115
116    if (!(dir && *dir))
117       return false;
118
119    /* Use heap. Real chance of stack 
120     * overflow if we recurse too hard. */
121    if (!(basedir = strdup(dir)))
122       return false;
123
124    path_parent_dir(basedir, strlen(basedir));
125
126    if (!*basedir || !strcmp(basedir, dir))
127    {
128       free(basedir);
129       return false;
130    }
131
132    if (     path_is_directory(basedir)
133          || path_mkdir(basedir))
134       norecurse = true;
135
136    free(basedir);
137
138    if (norecurse)
139    {
140       int ret = path_mkdir_cb(dir);
141
142       /* Don't treat this as an error. */
143       if (ret == -2 && path_is_directory(dir))
144          return true;
145       else if (ret == 0)
146          return true;
147    }
148    return false;
149 }