Custom implementation of Realpath()
This commit is contained in:
		
							parent
							
								
									b9806bfbf3
								
							
						
					
					
						commit
						292e1ce9db
					
				
							
								
								
									
										1
									
								
								src/io.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								src/io.h
									
									
									
									
									
								
							@ -37,6 +37,7 @@
 | 
				
			|||||||
#define IO_H__
 | 
					#define IO_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include "struct.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** @defgroup io File input/output
 | 
					/** @defgroup io File input/output
 | 
				
			||||||
 | 
				
			|||||||
@ -16,10 +16,67 @@
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(__AROS__) || defined(__BEOS__) || defined(__MORPHOS__) || defined(__GP2X__) || defined(__WIZ__) || defined(__CAANOO__) || defined(__amigaos__) || defined(__SWITCH__)
 | 
					#if defined(__AROS__) || defined(__BEOS__) || defined(__MORPHOS__) || defined(__GP2X__) || defined(__WIZ__) || defined(__CAANOO__) || defined(__amigaos__) || defined(__SWITCH__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "io.h"
 | 
				
			||||||
 | 
					#include "gfx2log.h"
 | 
				
			||||||
 | 
					#include "gfx2mem.h"
 | 
				
			||||||
// These platforms don't have realpath().
 | 
					// These platforms don't have realpath().
 | 
				
			||||||
 | 
					// Our custom implementation uses chdir() and relies on
 | 
				
			||||||
 | 
					// errno == ENOTDIR when trying to change directory to a file
 | 
				
			||||||
char *Realpath(const char *_path)
 | 
					char *Realpath(const char *_path)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  return strdup(_path);
 | 
					  char * rpath = NULL;
 | 
				
			||||||
 | 
					  char * current_dir_save;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // backup current directory
 | 
				
			||||||
 | 
					  current_dir_save = Get_current_directory(NULL, NULL, 0);
 | 
				
			||||||
 | 
					  if (current_dir_save == NULL) {
 | 
				
			||||||
 | 
					    // error
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (chdir(_path) < 0) {
 | 
				
			||||||
 | 
					    if (errno == ENOTDIR) {
 | 
				
			||||||
 | 
					      const char * position;
 | 
				
			||||||
 | 
					      const char * filename;
 | 
				
			||||||
 | 
					      char * directory;
 | 
				
			||||||
 | 
					      position = Find_last_separator(_path);
 | 
				
			||||||
 | 
					      if (position != NULL) {
 | 
				
			||||||
 | 
					        size_t dirlen = position - _path;
 | 
				
			||||||
 | 
					        filename = position + 1;
 | 
				
			||||||
 | 
					        directory = GFX2_malloc(dirlen);
 | 
				
			||||||
 | 
					        if (directory != NULL) {
 | 
				
			||||||
 | 
					          memcpy(directory, _path, dirlen);
 | 
				
			||||||
 | 
					          directory[dirlen] = '\0';
 | 
				
			||||||
 | 
					          GFX2_Log(GFX2_DEBUG, "Directory : \"%s\", filename : \"%s\"\n", directory, filename);
 | 
				
			||||||
 | 
					          if (chdir(directory) == 0) {
 | 
				
			||||||
 | 
					            char * dirpart = Get_current_directory(NULL, NULL, 0);
 | 
				
			||||||
 | 
					            if (dirpart != NULL) {
 | 
				
			||||||
 | 
					              size_t len = strlen(dirpart) + strlen(filename) + 2;
 | 
				
			||||||
 | 
					              rpath = GFX2_malloc(len);
 | 
				
			||||||
 | 
					              if (rpath != NULL) {
 | 
				
			||||||
 | 
					                snprintf(rpath, len, "%s%s%s", dirpart, PATH_SEPARATOR, filename);
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              free(dirpart);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            GFX2_Log(GFX2_ERROR, "chdir(\"%s\") : %s\n", directory, strerror(errno));
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          free(directory);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      GFX2_Log(GFX2_ERROR, "chdir(\"%s\") : %s\n", _path, strerror(errno));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    // _path is a directory
 | 
				
			||||||
 | 
					    rpath = Get_current_directory(NULL, NULL, 0);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // "restore" current directory
 | 
				
			||||||
 | 
					  chdir(current_dir_save);
 | 
				
			||||||
 | 
					  free(current_dir_save);
 | 
				
			||||||
 | 
					  return rpath;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
#elif defined(__WIN32__) || defined(WIN32)
 | 
					#elif defined(__WIN32__) || defined(WIN32)
 | 
				
			||||||
 | 
				
			|||||||
@ -306,8 +306,11 @@ int Test_File_exists(char * errmsg)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int Test_Realpath(char * errmsg)
 | 
					int Test_Realpath(char * errmsg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  char filepath[256];
 | 
				
			||||||
  char * path;
 | 
					  char * path;
 | 
				
			||||||
 | 
					  FILE * f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Directory test
 | 
				
			||||||
  path = Realpath(tmpdir);
 | 
					  path = Realpath(tmpdir);
 | 
				
			||||||
  if (path == NULL)
 | 
					  if (path == NULL)
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
@ -316,6 +319,25 @@ int Test_Realpath(char * errmsg)
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  GFX2_Log(GFX2_DEBUG, "Realpath(\"%s\") returned \"%s\"\n", tmpdir, path);
 | 
					  GFX2_Log(GFX2_DEBUG, "Realpath(\"%s\") returned \"%s\"\n", tmpdir, path);
 | 
				
			||||||
  free(path);
 | 
					  free(path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // File test
 | 
				
			||||||
 | 
					  snprintf(filepath, sizeof(filepath), "%s/tempfile.txt", tmpdir);
 | 
				
			||||||
 | 
					  f = fopen(filepath, "w");
 | 
				
			||||||
 | 
					  if (f == NULL) {
 | 
				
			||||||
 | 
					    snprintf(errmsg, ERRMSG_LENGTH, "Failed to create \"%s\"", filepath);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  fputs("TEST\n", f);
 | 
				
			||||||
 | 
					  fclose(f);
 | 
				
			||||||
 | 
					  path = Realpath(filepath);
 | 
				
			||||||
 | 
					  Remove_path(filepath);
 | 
				
			||||||
 | 
					  if (path == NULL)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    snprintf(errmsg, ERRMSG_LENGTH, "Realpath(\"%s\") returned NULL", filepath);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  GFX2_Log(GFX2_DEBUG, "Realpath(\"%s\") returned \"%s\"\n", filepath, path);
 | 
				
			||||||
 | 
					  free(path);
 | 
				
			||||||
  return 1;
 | 
					  return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user