- PathPackage now does CHECK_ERR. adjusted callers appropriately

- mem.h: export mem_assign (needed to wrap a mem buffer)
- use stricmp in some file extension comparisons
- wposix: properly sets last-error code when opendir fails
- also: misc comments

This was SVN commit r2650.
This commit is contained in:
janwas 2005-09-02 03:03:06 +00:00
parent 21709a5a7a
commit 50ea8c532c
9 changed files with 73 additions and 48 deletions

View File

@ -71,11 +71,18 @@ const size_t SECTOR_SIZE = 4096;
// accordingly. <dir> need and should not end with a directory separator.
int pp_set_dir(PathPackage* pp, const char* dir)
{
const int len = snprintf(pp->path, ARRAY_SIZE(pp->path), "%s%c", dir, DIR_SEP);
// note: use / instead of DIR_SEP because pp->path is portable.
const int len = snprintf(pp->path, ARRAY_SIZE(pp->path), "%s/", dir);
// (need len below and must return an error code, not -1)
if(len < 0)
return ERR_PATH_LENGTH;
CHECK_ERR(ERR_PATH_LENGTH);
pp->end = pp->path+len;
pp->chars_left = ARRAY_SIZE(pp->path)-len;
// check if <dir> actually did end with '/' (this will cause problems
// when attempting to vfs_open the file).
if(len >= 2) // protect against underrun
debug_assert(pp->end[-2] != '/' && pp->end[-2] != DIR_SEP);
return 0;
}
@ -84,7 +91,8 @@ int pp_set_dir(PathPackage* pp, const char* dir)
// pp_set_dir on this package. the whole path is accessible at pp->path.
int pp_append_file(PathPackage* pp, const char* fn)
{
return strcpy_s(pp->end, pp->chars_left, fn);
CHECK_ERR(strcpy_s(pp->end, pp->chars_left, fn));
return 0;
}
//-----------------------------------------------------------------------------
@ -331,20 +339,20 @@ int dir_open(const char* P_path, DirIterator* d_)
d->os_dir = opendir(n_path);
if(!d->os_dir)
{
int err = -1;
switch(errno)
{
case ENOMEM:
return ERR_NO_MEM;
err = ERR_NO_MEM;
case ENOENT:
return ERR_PATH_NOT_FOUND;
default:
return -1;
err = ERR_PATH_NOT_FOUND;
// default: err already set
}
CHECK_ERR(err);
}
// (see pp declaration)
WARN_ERR(pp_set_dir(&d->pp, n_path));
return 0;
return pp_set_dir(&d->pp, n_path);
}

View File

@ -741,6 +741,10 @@ static void vfs_init_once(void)
mount_init();
}
// make the VFS tree ready for use. must be called before all other
// functions below, barring explicit mentions to the contrary.
//
// rationale: initialization could be done implicitly by calling this
// from all VFS APIs. we refrain from that and require the user to
// call this because a central point of initialization (file_rel_chdir)

View File

@ -191,7 +191,7 @@ Decompression is free because it is done in parallel with IOs.
#include "file.h" // file open flags
// make the VFS tree ready for use. must be called before all other
// functions below unless explicitly mentioned to be allowed.
// functions below, barring explicit mentions to the contrary.
extern void vfs_init();
extern void vfs_shutdown(void);

View File

@ -818,11 +818,11 @@ int vfs_reload_changed_files()
continue;
// .. compiled XML files the engine writes out by the hundreds;
// skipping them is a big performance gain.
if(!strcmp(ext, ".xmb"))
if(!stricmp(ext, ".xmb"))
continue;
// .. temp files, usually created when an editor saves a file
// (delete, create temp, rename temp); no need to reload those.
if(!strcmp(ext, ".tmp"))
if(!stricmp(ext, ".tmp"))
continue;
// .. more than one notification for a file; only reload once.
// note: this doesn't suffer from the 'reloaded too early'

View File

@ -31,6 +31,9 @@ extern void* mem_get_ptr(Handle h, size_t* size = 0);
extern void mem_shutdown(void);
extern Handle mem_assign(void* p, size_t size, uint flags, void* raw_p, size_t raw_size, MEM_DTOR dtor, uintptr_t ctx);
#ifdef __cplusplus
}
#endif

View File

@ -1472,7 +1472,7 @@ static int VSrc_reload(VSrc* vs, const char* fn, Handle hvs)
// declare here so that it doesn't go out of scope below.
const char* ext = strchr(fn, '.');
if(ext && !strcmp(ext, ".txt"))
if(ext && !stricmp(ext, ".txt"))
{
void* def_file;
size_t def_size;

View File

@ -421,7 +421,7 @@ static void add_oal_dlls_in_dir(const char* dir, DllSet* dlls)
int err;
PathPackage pp;
WARN_ERR_RETURN(pp_set_dir(&pp, dir));
(void)pp_set_dir(&pp, dir);
DirIterator d;
WARN_ERR_RETURN(dir_open(dir, &d));

View File

@ -391,47 +391,56 @@ DIR* opendir(const char* path)
if(!is_normal_dir(path))
{
errno = ENOENT;
fail:
debug_warn("opendir failed");
return 0;
}
WDIR* d = wdir_alloc();
if(!d)
{
errno = ENOMEM;
goto fail;
}
// build search path for FindFirstFile. note: "path\\dir" only returns
// information about that directory; trailing slashes aren't allowed.
// for dir entries to be returned, we have to append "\\*".
char search_path[PATH_MAX];
snprintf(search_path, ARRAY_SIZE(search_path), "%s\\*", path);
// note: we could store search_path and defer FindFirstFile until
// readdir. this way is a bit more complex but required for
// correctness (we must return a valid DIR iff <path> is valid).
d->hFind = FindFirstFileA(search_path, &d->fd);
if(d->hFind == INVALID_HANDLE_VALUE)
{
WDIR* d = wdir_alloc();
if(!d)
switch(GetLastError())
{
// not an error - the directory is just empty.
case ERROR_NO_MORE_FILES:
goto success;
case ERROR_FILE_NOT_FOUND:
case ERROR_PATH_NOT_FOUND:
errno = ENOENT;
break;
case ERROR_NOT_ENOUGH_MEMORY:
errno = ENOMEM;
goto fail;
break;
default:
errno = EINVAL;
break;
}
// build search path for FindFirstFile. note: "path\\dir" only returns
// information about that directory; trailing slashes aren't allowed.
// for dir entries to be returned, we have to append "\\*".
char search_path[PATH_MAX];
snprintf(search_path, ARRAY_SIZE(search_path), "%s\\*", path);
// note: we could store search_path and defer FindFirstFile until
// readdir. this way is a bit more complex but required for
// correctness (we must return a valid DIR iff <path> is valid).
d->hFind = FindFirstFileA(search_path, &d->fd);
if(d->hFind == INVALID_HANDLE_VALUE)
{
// actual failure (not just an empty directory)
if(GetLastError() != ERROR_NO_MORE_FILES)
{
// unfortunately there's no way around this; we need to allocate
// d before FindFirstFile because it uses d->fd.
wdir_free(d);
errno = 0; // unknown
goto fail;
}
}
// success
return d;
// unfortunately there's no way around this; we need to allocate
// d before FindFirstFile because it uses d->fd. copying from a
// temporary isn't nice either (this free doesn't happen often)
wdir_free(d);
goto fail;
}
fail:
debug_warn("opendir failed");
return 0;
success:
return d;
}

View File

@ -40,9 +40,10 @@ static bool ATLAS_IsAvailable()
#else
const char* so_name = "AtlasUI.so";
#endif
// we don't care when relocations take place because this SO contains
// very few symbols, so RTLD_LAZY or RTLD_NOW aren't needed.
const int flags = RTLD_LOCAL;
// we don't really care when relocations take place, but one of
// {RTLD_NOW, RTLD_LAZY} must be passed. go with the former because
// it is safer and matches the Windows load behavior.
const int flags = RTLD_LOCAL|RTLD_NOW;
atlas_so_handle = dlopen(so_name, flags);
// open failed (mostly likely SO not found)
if(!atlas_so_handle)