From: <str...@us...> - 2006-11-26 19:42:23
|
Revision: 7598 http://svn.sourceforge.net/alleg/?rev=7598&view=rev Author: strangemoose Date: 2006-11-26 11:42:21 -0800 (Sun, 26 Nov 2006) Log Message: ----------- Some long overdue changes. FS handles (FILE, DIR) etc need to have a vtable added. Already started on it. See FS-HOOK for things I know need fixed, and if you see anything else, let me know. Modified Paths: -------------- allegro/branches/vfs-work-4.3/include/allegro/fshook.h allegro/branches/vfs-work-4.3/include/allegro/internal/fshook.h allegro/branches/vfs-work-4.3/include/allegro/platform/aintunix.h allegro/branches/vfs-work-4.3/include/allegro/system.h allegro/branches/vfs-work-4.3/src/allegro.c allegro/branches/vfs-work-4.3/src/file.c allegro/branches/vfs-work-4.3/src/fshook.c allegro/branches/vfs-work-4.3/src/fshook_stdio.c allegro/branches/vfs-work-4.3/src/libc.c allegro/branches/vfs-work-4.3/src/linux/lsystem.c allegro/branches/vfs-work-4.3/src/macosx/system.m allegro/branches/vfs-work-4.3/src/unix/usystem.c allegro/branches/vfs-work-4.3/src/win/wsystem.c allegro/branches/vfs-work-4.3/src/x/xsystem.c Added Paths: ----------- allegro/branches/vfs-work-4.3/FSHOOK-TODO Added: allegro/branches/vfs-work-4.3/FSHOOK-TODO =================================================================== --- allegro/branches/vfs-work-4.3/FSHOOK-TODO (rev 0) +++ allegro/branches/vfs-work-4.3/FSHOOK-TODO 2006-11-26 19:42:21 UTC (rev 7598) @@ -0,0 +1,6 @@ +TODO +==== + +* Finish changing macros to use handle level vtables when nesesary +* Fix fstat +* Fix mktemp Modified: allegro/branches/vfs-work-4.3/include/allegro/fshook.h =================================================================== --- allegro/branches/vfs-work-4.3/include/allegro/fshook.h 2006-11-26 13:05:28 UTC (rev 7597) +++ allegro/branches/vfs-work-4.3/include/allegro/fshook.h 2006-11-26 19:42:21 UTC (rev 7598) @@ -20,18 +20,28 @@ AL_BEGIN_EXTERN_C -typedef void *AL_STAT; -typedef void *AL_FILE; +/* The following defines are reserved for fs drivers. + * Define to keep from defining types multiple times. + */ + +#ifndef ALLEGRO_FS_FILE_DEFINED +//typedef void *AL_FILE; +typedef struct AL_FILE { + AL_FS_HOOK_VTABLE vtable; +}; +#endif + +#ifndef ALLEGRO_FS_DIR_DEFINED typedef void *AL_DIR; +#endif + +#ifndef ALLEGRO_FS_DIR_DEFINED typedef void *AL_DIRENT; +#endif enum { - AL_PROGRAM_DIR = 0, - AL_SYSTEM_PROGRAM_DIR, /* eg: C:\Program Files\ on windows */ - AL_SYSTEM_DATA_DIR, - AL_USER_DATA_DIR, - AL_USER_HOME_DIR, - AL_DIR_LAST // must be last + AL_MKTEMP_UNLINK_NOW = 1, + AL_MKTEMP_UNLINK_ON_CLOSE }; enum { @@ -50,7 +60,12 @@ }; enum { - AL_FS_HOOK_FOPEN = 0, + AL_FS_HOOK_CREATE_HANDLE = 0, + AL_FS_HOOK_DESTROY_HANDLE, + AL_FS_HOOK_OPEN_HANDLE, + AL_FS_HOOK_CLOSE_HANDLE, + + AL_FS_HOOK_FOPEN, AL_FS_HOOK_FCLOSE, AL_FS_HOOK_FREAD, AL_FS_HOOK_FWRITE, @@ -69,7 +84,7 @@ AL_FS_HOOK_MKTEMP, AL_FS_HOOK_GETCWD, AL_FS_HOOK_CHDIR, - AL_FS_HOOK_GETDIR, + AL_FS_HOOK_ADD_SEARCH_PATH, AL_FS_HOOK_SEARCH_PATH_COUNT, AL_FS_HOOK_GET_SEARCH_PATH, @@ -89,13 +104,47 @@ AL_FS_HOOK_LAST /* must be last */ }; + /* + Different Methods of handling file stat info (ie: AL_STAT): + + 1. AL_STAT *al_fs_fstat(char *file) && void al_fs_stat_free(stathandle); + Pros: Can handle AL_STAT as a opaque type, hiding the struct members, and struct size away + to avoid possible ABI breakages. + Cons: The user has to free the handle, and use some annoyingly long named functions to access it. + + 2. int32_t al_fs_fstat(char *file, AL_STAT *st); + Pros: no handle to free, just pass in a AL_STAT on the stack. + Cons: struct needs to be fully uservisible, + may cause ABI breakages if items are added or removed from the struct + again needs some annoyingly long and ugly (named) functions to access the info. + + 3. Have no AL_STAT handle at all, cache the stat info in the AL_FILE handle. + Pros: no annoying AL_STAT handle or ABI breakages to worry about. + annoying access methods can be shortened. + Cons: Needs a AL_FILE handle to access stat info *** + + ***) Possible Solution: allow an AL_FILE handle to be created, but not open the file + + <Thomas> 3 is my preference. I'm going to implement it, and worry about arguments for or against later. +*/ + +/* TODO: Have stat info cached in AL_FILE handles. */ +/* add al_fs_get_handle()/al_fs_open_handle()/_close_handle() + * alows one to grab a handle to get file info without opening the file + */ + +/* set the given <phid> hook to <fshook> */ int al_fs_set_hook(uint32_t phid, void *fshook); - void *al_fs_get_hook(uint32_t phid); +AL_FILE *al_fs_create_handle(AL_CONST char *path); +void al_fs_destroy_handle(AL_FILE *handle); +int32_t al_fs_open_handle(AL_FILE *handle, AL_CONST char *mode); +int32_t al_fs_close_handle(AL_FILE *handle); + AL_FILE *al_fs_fopen(const char *path, const char *mode); int32_t al_fs_fclose(AL_FILE *fp); ssize_t al_fs_fread(void *ptr, size_t size, AL_FILE *fp); @@ -106,20 +155,20 @@ int32_t al_fs_ferror(AL_FILE *fp); int32_t al_fs_feof(AL_FILE *fp); -int32_t al_fs_fstat(const char *path, AL_STAT *st); -#warning "Implement/Fix al_fs_stat_free" -int32_t al_fs_stat_free(AL_STAT *stbuf); +int32_t al_fs_funlink( AL_FILE *fp ); +/* unlink is just a convienience function, it calls funlink */ +int32_t al_fs_unlink( const char *path ); +int32_t al_fs_fstat(AL_FILE *fp); + AL_DIR *al_fs_opendir(const char *path); int32_t al_fs_closedir(AL_DIR *dir); AL_DIRENT *al_fs_readdir(AL_DIR *dir); -AL_FILE *al_fs_mktemp(const char *tmpl); +AL_FILE *al_fs_mktemp(const char *tmpl, uint32_t ulink); int32_t al_fs_getcwd(char *buf, size_t len); int32_t al_fs_chdir(const char *path); -int32_t al_fs_getdir(uint32_t id, char *dir, size_t *len); - int32_t al_fs_add_search_path(const char *path); int32_t al_fs_search_path_count(); int32_t al_fs_get_search_path(uint32_t idx, char *dest, size_t len); Modified: allegro/branches/vfs-work-4.3/include/allegro/internal/fshook.h =================================================================== --- allegro/branches/vfs-work-4.3/include/allegro/internal/fshook.h 2006-11-26 13:05:28 UTC (rev 7597) +++ allegro/branches/vfs-work-4.3/include/allegro/internal/fshook.h 2006-11-26 19:42:21 UTC (rev 7598) @@ -24,26 +24,31 @@ /* This is totally internal. the access functions SHOULD be used instead. This vtable can change at any time. */ struct AL_FS_HOOK_VTABLE { + AL_METHOD(AL_FILE *, create_handle, (AL_CONST char *path) ); + AL_METHOD(void, destroy_handle, (AL_FILE *handle) ); + AL_METHOD(int32_t, open_handle, (AL_FILE *handle, AL_CONST char *mode) ); + AL_METHOD(int32_t, close_handle, (AL_FILE *handle) ); + + AL_METHOD(void, fname, (AL_FILE *fh, char *name, uint32_t len) ); AL_METHOD(AL_FILE *, fopen, (AL_CONST char *path, AL_CONST char *mode) ); - AL_METHOD(int32_t, fclose, (AL_FILE *fp) ); + AL_METHOD(int32_t, fclose, (AL_FILE *fp) ); AL_METHOD(size_t, fread, (void *ptr, size_t size, AL_FILE *fp) ); AL_METHOD(size_t, fwrite, (AL_CONST void *ptr, size_t size, AL_FILE *fp) ); - AL_METHOD(int32_t, fflush, (AL_FILE *fp) ); - AL_METHOD(int32_t, fseek, (AL_FILE *fp, uint32_t offset, uint32_t whence) ); - AL_METHOD(int32_t, ftell, (AL_FILE *fp) ); - AL_METHOD(int32_t, ferror, (AL_FILE *fp) ); - AL_METHOD(int32_t, feof, (AL_FILE *fp) ); + AL_METHOD(int32_t, fflush, (AL_FILE *fp) ); + AL_METHOD(int32_t, fseek, (AL_FILE *fp, uint32_t offset, uint32_t whence) ); + AL_METHOD(int32_t, ftell, (AL_FILE *fp) ); + AL_METHOD(int32_t, ferror, (AL_FILE *fp) ); + AL_METHOD(int32_t, feof, (AL_FILE *fp) ); - AL_METHOD(int32_t, fstat, (AL_CONST char *path, AL_STAT *stbuf) ); + AL_METHOD(int32_t, fstat, (AL_FILE *handle) ); AL_METHOD(AL_DIR *, opendir, (AL_CONST char *path) ); AL_METHOD(AL_DIRENT *, readdir, (AL_DIR *dir) ); - AL_METHOD(int32_t, closedir, (AL_DIR *dir) ); + AL_METHOD(int32_t, closedir, (AL_DIR *dir) ); - AL_METHOD(AL_FILE *, mktemp, (AL_CONST char *template) ); - AL_METHOD(int32_t, getcwd, (char *buf, size_t len) ); - AL_METHOD(int32_t, chdir, (AL_CONST char *path) ); - AL_METHOD(int32_t, getdir, (uint32_t id, char *dir, uint32_t *len) ); + AL_METHOD(AL_FILE *, mktemp, (AL_CONST char *t) ); + AL_METHOD(int32_t, getcwd, (char *buf, size_t len) ); + AL_METHOD(int32_t, chdir, (AL_CONST char *path) ); AL_METHOD(int32_t, add_search_path, (AL_CONST char *path) ); AL_METHOD(int32_t, search_path_count, (void) ); @@ -51,12 +56,17 @@ /* I had wanted to make these a single function with a few enum entries, but can I assume all the types are the same size? */ - AL_METHOD(uint32_t, get_stat_mode, (AL_STAT *) ); - AL_METHOD(time_t, get_stat_atime, (AL_STAT *) ); - AL_METHOD(time_t, get_stat_mtime, (AL_STAT *) ); - AL_METHOD(time_t, get_stat_ctime, (AL_STAT *) ); - AL_METHOD(size_t, get_stat_size, (AL_STAT *) ); + AL_METHOD(uint32_t, file_mode, (AL_FILE *) ); + AL_METHOD(time_t, file_atime, (AL_FILE *) ); + AL_METHOD(time_t, file_mtime, (AL_FILE *) ); + AL_METHOD(time_t, file_ctime, (AL_FILE *) ); + AL_METHOD(size_t, file_size, (AL_FILE *) ); + AL_METHOD(size_t, get_file_exists, (AL_FILE *) ); + AL_METHOD(size_t, get_dir_exists, (AL_FILE *) ); + + AL_METHOD(size_t, file_exists, + AL_METHOD(uint32_t, drive_sep, (size_t len, char *sep) ); AL_METHOD(uint32_t, path_sep, (size_t len, char *sep) ); @@ -65,28 +75,30 @@ }; #define _al_fs_hook_fopen(path, mode) _al_fshooks.fopen(path, mode) -#define _al_fs_hook_fclose(fp) _al_fshooks.fclose(fp) -#define _al_fs_hook_fread(ptr, size, fp) _al_fshooks.fread(ptr, size, fp) -#define _al_fs_hook_fwrite(ptr, size, fp) _al_fshooks.fwrite(ptr, size, fp) -#define _al_fs_hook_fflush(fp) _al_fshooks.fflush(fp) -#define _al_fs_hook_fseek(fp, offset, whence) _al_fshooks.fseek(fp,offset,whence) -#define _al_fs_hook_ftell(fp) _al_fshooks.ftell(fp) -#define _al_fs_hook_ferror(fp) _al_fshooks.ferror(fp) -#define _al_fs_hook_feof(fp) _al_fshooks.feof(fp) +#define _al_fs_hook_fclose(fp) (fp)->vtable.fclose(fp) +#define _al_fs_hook_fread(ptr, size, fp) (fp)->vtable.fread(ptr, size, fp) +#define _al_fs_hook_fwrite(ptr, size, fp) (fp)->vtable.fwrite(ptr, size, fp) +#define _al_fs_hook_fflush(fp) (fp)->vtable.fflush(fp) +#define _al_fs_hook_fseek(fp, offset, whence) (fp)->vtable.fseek(fp,offset,whence) +#define _al_fs_hook_ftell(fp) (fp)->vtable.ftell(fp) +#define _al_fs_hook_ferror(fp) (fp)->vtable.ferror(fp) +#define _al_fs_hook_feof(fp) (fp)->vtable.feof(fp) -#define _al_fs_hook_fstat(path, stbuf) _al_fshooks.fstat(path, stbuf) +#warning "fix this stat stuff" +#define _al_fs_hook_fstat(path, stbuf) (fp)->vtable.fstat(path, stbuf) +#define _al_fs_hook_funlink(fp) (fp)->vtable.funlink(fp) + #define _al_fs_hook_opendir(path) _al_fshooks.opendir(path) -#define _al_fs_hook_closedir(dir) _al_fshooks.closedir(dir) -#define _al_fs_hook_readdir(dir) _al_fshooks.readdir(dir) +#define _al_fs_hook_closedir(dir) (dir)->vtable.closedir(dir) +#define _al_fs_hook_readdir(dir) (dir)->vtable.readdir(dir) #define _al_fs_hook_mktemp(template) _al_fshooks.mktemp(template) #define _al_fs_hook_getcwd(buf, len) _al_fshooks.getcwd(buf, len) #define _al_fs_hook_chdir(path) _al_fshooks.chdir(path) -#define _al_fs_hook_getdir(id, dir, len) _al_fshooks.getdir(id, dir, len) -#define _al_fs_hook_add_search_path(path) _al_fshooks.add_search_path(path) -#define _al_fs_hook_search_path_count() _al_fshooks.search_path_count() +#define _al_fs_hook_add_search_path(path) _al_fshooks.add_search_path(path) +#define _al_fs_hook_search_path_count() _al_fshooks.search_path_count() #define _al_fs_hook_get_search_path(idx, dest, len) _al_fshooks.get_search_path(idx, dest, len) #define _al_fs_hook_get_stat_mode(st) _al_fshooks.get_stat_mode(st) Modified: allegro/branches/vfs-work-4.3/include/allegro/platform/aintunix.h =================================================================== --- allegro/branches/vfs-work-4.3/include/allegro/platform/aintunix.h 2006-11-26 13:05:28 UTC (rev 7597) +++ allegro/branches/vfs-work-4.3/include/allegro/platform/aintunix.h 2006-11-26 19:42:21 UTC (rev 7598) @@ -1,6 +1,6 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ @@ -11,7 +11,7 @@ * Some definitions for internal use by the Unix library code. * * By Shawn Hargreaves. - * + * * See readme.txt for copyright information. */ @@ -39,6 +39,8 @@ /* Generic system driver entry for finding the executable */ AL_FUNC(void, _unix_get_executable_name, (char *output, int size)); + /* Generic system driver entry for retrievng system paths */ + AL_FUNC(int32_t _unix_get_path, (uint32_t id, char *dir, size_t size)); /* Helper for setting os_type */ AL_FUNC(void, _unix_read_os_type, (void)); @@ -122,7 +124,7 @@ */ typedef void (*bg_func) (int threaded); -/* Background function manager -- responsible for calling background +/* Background function manager -- responsible for calling background * functions. `int' methods return -1 on failure, 0 on success. */ struct bg_manager { @@ -134,7 +136,7 @@ void (*enable_interrupts) (void); void (*disable_interrupts) (void); int (*interrupts_disabled) (void); -}; +}; extern struct bg_manager _bg_man_pthreads; Modified: allegro/branches/vfs-work-4.3/include/allegro/system.h =================================================================== --- allegro/branches/vfs-work-4.3/include/allegro/system.h 2006-11-26 13:05:28 UTC (rev 7597) +++ allegro/branches/vfs-work-4.3/include/allegro/system.h 2006-11-26 19:42:21 UTC (rev 7598) @@ -94,7 +94,17 @@ AL_FUNC(void, get_executable_name, (char *output, int size)); AL_FUNC(int, set_close_button_callback, (AL_METHOD(void, proc, (void)))); +enum { + AL_PROGRAM_PATH = 0, + AL_TEMP_PATH, + AL_SYSTEM_DATA_PATH, + AL_USER_DATA_PATH, + AL_USER_HOME_PATH, + AL_LAST_PATH // must be last +}; +AL_FUNC(int32_t, al_get_path, (uint32_t id, char *path, size_t size)); + AL_FUNC(void, check_cpu, (void)); /* CPU Capabilities flags for x86 capable chips */ @@ -199,6 +209,7 @@ AL_METHOD(int, init, (void)); AL_METHOD(void, exit, (void)); AL_METHOD(void, get_executable_name, (char *output, int size)); + AL_METHOD(int32_t, get_path, (uint32_t id, char *output, size_t size)); AL_METHOD(int, find_resource, (char *dest, AL_CONST char *resource, int size)); AL_METHOD(void, set_window_title, (AL_CONST char *name)); AL_METHOD(int, set_close_button_callback, (AL_METHOD(void, proc, (void)))); Modified: allegro/branches/vfs-work-4.3/src/allegro.c =================================================================== --- allegro/branches/vfs-work-4.3/src/allegro.c 2006-11-26 13:05:28 UTC (rev 7597) +++ allegro/branches/vfs-work-4.3/src/allegro.c 2006-11-26 19:42:21 UTC (rev 7598) @@ -1,6 +1,6 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ @@ -85,12 +85,12 @@ /* default palette structures */ PALETTE black_palette; -PALETTE _current_palette; +PALETTE _current_palette; int _current_palette_changed = 0xFFFFFFFF; -PALETTE desktop_palette = +PALETTE desktop_palette = { { 63, 63, 63, 0 }, { 63, 0, 0, 0 }, { 0, 63, 0, 0 }, { 63, 63, 0, 0 }, { 0, 0, 63, 0 }, { 63, 0, 63, 0 }, { 0, 63, 63, 0 }, { 16, 16, 16, 0 }, @@ -101,69 +101,69 @@ PALETTE default_palette = { - { 0, 0, 0, 0 }, { 0, 0, 42, 0 }, { 0, 42, 0, 0 }, { 0, 42, 42, 0 }, - { 42, 0, 0, 0 }, { 42, 0, 42, 0 }, { 42, 21, 0, 0 }, { 42, 42, 42, 0 }, - { 21, 21, 21, 0 }, { 21, 21, 63, 0 }, { 21, 63, 21, 0 }, { 21, 63, 63, 0 }, - { 63, 21, 21, 0 }, { 63, 21, 63, 0 }, { 63, 63, 21, 0 }, { 63, 63, 63, 0 }, - { 0, 0, 0, 0 }, { 5, 5, 5, 0 }, { 8, 8, 8, 0 }, { 11, 11, 11, 0 }, - { 14, 14, 14, 0 }, { 17, 17, 17, 0 }, { 20, 20, 20, 0 }, { 24, 24, 24, 0 }, - { 28, 28, 28, 0 }, { 32, 32, 32, 0 }, { 36, 36, 36, 0 }, { 40, 40, 40, 0 }, - { 45, 45, 45, 0 }, { 50, 50, 50, 0 }, { 56, 56, 56, 0 }, { 63, 63, 63, 0 }, - { 0, 0, 63, 0 }, { 16, 0, 63, 0 }, { 31, 0, 63, 0 }, { 47, 0, 63, 0 }, - { 63, 0, 63, 0 }, { 63, 0, 47, 0 }, { 63, 0, 31, 0 }, { 63, 0, 16, 0 }, - { 63, 0, 0, 0 }, { 63, 16, 0, 0 }, { 63, 31, 0, 0 }, { 63, 47, 0, 0 }, - { 63, 63, 0, 0 }, { 47, 63, 0, 0 }, { 31, 63, 0, 0 }, { 16, 63, 0, 0 }, - { 0, 63, 0, 0 }, { 0, 63, 16, 0 }, { 0, 63, 31, 0 }, { 0, 63, 47, 0 }, - { 0, 63, 63, 0 }, { 0, 47, 63, 0 }, { 0, 31, 63, 0 }, { 0, 16, 63, 0 }, - { 31, 31, 63, 0 }, { 39, 31, 63, 0 }, { 47, 31, 63, 0 }, { 55, 31, 63, 0 }, - { 63, 31, 63, 0 }, { 63, 31, 55, 0 }, { 63, 31, 47, 0 }, { 63, 31, 39, 0 }, - { 63, 31, 31, 0 }, { 63, 39, 31, 0 }, { 63, 47, 31, 0 }, { 63, 55, 31, 0 }, - { 63, 63, 31, 0 }, { 55, 63, 31, 0 }, { 47, 63, 31, 0 }, { 39, 63, 31, 0 }, - { 31, 63, 31, 0 }, { 31, 63, 39, 0 }, { 31, 63, 47, 0 }, { 31, 63, 55, 0 }, - { 31, 63, 63, 0 }, { 31, 55, 63, 0 }, { 31, 47, 63, 0 }, { 31, 39, 63, 0 }, - { 45, 45, 63, 0 }, { 49, 45, 63, 0 }, { 54, 45, 63, 0 }, { 58, 45, 63, 0 }, - { 63, 45, 63, 0 }, { 63, 45, 58, 0 }, { 63, 45, 54, 0 }, { 63, 45, 49, 0 }, - { 63, 45, 45, 0 }, { 63, 49, 45, 0 }, { 63, 54, 45, 0 }, { 63, 58, 45, 0 }, - { 63, 63, 45, 0 }, { 58, 63, 45, 0 }, { 54, 63, 45, 0 }, { 49, 63, 45, 0 }, - { 45, 63, 45, 0 }, { 45, 63, 49, 0 }, { 45, 63, 54, 0 }, { 45, 63, 58, 0 }, - { 45, 63, 63, 0 }, { 45, 58, 63, 0 }, { 45, 54, 63, 0 }, { 45, 49, 63, 0 }, - { 0, 0, 28, 0 }, { 7, 0, 28, 0 }, { 14, 0, 28, 0 }, { 21, 0, 28, 0 }, - { 28, 0, 28, 0 }, { 28, 0, 21, 0 }, { 28, 0, 14, 0 }, { 28, 0, 7, 0 }, - { 28, 0, 0, 0 }, { 28, 7, 0, 0 }, { 28, 14, 0, 0 }, { 28, 21, 0, 0 }, - { 28, 28, 0, 0 }, { 21, 28, 0, 0 }, { 14, 28, 0, 0 }, { 7, 28, 0, 0 }, - { 0, 28, 0, 0 }, { 0, 28, 7, 0 }, { 0, 28, 14, 0 }, { 0, 28, 21, 0 }, - { 0, 28, 28, 0 }, { 0, 21, 28, 0 }, { 0, 14, 28, 0 }, { 0, 7, 28, 0 }, - { 14, 14, 28, 0 }, { 17, 14, 28, 0 }, { 21, 14, 28, 0 }, { 24, 14, 28, 0 }, - { 28, 14, 28, 0 }, { 28, 14, 24, 0 }, { 28, 14, 21, 0 }, { 28, 14, 17, 0 }, - { 28, 14, 14, 0 }, { 28, 17, 14, 0 }, { 28, 21, 14, 0 }, { 28, 24, 14, 0 }, - { 28, 28, 14, 0 }, { 24, 28, 14, 0 }, { 21, 28, 14, 0 }, { 17, 28, 14, 0 }, - { 14, 28, 14, 0 }, { 14, 28, 17, 0 }, { 14, 28, 21, 0 }, { 14, 28, 24, 0 }, - { 14, 28, 28, 0 }, { 14, 24, 28, 0 }, { 14, 21, 28, 0 }, { 14, 17, 28, 0 }, - { 20, 20, 28, 0 }, { 22, 20, 28, 0 }, { 24, 20, 28, 0 }, { 26, 20, 28, 0 }, - { 28, 20, 28, 0 }, { 28, 20, 26, 0 }, { 28, 20, 24, 0 }, { 28, 20, 22, 0 }, - { 28, 20, 20, 0 }, { 28, 22, 20, 0 }, { 28, 24, 20, 0 }, { 28, 26, 20, 0 }, - { 28, 28, 20, 0 }, { 26, 28, 20, 0 }, { 24, 28, 20, 0 }, { 22, 28, 20, 0 }, - { 20, 28, 20, 0 }, { 20, 28, 22, 0 }, { 20, 28, 24, 0 }, { 20, 28, 26, 0 }, - { 20, 28, 28, 0 }, { 20, 26, 28, 0 }, { 20, 24, 28, 0 }, { 20, 22, 28, 0 }, - { 0, 0, 16, 0 }, { 4, 0, 16, 0 }, { 8, 0, 16, 0 }, { 12, 0, 16, 0 }, - { 16, 0, 16, 0 }, { 16, 0, 12, 0 }, { 16, 0, 8, 0 }, { 16, 0, 4, 0 }, - { 16, 0, 0, 0 }, { 16, 4, 0, 0 }, { 16, 8, 0, 0 }, { 16, 12, 0, 0 }, - { 16, 16, 0, 0 }, { 12, 16, 0, 0 }, { 8, 16, 0, 0 }, { 4, 16, 0, 0 }, - { 0, 16, 0, 0 }, { 0, 16, 4, 0 }, { 0, 16, 8, 0 }, { 0, 16, 12, 0 }, - { 0, 16, 16, 0 }, { 0, 12, 16, 0 }, { 0, 8, 16, 0 }, { 0, 4, 16, 0 }, - { 8, 8, 16, 0 }, { 10, 8, 16, 0 }, { 12, 8, 16, 0 }, { 14, 8, 16, 0 }, - { 16, 8, 16, 0 }, { 16, 8, 14, 0 }, { 16, 8, 12, 0 }, { 16, 8, 10, 0 }, - { 16, 8, 8, 0 }, { 16, 10, 8, 0 }, { 16, 12, 8, 0 }, { 16, 14, 8, 0 }, - { 16, 16, 8, 0 }, { 14, 16, 8, 0 }, { 12, 16, 8, 0 }, { 10, 16, 8, 0 }, - { 8, 16, 8, 0 }, { 8, 16, 10, 0 }, { 8, 16, 12, 0 }, { 8, 16, 14, 0 }, - { 8, 16, 16, 0 }, { 8, 14, 16, 0 }, { 8, 12, 16, 0 }, { 8, 10, 16, 0 }, - { 11, 11, 16, 0 }, { 12, 11, 16, 0 }, { 13, 11, 16, 0 }, { 15, 11, 16, 0 }, - { 16, 11, 16, 0 }, { 16, 11, 15, 0 }, { 16, 11, 13, 0 }, { 16, 11, 12, 0 }, - { 16, 11, 11, 0 }, { 16, 12, 11, 0 }, { 16, 13, 11, 0 }, { 16, 15, 11, 0 }, - { 16, 16, 11, 0 }, { 15, 16, 11, 0 }, { 13, 16, 11, 0 }, { 12, 16, 11, 0 }, - { 11, 16, 11, 0 }, { 11, 16, 12, 0 }, { 11, 16, 13, 0 }, { 11, 16, 15, 0 }, - { 11, 16, 16, 0 }, { 11, 15, 16, 0 }, { 11, 13, 16, 0 }, { 11, 12, 16, 0 }, - { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, { 0, 0, 42, 0 }, { 0, 42, 0, 0 }, { 0, 42, 42, 0 }, + { 42, 0, 0, 0 }, { 42, 0, 42, 0 }, { 42, 21, 0, 0 }, { 42, 42, 42, 0 }, + { 21, 21, 21, 0 }, { 21, 21, 63, 0 }, { 21, 63, 21, 0 }, { 21, 63, 63, 0 }, + { 63, 21, 21, 0 }, { 63, 21, 63, 0 }, { 63, 63, 21, 0 }, { 63, 63, 63, 0 }, + { 0, 0, 0, 0 }, { 5, 5, 5, 0 }, { 8, 8, 8, 0 }, { 11, 11, 11, 0 }, + { 14, 14, 14, 0 }, { 17, 17, 17, 0 }, { 20, 20, 20, 0 }, { 24, 24, 24, 0 }, + { 28, 28, 28, 0 }, { 32, 32, 32, 0 }, { 36, 36, 36, 0 }, { 40, 40, 40, 0 }, + { 45, 45, 45, 0 }, { 50, 50, 50, 0 }, { 56, 56, 56, 0 }, { 63, 63, 63, 0 }, + { 0, 0, 63, 0 }, { 16, 0, 63, 0 }, { 31, 0, 63, 0 }, { 47, 0, 63, 0 }, + { 63, 0, 63, 0 }, { 63, 0, 47, 0 }, { 63, 0, 31, 0 }, { 63, 0, 16, 0 }, + { 63, 0, 0, 0 }, { 63, 16, 0, 0 }, { 63, 31, 0, 0 }, { 63, 47, 0, 0 }, + { 63, 63, 0, 0 }, { 47, 63, 0, 0 }, { 31, 63, 0, 0 }, { 16, 63, 0, 0 }, + { 0, 63, 0, 0 }, { 0, 63, 16, 0 }, { 0, 63, 31, 0 }, { 0, 63, 47, 0 }, + { 0, 63, 63, 0 }, { 0, 47, 63, 0 }, { 0, 31, 63, 0 }, { 0, 16, 63, 0 }, + { 31, 31, 63, 0 }, { 39, 31, 63, 0 }, { 47, 31, 63, 0 }, { 55, 31, 63, 0 }, + { 63, 31, 63, 0 }, { 63, 31, 55, 0 }, { 63, 31, 47, 0 }, { 63, 31, 39, 0 }, + { 63, 31, 31, 0 }, { 63, 39, 31, 0 }, { 63, 47, 31, 0 }, { 63, 55, 31, 0 }, + { 63, 63, 31, 0 }, { 55, 63, 31, 0 }, { 47, 63, 31, 0 }, { 39, 63, 31, 0 }, + { 31, 63, 31, 0 }, { 31, 63, 39, 0 }, { 31, 63, 47, 0 }, { 31, 63, 55, 0 }, + { 31, 63, 63, 0 }, { 31, 55, 63, 0 }, { 31, 47, 63, 0 }, { 31, 39, 63, 0 }, + { 45, 45, 63, 0 }, { 49, 45, 63, 0 }, { 54, 45, 63, 0 }, { 58, 45, 63, 0 }, + { 63, 45, 63, 0 }, { 63, 45, 58, 0 }, { 63, 45, 54, 0 }, { 63, 45, 49, 0 }, + { 63, 45, 45, 0 }, { 63, 49, 45, 0 }, { 63, 54, 45, 0 }, { 63, 58, 45, 0 }, + { 63, 63, 45, 0 }, { 58, 63, 45, 0 }, { 54, 63, 45, 0 }, { 49, 63, 45, 0 }, + { 45, 63, 45, 0 }, { 45, 63, 49, 0 }, { 45, 63, 54, 0 }, { 45, 63, 58, 0 }, + { 45, 63, 63, 0 }, { 45, 58, 63, 0 }, { 45, 54, 63, 0 }, { 45, 49, 63, 0 }, + { 0, 0, 28, 0 }, { 7, 0, 28, 0 }, { 14, 0, 28, 0 }, { 21, 0, 28, 0 }, + { 28, 0, 28, 0 }, { 28, 0, 21, 0 }, { 28, 0, 14, 0 }, { 28, 0, 7, 0 }, + { 28, 0, 0, 0 }, { 28, 7, 0, 0 }, { 28, 14, 0, 0 }, { 28, 21, 0, 0 }, + { 28, 28, 0, 0 }, { 21, 28, 0, 0 }, { 14, 28, 0, 0 }, { 7, 28, 0, 0 }, + { 0, 28, 0, 0 }, { 0, 28, 7, 0 }, { 0, 28, 14, 0 }, { 0, 28, 21, 0 }, + { 0, 28, 28, 0 }, { 0, 21, 28, 0 }, { 0, 14, 28, 0 }, { 0, 7, 28, 0 }, + { 14, 14, 28, 0 }, { 17, 14, 28, 0 }, { 21, 14, 28, 0 }, { 24, 14, 28, 0 }, + { 28, 14, 28, 0 }, { 28, 14, 24, 0 }, { 28, 14, 21, 0 }, { 28, 14, 17, 0 }, + { 28, 14, 14, 0 }, { 28, 17, 14, 0 }, { 28, 21, 14, 0 }, { 28, 24, 14, 0 }, + { 28, 28, 14, 0 }, { 24, 28, 14, 0 }, { 21, 28, 14, 0 }, { 17, 28, 14, 0 }, + { 14, 28, 14, 0 }, { 14, 28, 17, 0 }, { 14, 28, 21, 0 }, { 14, 28, 24, 0 }, + { 14, 28, 28, 0 }, { 14, 24, 28, 0 }, { 14, 21, 28, 0 }, { 14, 17, 28, 0 }, + { 20, 20, 28, 0 }, { 22, 20, 28, 0 }, { 24, 20, 28, 0 }, { 26, 20, 28, 0 }, + { 28, 20, 28, 0 }, { 28, 20, 26, 0 }, { 28, 20, 24, 0 }, { 28, 20, 22, 0 }, + { 28, 20, 20, 0 }, { 28, 22, 20, 0 }, { 28, 24, 20, 0 }, { 28, 26, 20, 0 }, + { 28, 28, 20, 0 }, { 26, 28, 20, 0 }, { 24, 28, 20, 0 }, { 22, 28, 20, 0 }, + { 20, 28, 20, 0 }, { 20, 28, 22, 0 }, { 20, 28, 24, 0 }, { 20, 28, 26, 0 }, + { 20, 28, 28, 0 }, { 20, 26, 28, 0 }, { 20, 24, 28, 0 }, { 20, 22, 28, 0 }, + { 0, 0, 16, 0 }, { 4, 0, 16, 0 }, { 8, 0, 16, 0 }, { 12, 0, 16, 0 }, + { 16, 0, 16, 0 }, { 16, 0, 12, 0 }, { 16, 0, 8, 0 }, { 16, 0, 4, 0 }, + { 16, 0, 0, 0 }, { 16, 4, 0, 0 }, { 16, 8, 0, 0 }, { 16, 12, 0, 0 }, + { 16, 16, 0, 0 }, { 12, 16, 0, 0 }, { 8, 16, 0, 0 }, { 4, 16, 0, 0 }, + { 0, 16, 0, 0 }, { 0, 16, 4, 0 }, { 0, 16, 8, 0 }, { 0, 16, 12, 0 }, + { 0, 16, 16, 0 }, { 0, 12, 16, 0 }, { 0, 8, 16, 0 }, { 0, 4, 16, 0 }, + { 8, 8, 16, 0 }, { 10, 8, 16, 0 }, { 12, 8, 16, 0 }, { 14, 8, 16, 0 }, + { 16, 8, 16, 0 }, { 16, 8, 14, 0 }, { 16, 8, 12, 0 }, { 16, 8, 10, 0 }, + { 16, 8, 8, 0 }, { 16, 10, 8, 0 }, { 16, 12, 8, 0 }, { 16, 14, 8, 0 }, + { 16, 16, 8, 0 }, { 14, 16, 8, 0 }, { 12, 16, 8, 0 }, { 10, 16, 8, 0 }, + { 8, 16, 8, 0 }, { 8, 16, 10, 0 }, { 8, 16, 12, 0 }, { 8, 16, 14, 0 }, + { 8, 16, 16, 0 }, { 8, 14, 16, 0 }, { 8, 12, 16, 0 }, { 8, 10, 16, 0 }, + { 11, 11, 16, 0 }, { 12, 11, 16, 0 }, { 13, 11, 16, 0 }, { 15, 11, 16, 0 }, + { 16, 11, 16, 0 }, { 16, 11, 15, 0 }, { 16, 11, 13, 0 }, { 16, 11, 12, 0 }, + { 16, 11, 11, 0 }, { 16, 12, 11, 0 }, { 16, 13, 11, 0 }, { 16, 15, 11, 0 }, + { 16, 16, 11, 0 }, { 15, 16, 11, 0 }, { 13, 16, 11, 0 }, { 12, 16, 11, 0 }, + { 11, 16, 11, 0 }, { 11, 16, 12, 0 }, { 11, 16, 13, 0 }, { 11, 16, 15, 0 }, + { 11, 16, 16, 0 }, { 11, 15, 16, 0 }, { 11, 13, 16, 0 }, { 11, 12, 16, 0 }, + { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 63, 63, 63, 0 } }; @@ -535,8 +535,20 @@ return -1; } +/* al_get_path: + * Gets a system path, ie: temp, home, etc + * Returns -1 on failure. + */ +int32_t al_get_path(uint32_t id, char *path, size_t size) +{ + ASSERT(system_driver); + if (system_driver->get_path) + return system_driver->get_path(id, path, size); + return -1; +} + /* debug_exit: * Closes the debugging output files. */ Modified: allegro/branches/vfs-work-4.3/src/file.c =================================================================== --- allegro/branches/vfs-work-4.3/src/file.c 2006-11-26 13:05:28 UTC (rev 7597) +++ allegro/branches/vfs-work-4.3/src/file.c 2006-11-26 19:42:21 UTC (rev 7598) @@ -1,6 +1,6 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ +/* ______ ___ ___ + * /\ _ \ /\_ \ /\_ \ + * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ @@ -98,14 +98,13 @@ ****************** Path handling ****************** ***************************************************/ - /* fix_filename_case: * Converts filename to upper case. */ char *fix_filename_case(char *filename) { ASSERT(filename); - + if (!ALLEGRO_LFN) ustrupr(filename); @@ -212,7 +211,7 @@ setpwent(); - while (((pwd = getpwent()) != NULL) && + while (((pwd = getpwent()) != NULL) && (strcmp(pwd->pw_name, ascii_username) != 0)) ; @@ -479,7 +478,7 @@ * or start with a '/' (Unix) are considered absolute. */ #if (defined ALLEGRO_DOS) || (defined ALLEGRO_WINDOWS) - if (ustrchr(filename, DEVICE_SEPARATOR)) + if (ustrchr(filename, DEVICE_SEPARATOR)) return FALSE; #endif @@ -695,8 +694,8 @@ /* file_exists: * Checks whether a file matching the given name and attributes exists, * returning non zero if it does. The file attribute may contain any of - * the FA_* constants from dir.h. If aret is not null, it will be set - * to the attributes of the matching file. If an error occurs the system + * the FA_* constants from dir.h. If aret is not null, it will be set + * to the attributes of the matching file. If an error occurs the system * error code will be stored in errno. */ int file_exists(AL_CONST char *filename, int attrib, int *aret) @@ -824,7 +823,7 @@ *allegro_errno = errno; return -1; } - + return 0; } @@ -839,7 +838,7 @@ * can use this for whatever you like). If an error occurs an error code * will be stored in errno, and callback() can cause for_each_file() to * abort by setting errno itself. Returns the number of successful calls - * made to callback(). The file attribute may contain any of the FA_* + * made to callback(). The file attribute may contain any of the FA_* * flags from dir.h. */ int for_each_file(AL_CONST char *name, int attrib, void (*callback)(AL_CONST char *filename, int attrib, int param), int param) @@ -967,7 +966,7 @@ usetc(hash+usetc(hash, '#'), 0); - /* try path/name */ + /* try path/name */ if (ugetc(name)) { ustrzcpy(dest, size, path); ustrzcat(dest, size, name); @@ -1018,7 +1017,7 @@ return 0; } - /* try path/objectname */ + /* try path/objectname */ if (objectname) { ustrzcpy(dest, size, path); ustrzcat(dest, size, objectname); @@ -1063,12 +1062,12 @@ RESOURCE_PATH *node = resource_path_list; RESOURCE_PATH *prior_node = NULL; RESOURCE_PATH *new_node = NULL; - + while (node && node->priority > priority) { prior_node = node; node = node->next; } - + if (path) { if (node && priority == node->priority) new_node = node; @@ -1076,9 +1075,9 @@ new_node = _AL_MALLOC(sizeof(RESOURCE_PATH)); if (!new_node) return 0; - + new_node->priority = priority; - + if (prior_node) { prior_node->next = new_node; new_node->next = node; @@ -1087,12 +1086,12 @@ new_node->next = resource_path_list; resource_path_list = new_node; } - + if (!resource_path_list->next) _add_exit_func(destroy_resource_path_list, "destroy_resource_path_list"); } - + ustrzcpy(new_node->path, sizeof(new_node->path) - ucwidth(OTHER_PATH_SEPARATOR), path); @@ -1105,16 +1104,16 @@ prior_node->next = node->next; else resource_path_list = node->next; - + _AL_FREE(node); - + if (!resource_path_list) _remove_exit_func(destroy_resource_path_list); } else return 0; } - + return 1; } @@ -1123,10 +1122,10 @@ static void destroy_resource_path_list(void) { RESOURCE_PATH *node = resource_path_list; - + if (node) _remove_exit_func(destroy_resource_path_list); - + while (node) { resource_path_list = node->next; _AL_FREE(node); @@ -1154,7 +1153,7 @@ char *s; int i, c; RESOURCE_PATH *rp_list_node = resource_path_list; - + ASSERT(dest); /* if the resource is a path with no filename, look in that location */ @@ -1224,7 +1223,7 @@ put_backslash(path); if (find_resource(dest, path, rname, datafile, objectname, subdir, size) == 0) - return 0; + return 0; } /* try any extra environment variable that the parameters say to use */ @@ -1236,7 +1235,7 @@ put_backslash(path); if (find_resource(dest, path, rname, datafile, objectname, subdir, size) == 0) - return 0; + return 0; } } @@ -1269,7 +1268,7 @@ } } - /* argh, all that work, and still no biscuit */ + /* argh, all that work, and still no biscuit */ return -1; } @@ -1335,7 +1334,7 @@ /* pack_fopen_datafile_object: - * Recursive helper to handle opening member objects from datafiles, + * Recursive helper to handle opening member objects from datafiles, * given a fake filename in the form 'object_name[/nestedobject]'. */ static PACKFILE *pack_fopen_datafile_object(PACKFILE *f, AL_CONST char *objname) @@ -1406,7 +1405,7 @@ /* oh dear, the object isn't there... */ pack_fclose(f); *allegro_errno = ENOENT; - return NULL; + return NULL; } @@ -1677,7 +1676,7 @@ pack_mputl(encrypt_id(F_NOPACK_MAGIC, TRUE), f); } } - else { + else { if (f->normal.flags & PACKFILE_FLAG_PACK) { /* read a packed file */ f->normal.unpack_data = create_lzss_unpack_data(); @@ -1703,37 +1702,37 @@ { /* duplicate the file descriptor */ int fd2 = dup(fd); - + if (fd2<0) { pack_fclose(f->normal.parent); free_packfile(f); *allegro_errno = errno; return NULL; } - + /* close the parent file (logically, not physically) */ pack_fclose(f->normal.parent); - + /* backward compatibility mode */ if (!clone_password(f)) { free_packfile(f); return NULL; } - + f->normal.flags |= PACKFILE_FLAG_OLD_CRYPT; - + /* re-open the parent file */ lseek(fd2, 0, SEEK_SET); - + if ((f->normal.parent = _pack_fdopen(fd2, F_READ)) == NULL) { free_packfile(f); return NULL; } - + f->normal.parent->normal.flags |= PACKFILE_FLAG_OLD_CRYPT; - + pack_mgetl(f->normal.parent); - + if (header == encrypt_id(F_PACK_MAGIC, FALSE)) header = encrypt_id(F_PACK_MAGIC, TRUE); else @@ -1798,11 +1797,11 @@ * data does not need to be decompressed. * * Instead of these flags, one of the constants F_READ, F_WRITE, - * F_READ_PACKED, F_WRITE_PACKED or F_WRITE_NOPACK may be used as the second + * F_READ_PACKED, F_WRITE_PACKED or F_WRITE_NOPACK may be used as the second * argument to fopen(). * * On success, fopen() returns a pointer to a file structure, and on error - * it returns NULL and stores an error code in errno. An attempt to read a + * it returns NULL and stores an error code in errno. An attempt to read a * normal file in packed mode will cause errno to be set to EDOM. */ PACKFILE *pack_fopen(AL_CONST char *filename, AL_CONST char *mode) @@ -1912,12 +1911,12 @@ -/* pack_fopen_chunk: +/* pack_fopen_chunk: * Opens a sub-chunk of the specified file, for reading or writing depending * on the type of the file. The returned file pointer describes the sub * chunk, and replaces the original file, which will no longer be valid. * When writing to a chunk file, data is sent to the original file, but - * is prefixed with two length counts (32 bit, big-endian). For uncompressed + * is prefixed with two length counts (32 bit, big-endian). For uncompressed * chunks these will both be set to the length of the data in the chunk. * For compressed chunks, created by setting the pack flag, the first will * contain the raw size of the chunk, and the second will be the negative @@ -1945,7 +1944,7 @@ if (f->normal.flags & PACKFILE_FLAG_WRITE) { - /* write a sub-chunk */ + /* write a sub-chunk */ int tmp_fd = -1; char *tmp_dir = NULL; char *tmp_name = NULL; @@ -1956,14 +1955,14 @@ #ifdef ALLEGRO_WINDOWS int size; int new_size = 64; - + /* Get the path of the temporary directory */ do { size = new_size; tmp_dir = realloc(tmp_dir, size); new_size = GetTempPath(size, tmp_dir); } while ( (size > new_size) && (new_size > 0) ); - + /* Check if we retrieved the path OK */ if (new_size == 0) sprintf(tmp_dir, "%s", ""); @@ -2022,7 +2021,7 @@ if (tmp_fd < 0) { _AL_FREE(tmp_dir); _AL_FREE(tmp_name); - + return NULL; } @@ -2039,7 +2038,7 @@ chunk->normal.flags |= PACKFILE_FLAG_CHUNK; } - + free(tmp_dir); free(tmp_name); } @@ -2097,7 +2096,7 @@ /* pack_fclose_chunk: * Call after reading or writing a sub-chunk. This closes the chunk file, * and returns a pointer to the original file structure (the one you - * passed to pack_fopen_chunk()), to allow you to read or write data + * passed to pack_fopen_chunk()), to allow you to read or write data * after the chunk. If an error occurs, returns NULL and sets errno. */ PACKFILE *pack_fclose_chunk(PACKFILE *f) @@ -2197,7 +2196,7 @@ /* pack_fseek: - * Like the stdio fseek() function, but only supports forward seeks + * Like the stdio fseek() function, but only supports forward seeks * relative to the current file position. */ int pack_fseek(PACKFILE *f, int offset) @@ -2240,7 +2239,7 @@ /* pack_feof: - * pack_feof() returns nonzero as soon as you reach the end of the file. It + * pack_feof() returns nonzero as soon as you reach the end of the file. It * does not wait for you to attempt to read beyond the end of the file, * contrary to the ISO C feof() function. */ @@ -2433,8 +2432,8 @@ /* pack_fread: - * Reads n bytes from f and stores them at memory location p. Returns the - * number of items read, which will be less than n if EOF is reached or an + * Reads n bytes from f and stores them at memory location p. Returns the + * number of items read, which will be less than n if EOF is reached or an * error occurs. Error codes are stored in errno. */ long pack_fread(void *p, long n, PACKFILE *f) @@ -2451,8 +2450,8 @@ /* pack_fwrite: - * Writes n bytes to the file f from memory location p. Returns the number - * of items written, which will be less than n if an error occurs. Error + * Writes n bytes to the file f from memory location p. Returns the number + * of items written, which will be less than n if an error occurs. Error * codes are stored in errno. */ long pack_fwrite(AL_CONST void *p, long n, PACKFILE *f) @@ -2488,7 +2487,7 @@ * Reads a line from a text file, storing it at location p. Stops when a * linefeed is encountered, or max bytes have been read. Returns a pointer * to where it stored the text, or NULL on error. The end of line is - * handled by detecting optional '\r' characters optionally followed + * handled by detecting optional '\r' characters optionally followed * by '\n' characters. This supports CR-LF (DOS/Windows), LF (Unix), and * CR (Mac) formats. */ @@ -2868,7 +2867,7 @@ } else { f->normal.buf_size = pack_fread(f->normal.buf, MIN(F_BUF_SIZE, f->normal.todo), f->normal.parent); - } + } if (f->normal.parent->normal.flags & PACKFILE_FLAG_EOF) f->normal.todo = 0; if (f->normal.parent->normal.flags & PACKFILE_FLAG_ERROR) Modified: allegro/branches/vfs-work-4.3/src/fshook.c =================================================================== --- allegro/branches/vfs-work-4.3/src/fshook.c 2006-11-26 13:05:28 UTC (rev 7597) +++ allegro/branches/vfs-work-4.3/src/fshook.c 2006-11-26 19:42:21 UTC (rev 7598) @@ -29,6 +29,22 @@ return -1; switch(phid) { + case AL_FS_HOOK_CREATE_HANDLE: + _al_fshooks.create_handle = fshook; + break; + + case AL_FS_HOOK_DESTROY_HANDLE: + _al_fshooks.destroy_handle = fshook; + break; + + case AL_FS_HOOK_OPEN_HANDLE: + _al_fshooks.open_handle = fshook; + break; + + case AL_FS_HOOK_CLOSE_HANDLE: + _al_fshooks.close_handle = fshook; + break; + case AL_FS_HOOK_FOPEN: _al_fshooks.fopen = fshook; break; @@ -93,10 +109,6 @@ _al_fshooks.chdir = fshook; break; - case AL_FS_HOOK_GETDIR: - _al_fshooks.getdir = fshook; - break; - case AL_FS_HOOK_ADD_SEARCH_PATH: _al_fshooks.add_search_path = fshook; break; @@ -152,94 +164,164 @@ return NULL; switch(phid) { + case AL_FS_HOOK_CREATE_HANDLE: + ptr = _al_fshooks.create_handle; + break; + + case AL_FS_HOOK_DESTROY_HANDLE: + ptr = _al_fshooks.destroy_handle; + break; + + case AL_FS_HOOK_OPEN_HANDLE: + ptr = _al_fshooks.open_handle; + break; + + case AL_FS_HOOK_CLOSE_HANDLE: + ptr = _al_fshooks.close_handle; + break; + case AL_FS_HOOK_FOPEN: ptr = _al_fshooks.fopen; + break; case AL_FS_HOOK_FCLOSE: ptr = _al_fshooks.fclose; + break; case AL_FS_HOOK_FREAD: ptr = _al_fshooks.fread; + break; case AL_FS_HOOK_FWRITE: ptr = _al_fshooks.fwrite; + break; case AL_FS_HOOK_FFLUSH: ptr = _al_fshooks.fflush; + break; case AL_FS_HOOK_FSEEK: ptr = _al_fshooks.fseek; + break; case AL_FS_HOOK_FTELL: ptr = _al_fshooks.ftell; + break; case AL_FS_HOOK_FERROR: ptr = _al_fshooks.ferror; + break; case AL_FS_HOOK_FEOF: ptr = _al_fshooks.feof; + break; case AL_FS_HOOK_FSTAT: ptr = _al_fshooks.fstat; + break; case AL_FS_HOOK_OPENDIR: ptr = _al_fshooks.opendir; + break; case AL_FS_HOOK_CLOSEDIR: ptr = _al_fshooks.closedir; + break; case AL_FS_HOOK_READDIR: ptr = _al_fshooks.readdir; + break; case AL_FS_HOOK_MKTEMP: ptr = _al_fshooks.mktemp; + break; case AL_FS_HOOK_GETCWD: ptr = _al_fshooks.getcwd; + break; case AL_FS_HOOK_CHDIR: ptr = _al_fshooks.chdir; + break; case AL_FS_HOOK_GETDIR: ptr = _al_fshooks.getdir; + break; case AL_FS_HOOK_ADD_SEARCH_PATH: ptr = _al_fshooks.add_search_path; + break; case AL_FS_HOOK_SEARCH_PATH_COUNT: ptr = _al_fshooks.search_path_count; + break; case AL_FS_HOOK_GET_SEARCH_PATH: ptr = _al_fshooks.get_search_path; + break; case AL_FS_HOOK_GET_STAT_MODE: ptr = _al_fshooks.get_stat_mode; + break; case AL_FS_HOOK_GET_STAT_ATIME: ptr = _al_fshooks.get_stat_atime; + break; case AL_FS_HOOK_GET_STAT_MTIME: ptr = _al_fshooks.get_stat_mtime; + break; case AL_FS_HOOK_GET_STAT_SIZE: ptr = _al_fshooks.get_stat_size; + break; case AL_FS_HOOK_GET_STAT_CTIME: ptr = _al_fshooks.get_stat_ctime; + break; case AL_FS_HOOK_PATH_TO_SYS: ptr = _al_fshooks.path_to_sys; + break; case AL_FS_HOOK_PATH_TO_UNI: ptr = _al_fshooks.path_to_uni; + break; default: ptr = NULL; + break; } return ptr; } +/* NULL is a valid value for path */ +AL_FILE *al_fs_create_handle(AL_CONST char *path) +{ + return _al_fs_hook_create_handle(path); +} + +void al_fs_destroy_handle(AL_FILE *handle) +{ + _al_fs_hook_destroy_handle(handle); +} + +int32_t al_fs_open_handle(AL_FILE *handle, AL_CONST char *mode) +{ + ASSERT(handle); + ASSERT(mode); + + return _al_fs_hook_open_handle(handle, mode); +} + +int32_t al_fs_close_handle(AL_FILE *handle) +{ + ASSERT(handle); + + return _al_fs_hook_close_handle(handle); +} + AL_FILE *al_fs_fopen(const char *path, const char *mode) { ASSERT(path != NULL); @@ -309,12 +391,11 @@ } -int32_t al_fs_fstat(const char *path, AL_STAT *stbuf) +int32_t al_fs_fstat(AL_FILE *fp) { - ASSERT(path != NULL); - ASSERT(stbuf != NULL); + ASSERT(fp != NULL); - return _al_fs_hook_fstat(path, stbuf); + return _al_fs_hook_fstat(fp); } @@ -362,16 +443,6 @@ return _al_fs_hook_chdir(path); } -int32_t al_fs_getdir(uint32_t id, char *dir, size_t *len) -{ - ASSERT(id >= 0 && id < AL_DIR_LAST); - ASSERT(dir); - ASSERT(len); - - return _al_fs_hook_getdir(id, dir, len); -} - - int32_t al_fs_add_search_path(const char *path) { ASSERT(path); @@ -392,7 +463,25 @@ return _al_fs_hook_get_search_path(idx, dest, len); } +int32_t al_fs_unlink( const char *path ) +{ + AL_FILE *fp = NULL; + int32_t ret = 0; + ASSERT(path); + fp = al_fs_create_handle( path ); + ret = al_fs_funlink( fp ); + al_fs_destroy_handle( fp ); + return fp; +} + +int32_t al_fs_funlink( AL_FILE *fp ) +{ + ASSERT(fp); + + return _al_fs_hook_funlink( fp ); +} + uint32_t al_fs_get_stat_mode(AL_STAT *st) { return _al_fs_hook_get_stat_mode(st); Modified: allegro/branches/vfs-work-4.3/src/fshook_stdio.c =================================================================== --- allegro/branches/vfs-work-4.3/src/fshook_stdio.c 2006-11-26 13:05:28 UTC (rev 7597) +++ allegro/branches/vfs-work-4.3/src/fshook_stdio.c 2006-11-26 19:42:21 UTC (rev 7598) @@ -15,6 +15,8 @@ * See readme.txt for copyright information. */ +#define ALLEGRO_FS_FILE_DEFINED + #include "allegro.h" #include "allegro/debug.h" #include "allegro/fshook.h" @@ -57,8 +59,33 @@ #define PREFIX_I "al-fs-stdio INFO: " +/* FIXME: + +should AL_FILE carry a vtable? so the io handler can be changed without fucking up + +*/ + +typedef struct AL_FILE AL_FILE; +struct AL_FILE { + AL_FS_HOOK_VTABLE vtable; + FILE *handle; + struct stat st; + char *path; + char *found; + char mode[6]; + uint32_t free_on_fclose; + uint32_t ulink; +}; + +static char **search_path = NULL; +static uint32_t search_path_count = 0; + uint32_t al_fs_init_stdio(void) { + al_fs_set_hook(AL_FS_HOOK_CREATE_HANDLE, al_fs_stdio_create_handle); + al_fs_set_hook(AL_FS_HOOK_DESTROY_HANDLE, al_fs_stdio_destroy_handle); + al_fs_set_hook(AL_FS_HOOK_OPEN_HANDLE, al_fs_stdio_open_handle); + al_fs_set_hook(AL_FS_HOOK_CLOSE_HANDLE, al_fs_stdio_close_handle); al_fs_set_hook(AL_FS_HOOK_FOPEN, al_fs_stdio_fopen); al_fs_set_hook(AL_FS_HOOK_FCLOSE, al_fs_stdio_fclose); @@ -79,7 +106,6 @@ al_fs_set_hook(AL_FS_HOOK_MKTEMP, al_fs_stdio_mktemp); al_fs_set_hook(AL_FS_HOOK_GETCWD, al_fs_stdio_getcwd); al_fs_set_hook(AL_FS_HOOK_CHDIR, al_fs_stdio_chdir); - al_fs_set_hook(AL_FS_HOOK_GETDIR, al_fs_stdio_getdir); al_fs_set_hook(AL_FS_HOOK_ADD_SEARCH_PATH, al_fs_stdio_add_search_path); al_fs_set_hook(AL_FS_HOOK_SEARCH_PATH_COUNT, al_fs_stdio_search_path_count); @@ -97,40 +123,164 @@ return 0; } -AL_FILE *al_fs_stdio_fopen(const char *path, const char *mode) +/* BIG ASS FIXME: I just added this to the wrong function, move the new lookup code to open_handle */ +AL_FILE *al_fs_stdio_create_handle(AL_CONST char *path) { - FILE *fh = fopen(path, mode); + AL_FILE *fh = NULL; + uint32_t len = 0; + + fh = AL_MALLOC(sizeof(AL_FILE)); if(!fh) { *allegro_errno = errno; return NULL; } - return (AL_FILE *)fh; + len = strlen( path ); + fh->path = AL_MALLOC(len+1); + if(!fh->path) { + *allegro_errno = errno; + AL_FREE(fh); + return NULL; + } + + memcpy(fh->path, path, len+1); + + return fh; } -int32_t al_fs_stdio_fclose(AL_FILE *fp) +void al_fs_stdio_destroy_handle(AL_FILE *handle) { - int32_t ret = fclose(fp); - if(ret == EOF) { - *allegro_errno = errno; + if(handle->found) { + if(handle->ulink) + unlink( handle->found ); + + AL_FREE(handle->found); } + else { + if(handle->ulink) + unlink( handle->path ); + } - return ret; + if(handle->path) + AL_FREE(handle->path); + + if(handle->handle) + fclose(handle->handle); + + memset(handle, 0, sizeof(AL_FILE)); + AL_FREE(handle); } +int32_t al_fs_stdio_open_handle(AL_FILE *fh, AL_CONST char *mode) +{ + char *tmp = NULL; + int len = 0; + uint32_t spi = 0; + + len = strlen(fh->path); + + /* absolute path, just try and open, no search_path lookup */ + if(fh->path[0] == '/') { + fh->handle = fopen( fh->path, mode ); + if(!fh->handle) { + *allegro_errno = errno; + return -1; + } + return 0; + } + + for(spi = 0; spi < search_path_count; ++spi) { + uint32_t splen = strlen( search_path[spi] ); + tmp = _AL_REALLOC( tmp, splen + len + 1 ); + memcpy(tmp, search_path[spi], MIN(splen, PATH_MAX)); + if(tmp[splen-1] == '/') { + tmp[splen] = '/'; + splen++; + } + + memcpy(tmp+splen, fh->path, MIN(len + splen, PATH_MAX)); + tmp[splen+len] = '\0'; + + fh->handle = fopen( tmp, mode ); + if(!fh->handle) + continue; + + fh->found = tmp; + + return 0; + } + + AL_FREE(tmp); + + return -1; +} + +void al_fs_stdio_close_handle(AL_FILE *handle) +{ + int32_t ret = 0; + + if(handle->handle) { + ret = fclose(handle->handle); + + /* unlink on close */ + if(handle->found && handle->ulink) { + unlink( handle->found ); + AL_FREE( handle->found ); + handle->found = NULL; + } + else if(handle->path && handle->ulink) { + unlink( handle->found ); + } + + handle->handle = NULL; + } + + return; +} + +/* FIXME: lookup stuff in search path */ +AL_FILE *al_fs_stdio_fopen(const char *path, const char *mode) +{ + AL_FILE *fh = al_fs_stdio_create_handle(path); + if(al_fs_stdio_open_handle(fh, mode) != 0) { + return -1; + } + + fh->free_on_fclose = 1; + return fh; +} + +void al_fs_stdio_fclose(AL_FILE *fp) +{ + al_fs_stdio_close_handle(fp); + + if(fp->free_on_fclose) + al_fs_stdio_destroy_handle(fp); +} + size_t al_fs_stdio_fread(void *ptr, size_t size, AL_FILE *fp) { - return fread(ptr, 1, size, (FILE *)fp); + size_t ret = fread(ptr, 1, size, fp->handle); + if(ret == 0) { + *allegro_errno = errno; + } + + return ret; } size_t al_fs_stdio_fwrite(const void *ptr, size_t size, AL_FILE *fp) { - return fwrite(ptr, 1, size, (FILE *)fp); + size_t ret = fwrite(ptr, 1, size, fp->handle); + if(ret == 0) { + *allegro_errno = errno; + } + + return ret; } int32_t al_fs_stdio_fflush(AL_FILE *fp) { - int32_t ret = fflush((FILE *)fp); + int32_t ret = fflush(fp->handle); if(ret == EOF) { *allegro_errno = errno; } @@ -140,7 +290,7 @@ int32_t al_fs_stdio_fseek(AL_FILE *fp, uint32_t offset, uint32_t whence) { - int32_t ret; + int32_t ret = 0; switch(whence) { case AL_SEEK_SET: whence = SEEK_SET; break; @@ -148,7 +298,7 @@ case AL_SEEK_END: whence = SEEK_END; break; } - ret = fseek((FILE *)fp, offset, whence); + ret = fseek(fp->handle, offset, whence); if(ret == -1) { *allegro_errno = errno; } @@ -158,7 +308,7 @@ int32_t al_fs_stdio_ftell(AL_FILE *fp) { - int32_t ret = ftell((FILE *)fp); + int32_t ret = ftell(fp->handle); if(ret == -1) { *allegro_errno = errno; } @@ -168,34 +318,25 @@ int32_t al_fs_stdio_ferror(AL_FILE *fp) { - return ferror((FILE *)fp); + return ferror(fp->handle); } int32_t al_fs_stdio_feof(AL_FILE *fp) { - return feof((FILE *)fp); + return feof(fp->handle); } -AL_STAT *al_fs_stdio_fstat(const char *path) +int32_t al_fs_stdio_fstat(AL_FILE *fp) { - struct stat *st = NULL; int32_t ret = 0; - st = malloc(sizeof(struct stat)); - if(!st) { - *allegro_errno = ENOMEM; - return NULL; - } - - ret = stat(path, st); + ret = stat(path, &(fp->st)); if(ret == -1) { *allegro_errno = errno; - free(st); - return NULL; } - return (AL_STAT *)st; + return ret; } @@ -230,327 +371,119 @@ return ent; } +#define MAX_MKTEMP_TRIES 1000 +const char mktemp_ok_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; -AL_FILE *al_fs_stdio_mktemp(const char *template) +void _al_fs_mktemp_replace_XX(char *template, char *dst) { - int32_t fd = mkstemp(template); - FILE *fh = NULL; + size_t len = strlen(template); + uint32_t i = 0; - if(fd == -1) { - *allegro_errno = errno; - return NULL; + for(i=0; i<len; ++i) { + if(template[i] != 'X') { + dst[i] = template[i]; + } + else { + dst[i] = mktemp_ok_chars[ _al_rand() % (sizeof(mktemp_ok_chars)-1) ]; + } } - - fh = fdopen(fd, "r+"); - if(!fh) { - *allegro_errno = errno; - close(fd); - return NULL; - } - - return fh; } -int32_t al_fs_stdio_getcwd(char *buf, size_t len) -{ - char *cwd = getcwd(buf, len); - if(!cwd) { - *allegro_errno = errno; - return -1; - } +/* FIXME: provide the filename created. */ +/* might have to make AL_FILE a strust to provide the filename, and unlink hint. */ +/* by default, temp file is NOT unlink'ed automatically */ - return 0; -} - -int32_t al_fs_stdio_chdir(const char *path) +AL_FILE *al_fs_stdio_mktemp(const char *template, uint32_t ulink) { - int32_t ret = chdir(path); - if(ret == -1) { - *allegro_errno = errno; - } + int32_t fd = -1, tries = 0; + int32_t template_len = 0, tmpdir_len = 0; + AL_FILE *fh = NULL; + char *dest = NULL; + char tmpdir[PATH_MAX]; - return ret; -} + template_len = strlen( template ); -#ifdef ALLEGRO_WINDOWS - -/* - Will at most copy MAX_PATH bytes including nul to "dir" - May cause some truncation, in some cases. -*/ -int32_t al_fs_stdio_getdir(uint32_t id, char *dir, uint32_t *len) -{ - char path[MAX_PATH], tmp[256]; - uint32_t csidl = 0, path_len = MIN(*len, MAX_PATH); - HRESULT ret = 0; - HANDLE process = GetCurrentProcess(); - - switch(id) { - case AL_SYSTEM_PROGRAM_DIR: /* CSIDL_PROGRAM_FILES + ApplicationName */ - csidl = CSIDL_PROGRAM_FILES; - break; - - case AL_PROGRAM_DIR: { /* where the program is in */ - HMODULE module = GetModuleHandle(NULL); /* Get handle for this process */ - DWORD mret = GetModuleFileNameEx(process, handle, path, MAX_PATH); - char *ptr = strrchr(path, '\\'); - if(!ptr) { /* shouldn't happen */ - return -1; - } - - /* chop off everything including and after the last slash */ - /* should this not chop the slash? */ - *ptr = '\0'; - - return 0; - } break; - - case AL_SYSTEM_DATA_DIR: /* CSIDL_COMMON_APPDATA */ - csidl = CSIDL_COMMON_APPDATA; - break; - - case AL_USER_DATA_DIR: /* CSIDL_APPDATA */ - csidl = CSIDL_APPDATA; - break; - - case AL_USER_HOME_DIR: /* CSIDL_PROFILE */ - csidl = CSIDL_PROFILE; - break; - - default: - return -1; + if(al_get_path(AL_TEMP_PATH, tmpdir, PATH_MAX) != 0) { + ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Failed to find temp directory")); + return NULL; } - ret = SHGetFolderPath(NULL, csidl, NULL, SHGFP_TYPE_CURRENT, path); - if(ret != S_OK) { - return -1; - } + tmpdir_len = strlen( tmpdir_len ); - _al_sane_strncpy(dir, path, path_len); - - *len = path_len; - - return 0; -} - -#else /* Unix */ - -int32_t _al_find_home(char *dir, uint32_t len) -{ - char *home_env = getenv("HOME"); - if(!home_env || home_env[0] == '\0') { - /* since HOME isn't set, we have to ask libc for the info */ - - /* get user id */ - uid_t uid = getuid(); - - /* grab user information */ - struct passwd *pass = getpwuid(uid); - if(!pass) { - *allegro_errno = errno; - return -1; - } - - if(pass->pw_dir) { - /* hey, we got our home directory */ - _al_sane_strncpy(dir, pass->pw_dir, strlen(pass->pw_dir)+1); - return 0; - } - else if(pass->pw_name) { - /* assume we live in /home/<username> */ - /* TODO: might want to make a "configure" option for this (/home) */ - /* should we check to see if the dir exists? */ -/* - struct stat st; - char tmp[path_max] = "/home/"; - _al_sane_strncpy(tmp, pass->pw_name, path_max); - - if(stat(tmp, &st) != 0) { - *allegro_errno = errno; - return -1; - } -*/ - _al_sane_strncpy(dir, "/home", strlen("/home")+1); - strncat(dir, pass->pw_name, len); - return 0; - } - else { - /* no home directory? */ - /* what to set allegro_errno to? */ - return -1; - } + dest = AL_MALLOC( template_len + tmpdir_len + 2 ); + if(!dest) { + *allegro_errno = errno; + return NULL; } - else { - _al_sane_strncpy(dir, home_env, strlen(home_env)+1); - return 0; - } - /* should not reach here */ - return -1; -} + memset(dest, 0, template_len + tmpdir_len + 2); + memcpy(dest, tmpdir, strlen( tmpdir ) ); -int32_t _al_find_progam_dir(char *dir, uint32_t len) -{ - char path[PATH_MAX] = ""; - char prog[PATH_MAX] = ""; - char *ptr = NULL; - uint32_t prog_len = strlen(system_driver->argv[0]), path_len = 0; - - strncat(prog, system_driver->argv[0], PATH_MAX); - - /* program name is longer than PATH_MAX, trying to grab the proper dir may result in garbled paths */ - /* Wait, is this even possible? */ - if(prog_len > PATH_MAX) { - *allegro_errno = errno = ERANGE; - return -1; + /* doing this check makes the path prettier, no extra / laying around */ + if(dest[tmpdir_len-1] != '/') { + dest[tmpdir_len] = '/'; + tmpdir_len++; } - /* absolute path */ - if(prog[0] == '/') { - _al_sane_strncpy(path, prog, prog_len+1); + memcpy(dest + tmpdir_len, template, template_len); - ptr = strrchr(path, '/'); - if(!ptr) { - *allegro_errno = errno = EINVAL; - return -1; - } + for(i=0; i<MAX_MKTEMP_TRIES; ++i) { + _al_fs_mktemp_replace_XX(template, dest + tmpdir_len); + fd = open( dest, O_EXCL | O_CREAT | O_RDWR ); + if(fd == -1) + continue; - /* chop off everything including and after the last slash */ - /* should this not chop the slash? */ - *ptr = '\0'; - - path_len = (uint32_t)( ptr - path ); - - /* actual path is longer than the provided memory block, try agian with a larger block */ - if(path_len > len) { - *allegro_errno = errno = ERANGE; - return -1; + fh = al_fs_stdio_create_handle( dest ); + if(!fh) { + close(fd); + free(dest); + return NULL; } - _al_sane_strncpy(dir, path, len); - - return 0; - } - else { - uint32_t cwd_len = 0; - char *cwd = NULL; - - memmove(prog, prog+2, prog_len + 1); - - cwd = getcwd(path, PATH_MAX); - if(!cwd) { - /* keep errno from getcwd */ - *allegro_errno = errno; - return -1; + fh->handle = fdopen( fd, "r+" ); + ... [truncated message content] |