-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFile.h
More file actions
183 lines (160 loc) · 7.28 KB
/
File.h
File metadata and controls
183 lines (160 loc) · 7.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/* Copyright (C) 2020-2025 Stuart Calder
* See accompanying LICENSE file for licensing information. */
#ifndef SSC_FILE_H
#define SSC_FILE_H
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Macro.h"
#include "Error.h"
#define SSC_FILE_DEFAULT_NEWFILE_SIZE 0
#if defined(SSC_OS_UNIXLIKE)
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
/* On Unix-like systems, files are managed through integer handles, "file descriptors". */
typedef int SSC_File_t;
#define SSC_FILE_IS_INT
#define SSC_FILE_NULL_LITERAL (-1) /* -1 is an invalid file descriptor representing failure. */
#ifdef __gnu_linux__
/* Assume that memfd_secret() is supported if no Linux kernel version is specified. */
#if !SSC_LINUX_VERSION_VALUE_ISDEFINED || (SSC_LINUX_VERSION_VALUE >= SSC_LINUX_VERSION(5, 14, 0))
#define SSC_HAS_FILE_CREATESECRET
#endif
#endif
#elif defined(SSC_OS_WINDOWS)
#include <windows.h>
#include <direct.h>
/* On Windows systems, files are managed through HANDLEs. */
typedef HANDLE SSC_File_t;
#define SSC_FILE_NULL_LITERAL INVALID_HANDLE_VALUE
#else
#error "Unsupported operating system."
#endif /* ~ if defined (SSC_OS_UNIXLIKE) or defined (SSC_OS_WINDOWS) */
#define R_ SSC_RESTRICT
SSC_BEGIN_C_DECLS
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/* Get the size of a file in bytes. */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
SSC_API SSC_Error_t
SSC_File_getSize(SSC_File_t file, size_t* R_ storesize);
SSC_INLINE size_t
SSC_File_getSizeOrDie(SSC_File_t file)
{
size_t s;
#ifdef SSC_FILE_IS_INT
SSC_assertMsg(!SSC_File_getSize(file, &s), "Error: SSC_File_getSize() failed to store the size of file %d at %p!", file, (void*)&s);
#else
SSC_assertMsg(!SSC_File_getSize(file, &s), "Error: SSC_File_getSize() failed to store the size of a file at %p!", (void*)&s);
#endif
return s;
}
/*==========================================================================================*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/* Get the size of a file at a specified filepath in bytes. */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
SSC_API SSC_Error_t
SSC_FilePath_getSize(const char* R_ fpath, size_t* R_ storesize);
SSC_INLINE size_t
SSC_FilePath_getSizeOrDie(const char* fpath)
{
size_t s;
SSC_assertMsg(!SSC_FilePath_getSize(fpath, &s), "Error: SSC_FilePath_getSize() failed to obtain the size of %s!\n", fpath);
return s;
}
/*==========================================================================================*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/* Is there a file at a specified filepath? */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
SSC_API bool
SSC_FilePath_exists(const char* fpath);
/* ->true : There is a file.
* ->false: There is not a file. */
/*==========================================================================================*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/* If @control is true, force a file to exist at @fpath; otherwise force a file to NOT exist at @fpath. */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
SSC_API void
SSC_FilePath_forceExistOrDie(const char* R_ fpath, bool control);
/*==========================================================================================*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/* Open the file at a specified filepath. */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
SSC_API SSC_Error_t
SSC_FilePath_open(const char* R_ fpath, bool ronly, SSC_File_t* R_ file);
SSC_INLINE SSC_File_t
SSC_FilePath_openOrDie(const char* R_ fpath, bool ronly)
{
SSC_File_t f;
SSC_assertMsg(
!SSC_FilePath_open(fpath, ronly, &f),
"Error: SSC_FilePath_open() failed to open %s as %s!\n",
fpath,
ronly ? "ReadOnly" : "ReadWrite");
return f;
}
/*==========================================================================================*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/* Create a file at a specified filepath. */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
SSC_API SSC_Error_t
SSC_FilePath_create(const char* R_ fpath, SSC_File_t* R_ file);
SSC_INLINE SSC_File_t
SSC_FilePath_createOrDie(const char* fpath)
{
SSC_File_t f;
SSC_assertMsg(!SSC_FilePath_create(fpath, &f), "Error: SSC_FilePath_create() failed to create %s!\n", fpath);
return f;
}
/*==========================================================================================*/
#ifdef SSC_HAS_FILE_CREATESECRET
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/* Create a "secret" file, with more protections than usually afforded by RAM-backed
* filesytems. */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
SSC_API SSC_Error_t
SSC_File_createSecret(SSC_File_t* file);
/*==========================================================================================*/
#endif /* ! SSC_HAS_FILE_CREATESECRET */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/* Close the file associed with a specified file handle. */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
SSC_API SSC_Error_t
SSC_File_close(SSC_File_t file); //TODO
SSC_INLINE void
SSC_File_closeOrDie(SSC_File_t file)
{
#ifdef SSC_FILE_IS_INT
SSC_assertMsg(!SSC_File_close(file), "Error: SSC_File_close() failed to close file %d!\n", file);
#else
SSC_assertMsg(!SSC_File_close(file), SSC_ERR_S_FAILED_IN("SSC_File_close()"));
#endif
}
/*==========================================================================================*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/* Set the size of a file in bytes. Fill the void with zeroes. */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
SSC_API SSC_Error_t
SSC_File_setSize(SSC_File_t file, size_t size);
SSC_INLINE void
SSC_File_setSizeOrDie(SSC_File_t file, size_t size)
{
#ifdef SSC_FILE_IS_INT
SSC_assertMsg(!SSC_File_setSize(file, size), "Error: SSC_File_setSize() failed to set file %d to size %zu!\n", file, size);
#else
SSC_assertMsg(!SSC_File_setSize(file, size), "Error: SSC_File_setSize() failed to set a file to size %zu!\n", size);
#endif
}
/*==========================================================================================*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/* Change the current working directory to @path. */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
SSC_API SSC_Error_t
SSC_chdir(const char* path);
/*==========================================================================================*/
SSC_END_C_DECLS
#undef R_
#endif /* ~ SSC_FILE_H */