Skip to content

Commit a7c2060

Browse files
committed
WIP
1 parent 63cc591 commit a7c2060

5 files changed

Lines changed: 427 additions & 28 deletions

File tree

extensions/pl_platform_ext.h

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Index of this file:
77
// [SECTION] header mess
88
// [SECTION] includes
99
// [SECTION] APIs
10+
// [SECTION] defines
1011
// [SECTION] forward declarations
1112
// [SECTION] public apis
1213
// [SECTION] enums
@@ -33,24 +34,36 @@ Index of this file:
3334
//-----------------------------------------------------------------------------
3435

3536
#define plAtomicsI_version {1, 0, 0}
36-
#define plFileI_version {1, 0, 0}
37+
#define plFileI_version {1, 1, 0}
3738
#define plNetworkI_version {1, 0, 0}
3839
#define plThreadsI_version {1, 0, 1}
3940
#define plVirtualMemoryI_version {1, 0, 0}
4041

42+
//-----------------------------------------------------------------------------
43+
// [SECTION] defines
44+
//-----------------------------------------------------------------------------
45+
46+
#ifndef PL_MAX_PATH_LENGTH
47+
#define PL_MAX_PATH_LENGTH 1024
48+
#endif
49+
4150
//-----------------------------------------------------------------------------
4251
// [SECTION] forward declarations
4352
//-----------------------------------------------------------------------------
4453

45-
// basic types (atomics ext)
54+
// basic types (atomics)
4655
typedef struct _plAtomicCounter plAtomicCounter; // opaque type
4756

48-
// basic types (network ext)
57+
// basic types (file)
58+
typedef struct _plDirectoryEntry plDirectoryEntry;
59+
typedef struct _plDirectoryInfo plDirectoryInfo;
60+
61+
// basic types (network)
4962
typedef struct _plSocket plSocket; // opaque type (used by platform backends)
5063
typedef struct _plNetworkAddress plNetworkAddress; // opaque type (used by platform backends)
5164
typedef struct _plSocketReceiverInfo plSocketReceiverInfo;
5265

53-
// basic types (threads ext)
66+
// basic types (threads)
5467
typedef struct _plThread plThread; // opaque type (used by platform backends)
5568
typedef struct _plMutex plMutex; // opaque type (used by platform backends)
5669
typedef struct _plCriticalSection plCriticalSection; // opaque type (used by platform backends)
@@ -61,18 +74,19 @@ typedef struct _plThreadKey plThreadKey; // opaque type (used by
6174

6275
typedef void* (*plThreadProcedure)(void*); // thread procedure signature
6376

64-
// enums (atomics ext)
77+
// enums (atomics)
6578
typedef int plAtomicsResult; // -> enum _plAtomicsResult // Enum:
6679

67-
// enums (file ext)
68-
typedef int plFileResult; // -> enum _plFileResult // Enum:
80+
// enums (file)
81+
typedef int plFileResult; // -> enum _plFileResult // Enum:
82+
typedef int plDirectoryEntryType; // -> enum _plDirectoryEntryType // Enum:
6983

70-
// enums (network ext)
84+
// enums (network)
7185
typedef int plNetworkAddressFlags; // -> enum _plNetworkAddressFlags // Flags:
7286
typedef int plSocketFlags; // -> enum _plSocketFlags // Flags:
7387
typedef int plNetworkResult; // -> enum _plNetworkResult // Enum:
7488

75-
// enums (thread ext)
89+
// enums (thread)
7690
typedef int plThreadResult; // -> enum _plThreadResult // Enum:
7791

7892
//-----------------------------------------------------------------------------
@@ -104,6 +118,15 @@ typedef struct _plFileI
104118
plFileResult (*binary_read) (const char* file, size_t* sizeOut, uint8_t* buffer); // pass NULL for buffer to get size
105119
plFileResult (*binary_write)(const char* file, size_t, uint8_t* buffer);
106120

121+
// simple directory ops
122+
bool (*directory_exists)(const char* path);
123+
plFileResult (*create_directory)(const char* path);
124+
plFileResult (*remove_directory)(const char* path);
125+
126+
// directory info
127+
plFileResult (*get_directory_info) (const char* path, plDirectoryInfo* infoOut);
128+
void (*cleanup_directory_info)(plDirectoryInfo* infoOut);
129+
107130
} plFileI;
108131

109132
typedef struct _plNetworkI
@@ -221,7 +244,24 @@ enum _plAtomicsResult
221244
enum _plFileResult
222245
{
223246
PL_FILE_RESULT_FAIL = 0,
224-
PL_FILE_RESULT_SUCCESS = 1
247+
PL_FILE_RESULT_SUCCESS = 1,
248+
249+
PL_FILE_DIRECTORY_NOT_EMPTY = 2,
250+
PL_FILE_DIRECTORY_ALREADY_EXIST = 3
251+
};
252+
253+
enum _plDirectoryEntryType
254+
{
255+
PL_DIRECTORY_ENTRY_TYPE_UNKNOWN = 0,
256+
PL_DIRECTORY_ENTRY_TYPE_DIRECTORY,
257+
PL_DIRECTORY_ENTRY_TYPE_FILE,
258+
259+
// Linux/MacOS only
260+
PL_DIRECTORY_ENTRY_TYPE_PIPE,
261+
PL_DIRECTORY_ENTRY_TYPE_LINK,
262+
PL_DIRECTORY_ENTRY_TYPE_SOCKET,
263+
PL_DIRECTORY_ENTRY_TYPE_BLOCK_DEVICE,
264+
PL_DIRECTORY_ENTRY_TYPE_CHARACTER_DEVICE,
225265
};
226266

227267
enum _plNetworkAddressFlags
@@ -261,4 +301,18 @@ typedef struct _plSocketReceiverInfo
261301
char acServiceBuffer[100];
262302
} plSocketReceiverInfo;
263303

304+
typedef struct _plDirectoryEntry
305+
{
306+
plDirectoryEntryType tType;
307+
char acName[PL_MAX_PATH_LENGTH];
308+
} plDirectoryEntry;
309+
310+
typedef struct _plDirectoryInfo
311+
{
312+
uint32_t uFileCount;
313+
uint32_t uDirectoryCount;
314+
uint32_t uEntryCount;
315+
plDirectoryEntry* sbtEntries;
316+
} plDirectoryInfo;
317+
264318
#endif // PL_PLATFORM_EXT_H

extensions/pl_platform_linux_ext.c

Lines changed: 105 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Index of this file:
2828
#include <sys/types.h>
2929
#include <fcntl.h> // O_RDONLY, O_WRONLY ,O_CREAT
3030
#include <pthread.h>
31-
#include <unistd.h>
31+
#include <unistd.h> // rmdir
3232
#include <sys/sendfile.h> // sendfile
3333
#include <stdatomic.h>
3434
#include <sys/socket.h>
@@ -37,6 +37,7 @@ Index of this file:
3737
#include <errno.h>
3838
#include <semaphore.h>
3939
#include <sys/mman.h> // virtual memory
40+
#include <dirent.h> // directory operations
4041

4142
plThread** gsbtThreads;
4243

@@ -151,6 +152,99 @@ pl_copy_file(const char* source, const char* destination)
151152
return PL_FILE_RESULT_SUCCESS;
152153
}
153154

155+
bool
156+
pl_file_directory_exists(const char* pcPath)
157+
{
158+
struct stat st = {0};
159+
160+
if (stat(pcPath, &st) == -1)
161+
return false;
162+
return true;
163+
}
164+
165+
plFileResult
166+
pl_file_create_directory(const char* pcPath)
167+
{
168+
struct stat st = {0};
169+
170+
if (stat(pcPath, &st) == -1)
171+
{
172+
mkdir(pcPath, 0700);
173+
return PL_FILE_RESULT_SUCCESS;
174+
}
175+
return PL_FILE_DIRECTORY_ALREADY_EXIST;
176+
}
177+
178+
plFileResult
179+
pl_file_remove_directory(const char* pcPath)
180+
{
181+
if(pl_file_directory_exists(pcPath))
182+
{
183+
rmdir(pcPath);
184+
return PL_FILE_RESULT_SUCCESS;
185+
}
186+
return PL_FILE_RESULT_FAIL;
187+
}
188+
189+
void
190+
pl_file_cleanup_directory_info(plDirectoryInfo* ptInfoOut)
191+
{
192+
pl_sb_free(ptInfoOut->sbtEntries);
193+
ptInfoOut->uEntryCount = 0;
194+
}
195+
196+
plFileResult
197+
pl_file_get_directory_info(const char* pcPath, plDirectoryInfo* ptInfoOut)
198+
{
199+
DIR* ptDirectoryPath = opendir(pcPath);
200+
struct dirent* ptEntry = NULL;
201+
202+
if (ptDirectoryPath == NULL)
203+
{
204+
perror("Error opening directory");
205+
return PL_FILE_RESULT_FAIL;
206+
}
207+
208+
// Read directory entries
209+
while ((ptEntry = readdir(ptDirectoryPath)) != NULL)
210+
{
211+
// Skip "." and ".." entries (current and parent directory)
212+
if (strcmp(ptEntry->d_name, ".") == 0 || strcmp(ptEntry->d_name, "..") == 0)
213+
{
214+
continue;
215+
}
216+
217+
pl_sb_add(ptInfoOut->sbtEntries);
218+
plDirectoryEntry* ptNewEntry = &pl_sb_top(ptInfoOut->sbtEntries);
219+
220+
switch(ptEntry->d_type)
221+
{
222+
case DT_REG: ptInfoOut->uFileCount++; ptNewEntry->tType = PL_DIRECTORY_ENTRY_TYPE_FILE; break;
223+
case DT_DIR: ptInfoOut->uDirectoryCount++; ptNewEntry->tType = PL_DIRECTORY_ENTRY_TYPE_DIRECTORY; break;
224+
case DT_LNK: ptNewEntry->tType = PL_DIRECTORY_ENTRY_TYPE_LINK; break;
225+
case DT_FIFO: ptNewEntry->tType = PL_DIRECTORY_ENTRY_TYPE_PIPE; break;
226+
case DT_SOCK: ptNewEntry->tType = PL_DIRECTORY_ENTRY_TYPE_SOCKET; break;
227+
case DT_BLK: ptNewEntry->tType = PL_DIRECTORY_ENTRY_TYPE_BLOCK_DEVICE; break;
228+
case DT_CHR: ptNewEntry->tType = PL_DIRECTORY_ENTRY_TYPE_CHARACTER_DEVICE; break;
229+
case DT_UNKNOWN: ptNewEntry->tType = PL_DIRECTORY_ENTRY_TYPE_UNKNOWN; break;
230+
default:
231+
PL_ASSERT(false && "unknown dirent file type");
232+
break;
233+
}
234+
235+
strncpy(ptNewEntry->acName, ptEntry->d_name, PL_MAX_PATH_LENGTH);
236+
}
237+
238+
if (closedir(ptDirectoryPath) == -1)
239+
{
240+
perror("Error closing directory");
241+
return PL_FILE_RESULT_FAIL;
242+
}
243+
244+
ptInfoOut->uEntryCount = pl_sb_size(ptInfoOut->sbtEntries);
245+
return PL_FILE_RESULT_SUCCESS;
246+
}
247+
154248
//-----------------------------------------------------------------------------
155249
// [SECTION] atomics ext
156250
//-----------------------------------------------------------------------------
@@ -908,11 +1002,16 @@ PL_EXPORT void
9081002
pl_load_ext(plApiRegistryI* ptApiRegistry, bool bReload)
9091003
{
9101004
const plFileI tFileApi = {
911-
.copy = pl_copy_file,
912-
.exists = pl_file_exists,
913-
.remove = pl_file_delete,
914-
.binary_read = pl_binary_read_file,
915-
.binary_write = pl_binary_write_file
1005+
.copy = pl_copy_file,
1006+
.exists = pl_file_exists,
1007+
.remove = pl_file_delete,
1008+
.binary_read = pl_binary_read_file,
1009+
.binary_write = pl_binary_write_file,
1010+
.directory_exists = pl_file_directory_exists,
1011+
.create_directory = pl_file_create_directory,
1012+
.remove_directory = pl_file_remove_directory,
1013+
.get_directory_info = pl_file_get_directory_info,
1014+
.cleanup_directory_info = pl_file_cleanup_directory_info,
9161015
};
9171016

9181017
const plNetworkI tNetworkApi = {

0 commit comments

Comments
 (0)