@@ -41,6 +41,8 @@ static g_mutex filesystemNextNodeIdLock;
4141
4242static g_hashmap<g_fs_virt_id, g_fs_node*>* filesystemNodes;
4343
44+ g_fs_open_status _filesystemChooseOrigin (const char * path, g_task* task, g_fs_node*& origin);
45+
4446void filesystemInitialize ()
4547{
4648 mutexInitializeTask (&filesystemNextNodeIdLock, __func__);
@@ -269,50 +271,37 @@ g_filesystem_find_result filesystemFind(g_fs_node* parent, const char* path)
269271
270272 return {
271273 status: status,
272- file : node,
274+ node : node,
273275 foundAllButLast: ((nameEnd - nameStart) > 0 ),
274- lastFoundNode : lastFoundParent,
276+ lastFoundParent : lastFoundParent,
275277 fileNameStart: nameStart
276278 };
277279}
278280
279281g_fs_open_status filesystemOpen (const char * path, g_file_flag_mode flags, g_task* task, g_fd* outFd)
280282{
281- // Decide for relative path origin
282- g_fs_node* origin = nullptr ;
283- if (path[0 ] != ' /' )
284- {
285- const char * cwd = task->process ->environment .workingDirectory ;
286- if (cwd == nullptr )
287- cwd = " /" ;
288-
289- auto findCwdRes = filesystemFind (0 , cwd);
290- if (findCwdRes.status == G_FS_OPEN_SUCCESSFUL)
291- origin = findCwdRes.file ;
292- else
293- return findCwdRes.status ;
294- }
295-
296- if (!origin)
297- origin = filesystemGetRoot ();
283+ g_fs_node* origin;
284+ g_fs_open_status findOriginStatus = _filesystemChooseOrigin (path, task, origin);
285+ if (findOriginStatus != G_FS_OPEN_SUCCESSFUL)
286+ return findOriginStatus;
298287
299288 // Try to find existing node
300289 auto findRes = filesystemFind (origin, path);
301290
302291 // Handle different open cases
303292 if (findRes.status == G_FS_OPEN_SUCCESSFUL)
304293 {
305- if (findRes.file ->type == G_FS_NODE_TYPE_FOLDER)
294+ if (findRes.node ->type == G_FS_NODE_TYPE_FOLDER)
306295 {
307296 logInfo (" %! tried to open folder" , " fs" );
308297 return G_FS_OPEN_ERROR;
309298 }
310299
311300 if (flags & G_FILE_FLAG_MODE_TRUNCATE)
312301 {
313- if (filesystemTruncate (findRes.file ) != G_FS_OPEN_SUCCESSFUL)
302+ if (filesystemTruncate (findRes.node ) != G_FS_OPEN_SUCCESSFUL)
314303 {
315- logInfo (" %! failed to truncate file %i" , " fs" , findRes.file ->id );
304+ logInfo (" %! failed to truncate file %i" , " fs" , findRes.node ->id );
316305 return G_FS_OPEN_ERROR;
317306 }
318307 }
@@ -327,7 +316,7 @@ g_fs_open_status filesystemOpen(const char* path, g_file_flag_mode flags, g_task
327316 origin->id );
328317 return G_FS_OPEN_ERROR;
329318 }
330- else if (filesystemCreateFile (findRes.lastFoundNode , findRes.fileNameStart , &findRes.file ) !=
319+ else if (filesystemCreateFile (findRes.lastFoundParent , findRes.fileNameStart , &findRes.node ) !=
331320 G_FS_OPEN_SUCCESSFUL)
332321 {
333322 logInfo (" %! failed to create file '%s' in parent %i" , " fs" , path, origin->id );
@@ -345,7 +334,7 @@ g_fs_open_status filesystemOpen(const char* path, g_file_flag_mode flags, g_task
345334 }
346335
347336 // Actually open the file
348- return filesystemOpenNodeFd (findRes.file , flags, task->process ->id , outFd);
337+ return filesystemOpenNodeFd (findRes.node , flags, task->process ->id , outFd);
349338}
350339
351340g_fs_open_status filesystemOpenNode (g_fs_node* file, g_file_flag_mode flags, g_pid process,
@@ -809,3 +798,95 @@ bool filesystemGetFileName(g_fd fd, const char** outName)
809798 *outName = node->name ;
810799 return true ;
811800}
801+
802+ g_fs_real_path_status filesystemRealPath (g_task* task, const char * in, char * out)
803+ {
804+ g_fs_node* origin;
805+ auto findOriginStatus = _filesystemChooseOrigin (in, task, origin);
806+ if (findOriginStatus != G_FS_OPEN_SUCCESSFUL)
807+ return findOriginStatus;
808+
809+ auto findResult = filesystemFind (origin, in);
810+ if (findResult.status == G_FS_OPEN_NOT_FOUND)
811+ return G_FS_REAL_PATH_NOT_FOUND;
812+ if (findResult.status != G_FS_OPEN_SUCCESSFUL)
813+ return G_FS_REAL_PATH_ERROR;
814+
815+ filesystemGetAbsolutePath (findResult.node , out);
816+ return G_FS_REAL_PATH_SUCCESS;
817+ }
818+
819+
820+ g_fs_open_status _filesystemChooseOrigin (const char * path, g_task* task, g_fs_node*& origin)
821+ {
822+ if (path[0 ] == ' /' )
823+ {
824+ origin = filesystemGetRoot ();
825+ }
826+ else
827+ {
828+ const char * cwd = task->process ->environment .workingDirectory ;
829+ if (cwd == nullptr )
830+ cwd = " /" ;
831+
832+ origin = nullptr ;
833+ auto findCwdRes = filesystemFind (nullptr , cwd);
834+ if (findCwdRes.status == G_FS_OPEN_SUCCESSFUL)
835+ origin = findCwdRes.node ;
836+ else
837+ return findCwdRes.status ;
838+ }
839+
840+ return G_FS_OPEN_SUCCESSFUL;
841+ }
842+
843+ g_fs_stat_status filesystemStat (g_task* task, const char * path, g_fs_stat_data* out)
844+ {
845+
846+ g_fs_node* origin;
847+ g_fs_open_status findOriginStatus = _filesystemChooseOrigin (path, task, origin);
848+ if (findOriginStatus != G_FS_OPEN_SUCCESSFUL)
849+ return findOriginStatus;
850+
851+ auto findRes = filesystemFind (origin, path);
852+ if (findRes.status == G_FS_OPEN_NOT_FOUND)
853+ return G_FS_STAT_NOT_FOUND;
854+ if (findRes.status != G_FS_OPEN_SUCCESSFUL)
855+ return G_FS_STAT_ERROR;
856+
857+ return filesystemStatNode (findRes.node , out);
858+ }
859+
860+ g_fs_stat_status filesystemFstat (g_task* task, g_fd fd, g_fs_stat_data* out)
861+ {
862+ g_file_descriptor* descriptor = filesystemProcessGetDescriptor (task->process ->id , fd);
863+ if (!descriptor)
864+ return G_FS_STAT_INVALID_FD;
865+
866+ g_fs_node* node = filesystemGetNode (descriptor->nodeId );
867+ if (!node)
868+ return G_FS_STAT_INVALID_FD;
869+
870+ return filesystemStatNode (node, out);
871+ }
872+
873+ g_fs_stat_status filesystemStatNode (g_fs_node* node, g_fs_stat_data* out)
874+ {
875+ out->virtual_id = node->id ;
876+ out->type = node->type ;
877+
878+ auto lengthStatus = filesystemGetLength (node, &out->size );
879+ if (lengthStatus != G_FS_LENGTH_SUCCESSFUL)
880+ {
881+ logInfo (" %! failed to stat file %i with get-length error %i" , " filesystem" , node->id , lengthStatus);
882+ out->size = -1 ;
883+ }
884+
885+ // TODO
886+ out->device = -1 ;
887+ out->time_last_access = 0 ;
888+ out->time_last_modification = 0 ;
889+ out->time_creation = 0 ;
890+
891+ return G_FS_STAT_SUCCESS;
892+ }
0 commit comments