SDL

Форк
0
/
SDL_sysfsops.c 
201 строка · 5.7 Кб
1
/*
2
  Simple DirectMedia Layer
3
  Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
4

5
  This software is provided 'as-is', without any express or implied
6
  warranty.  In no event will the authors be held liable for any damages
7
  arising from the use of this software.
8

9
  Permission is granted to anyone to use this software for any purpose,
10
  including commercial applications, and to alter it and redistribute it
11
  freely, subject to the following restrictions:
12

13
  1. The origin of this software must not be misrepresented; you must not
14
     claim that you wrote the original software. If you use this software
15
     in a product, an acknowledgment in the product documentation would be
16
     appreciated but is not required.
17
  2. Altered source versions must be plainly marked as such, and must not be
18
     misrepresented as being the original software.
19
  3. This notice may not be removed or altered from any source distribution.
20
*/
21

22
#include "SDL_internal.h"
23

24
#if defined(SDL_FSOPS_POSIX)
25

26
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
27
// System dependent filesystem routines
28

29
#include "../SDL_sysfilesystem.h"
30

31
#include <stdio.h>
32
#include <string.h>
33
#include <errno.h>
34
#include <dirent.h>
35
#include <sys/stat.h>
36

37
int SDL_SYS_EnumerateDirectory(const char *path, const char *dirname, SDL_EnumerateDirectoryCallback cb, void *userdata)
38
{
39
    int result = 1;
40

41
    DIR *dir = opendir(path);
42
    if (!dir) {
43
        SDL_SetError("Can't open directory: %s", strerror(errno));
44
        return -1;
45
    }
46

47
    struct dirent *ent;
48
    while ((result == 1) && ((ent = readdir(dir)) != NULL))
49
    {
50
        const char *name = ent->d_name;
51
        if ((SDL_strcmp(name, ".") == 0) || (SDL_strcmp(name, "..") == 0)) {
52
            continue;
53
        }
54
        result = cb(userdata, dirname, name);
55
    }
56

57
    closedir(dir);
58

59
    return result;
60
}
61

62
bool SDL_SYS_RemovePath(const char *path)
63
{
64
    int rc = remove(path);
65
    if (rc < 0) {
66
        if (errno == ENOENT) {
67
            // It's already gone, this is a success
68
            return true;
69
        }
70
        return SDL_SetError("Can't remove path: %s", strerror(errno));
71
    }
72
    return true;
73
}
74

75
bool SDL_SYS_RenamePath(const char *oldpath, const char *newpath)
76
{
77
    if (rename(oldpath, newpath) < 0) {
78
        return SDL_SetError("Can't remove path: %s", strerror(errno));
79
    }
80
    return true;
81
}
82

83
bool SDL_SYS_CopyFile(const char *oldpath, const char *newpath)
84
{
85
    char *buffer = NULL;
86
    char *tmppath = NULL;
87
    SDL_IOStream *input = NULL;
88
    SDL_IOStream *output = NULL;
89
    const size_t maxlen = 4096;
90
    size_t len;
91
    bool result = false;
92

93
    if (SDL_asprintf(&tmppath, "%s.tmp", newpath) < 0) {
94
        goto done;
95
    }
96

97
    input = SDL_IOFromFile(oldpath, "rb");
98
    if (!input) {
99
        goto done;
100
    }
101

102
    output = SDL_IOFromFile(tmppath, "wb");
103
    if (!output) {
104
        goto done;
105
    }
106

107
    buffer = (char *)SDL_malloc(maxlen);
108
    if (!buffer) {
109
        goto done;
110
    }
111

112
    while ((len = SDL_ReadIO(input, buffer, maxlen)) > 0) {
113
        if (SDL_WriteIO(output, buffer, len) < len) {
114
            goto done;
115
        }
116
    }
117
    if (SDL_GetIOStatus(input) != SDL_IO_STATUS_EOF) {
118
        goto done;
119
    }
120

121
    SDL_CloseIO(input);
122
    input = NULL;
123

124
    if (!SDL_CloseIO(output)) {
125
        goto done;
126
    }
127
    output = NULL;
128

129
    if (!SDL_RenamePath(tmppath, newpath)) {
130
        SDL_RemovePath(tmppath);
131
        goto done;
132
    }
133

134
    result = true;
135

136
done:
137
    if (output) {
138
        SDL_CloseIO(output);
139
        SDL_RemovePath(tmppath);
140
    }
141
    if (input) {
142
        SDL_CloseIO(input);
143
    }
144
    SDL_free(tmppath);
145
    SDL_free(buffer);
146

147
    return result;
148
}
149

150
bool SDL_SYS_CreateDirectory(const char *path)
151
{
152
    const int rc = mkdir(path, 0770);
153
    if (rc < 0) {
154
        const int origerrno = errno;
155
        if (origerrno == EEXIST) {
156
            struct stat statbuf;
157
            if ((stat(path, &statbuf) == 0) && (S_ISDIR(statbuf.st_mode))) {
158
                return true;  // it already exists and it's a directory, consider it success.
159
            }
160
        }
161
        return SDL_SetError("Can't create directory: %s", strerror(origerrno));
162
    }
163
    return true;
164
}
165

166
bool SDL_SYS_GetPathInfo(const char *path, SDL_PathInfo *info)
167
{
168
    struct stat statbuf;
169
    const int rc = stat(path, &statbuf);
170
    if (rc < 0) {
171
        return SDL_SetError("Can't stat: %s", strerror(errno));
172
    } else if (S_ISREG(statbuf.st_mode)) {
173
        info->type = SDL_PATHTYPE_FILE;
174
        info->size = (Uint64) statbuf.st_size;
175
    } else if (S_ISDIR(statbuf.st_mode)) {
176
        info->type = SDL_PATHTYPE_DIRECTORY;
177
        info->size = 0;
178
    } else {
179
        info->type = SDL_PATHTYPE_OTHER;
180
        info->size = (Uint64) statbuf.st_size;
181
    }
182

183
#if defined(HAVE_ST_MTIM)
184
    // POSIX.1-2008 standard
185
    info->create_time = (SDL_Time)SDL_SECONDS_TO_NS(statbuf.st_ctim.tv_sec) + statbuf.st_ctim.tv_nsec;
186
    info->modify_time = (SDL_Time)SDL_SECONDS_TO_NS(statbuf.st_mtim.tv_sec) + statbuf.st_mtim.tv_nsec;
187
    info->access_time = (SDL_Time)SDL_SECONDS_TO_NS(statbuf.st_atim.tv_sec) + statbuf.st_atim.tv_nsec;
188
#elif defined(SDL_PLATFORM_APPLE)
189
    /* Apple platform stat structs use 'st_*timespec' naming. */
190
    info->create_time = (SDL_Time)SDL_SECONDS_TO_NS(statbuf.st_ctimespec.tv_sec) + statbuf.st_ctimespec.tv_nsec;
191
    info->modify_time = (SDL_Time)SDL_SECONDS_TO_NS(statbuf.st_mtimespec.tv_sec) + statbuf.st_mtimespec.tv_nsec;
192
    info->access_time = (SDL_Time)SDL_SECONDS_TO_NS(statbuf.st_atimespec.tv_sec) + statbuf.st_atimespec.tv_nsec;
193
#else
194
    info->create_time = (SDL_Time)SDL_SECONDS_TO_NS(statbuf.st_ctime);
195
    info->modify_time = (SDL_Time)SDL_SECONDS_TO_NS(statbuf.st_mtime);
196
    info->access_time = (SDL_Time)SDL_SECONDS_TO_NS(statbuf.st_atime);
197
#endif
198
    return true;
199
}
200

201
#endif // SDL_FSOPS_POSIX
202

203

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.