From 8a34716fd343a4a12f6fded6d53d48024f656df9 Mon Sep 17 00:00:00 2001 From: "fabio.olimpieri" Date: Sun, 11 Jan 2015 19:53:47 +0000 Subject: [PATCH] Fixed file attributes in virtual filesystem emulation, shorter save state warning --- Makefile.wii | 4 +- src/filesys.c | 5 +- src/od-wii/fsdb_wii.c | 225 ++++++++++++++++++++++++++++++++++++++++++ src/od-wii/hrtimer.h | 38 +++++++ src/od-wii/main.c | 66 +++++++++++++ src/od-wii/memory.c | 45 +++++++++ src/od-wii/memory.h | 11 +++ src/savestate.c | 2 +- 8 files changed, 391 insertions(+), 5 deletions(-) create mode 100644 src/od-wii/fsdb_wii.c create mode 100644 src/od-wii/hrtimer.h create mode 100644 src/od-wii/main.c create mode 100644 src/od-wii/memory.c create mode 100644 src/od-wii/memory.h diff --git a/Makefile.wii b/Makefile.wii index 3b79f2b..0027a45 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -34,6 +34,7 @@ SRCS := $(wildcard $(SRC_DIR)/*.c $(SRC_DIR)/caps/*.c $(SRC_DIR)/dms/*.c $(SRC_D $(SRC_DIR)/machdep/support.c \ $(SRC_DIR)/osdep/main.c \ $(SRC_DIR)/osdep/memory.c\ + $(SRC_DIR)/osdep/fsdb_wii.c\ $(SRC_DIR)/sounddep/sound.c \ $(SRC_DIR)/threaddep/thread.c @@ -56,6 +57,7 @@ SRCS := $(filter-out \ src/enforcer.c \ src/fdi2raw.c \ src/filesys_bootrom.c \ + src/fsdb_unix.c \ src/genblitter.c \ src/gencomp.c \ src/gencpu.c \ @@ -106,7 +108,7 @@ src/machdep: src/osdep: rm -f $@ - mkdir $@ && cd src/od-generic && find . -maxdepth 1 -type f -exec ln '{}' ../osdep/'{}' ';' + mkdir $@ && cd src/od-wii && find . -maxdepth 1 -type f -exec ln '{}' ../osdep/'{}' ';' src/gfxdep: rm -f $@ diff --git a/src/filesys.c b/src/filesys.c index 0618bc2..a894197 100644 --- a/src/filesys.c +++ b/src/filesys.c @@ -67,9 +67,8 @@ static int wii_access (const char *pathname, int mode) if (stat(pathname, &st) < 0) return -1; - if (mode == R_OK && S_ISDIR(st.st_mode)) - return 0; - return -1; + + return 0; //With Wii the file/dir is considered always accessible if it exists } #define access wii_access #endif diff --git a/src/od-wii/fsdb_wii.c b/src/od-wii/fsdb_wii.c new file mode 100644 index 0000000..62486de --- /dev/null +++ b/src/od-wii/fsdb_wii.c @@ -0,0 +1,225 @@ + /* + * UAE - The Un*x Amiga Emulator + * + * Library of functions to make emulated filesystem as independent as + * possible of the host filesystem's capabilities. + * This is the Win32 version. + * + * Copyright 1997 Mathias Ortmann + * Copyright 1999 Bernd Schmidt + */ + +#ifdef FILESYS + +#include "sysconfig.h" +#include "sysdeps.h" + +#include "fsdb.h" +#include + +#define TRACING_ENABLED 0 +#if TRACING_ENABLED +#define TRACE(x) do { write_log x; } while(0) +#else +#define TRACE(x) +#endif + +/* these are deadly (but I think allowed on the Amiga): */ +#define NUM_EVILCHARS 7 +static const char evilchars[NUM_EVILCHARS] = { '\\', '*', '?', '\"', '<', '>', '|' }; + +/* Return nonzero for any name we can't create on the native filesystem. */ +int fsdb_name_invalid (const char *n) +{ + int i; + char a = n[0]; + char b = (a == '\0' ? a : n[1]); + char c = (b == '\0' ? b : n[2]); + char d = (c == '\0' ? c : n[3]); + int l = strlen (n), ll; + + if (a >= 'a' && a <= 'z') + a -= 32; + if (b >= 'a' && b <= 'z') + b -= 32; + if (c >= 'a' && c <= 'z') + c -= 32; + + /* reserved dos devices */ + ll = 0; + if (a == 'A' && b == 'U' && c == 'X') ll = 3; /* AUX */ + if (a == 'C' && b == 'O' && c == 'N') ll = 3; /* CON */ + if (a == 'P' && b == 'R' && c == 'N') ll = 3; /* PRN */ + if (a == 'N' && b == 'U' && c == 'L') ll = 3; /* NUL */ + if (a == 'L' && b == 'P' && c == 'T' && (d >= '0' && d <= '9')) ll = 4; /* LPT# */ + if (a == 'C' && b == 'O' && c == 'M' && (d >= '0' && d <= '9')) ll = 4; /* COM# */ + /* AUX.anything, CON.anything etc.. are also illegal names */ + if (ll && (l == ll || (l > ll && n[ll] == '.'))) + return 1; + + /* spaces and periods at the end are a no-no */ + i = l - 1; + if (n[i] == '.' || n[i] == ' ') + return 1; + + /* these characters are *never* allowed */ + for (i = 0; i < NUM_EVILCHARS; i++) { + if (strchr (n, evilchars[i]) != 0) + return 1; + } + + /* the reserved fsdb filename */ + if (strcmp (n, FSDB_FILE) == 0) + return 1; + return 0; /* the filename passed all checks, now it should be ok */ +} + +static uae_u32 filesys_parse_mask (uae_u32 mask) +{ + return mask ^ 0xf; +} + +int fsdb_exists (char *nname) +{ + struct stat statbuf; + + return (stat (nname, &statbuf) != -1); +} + +/* For an a_inode we have newly created based on a filename we found on the + * native fs, fill in information about this file/directory. */ +int fsdb_fill_file_attrs (a_inode *base, a_inode *aino) +{ + int mode; + + if ((mode = FAT_getAttr (aino->nname)) <0) { + write_log ("FAT_getAttr('%s') failed! error=%d, aino=%p dir=%d\n", aino->nname,errno,aino,aino->dir); + return 0; + } + + aino->dir = (mode & ATTR_DIRECTORY) ? 1 : 0; + aino->amigaos_mode = A_FIBF_EXECUTE | A_FIBF_READ; + if (ATTR_ARCHIVE & mode) + aino->amigaos_mode |= A_FIBF_ARCHIVE; + if (! (ATTR_READONLY & mode)) + aino->amigaos_mode |= A_FIBF_WRITE | A_FIBF_DELETE; + aino->amigaos_mode = filesys_parse_mask (aino->amigaos_mode); + return 1; +} + +int fsdb_set_file_attrs (a_inode *aino) +{ + struct stat statbuf; + int mode=0, tmpmask; + + tmpmask = filesys_parse_mask (aino->amigaos_mode); + + if (stat (aino->nname, &statbuf) == -1) + return ERROR_OBJECT_NOT_AROUND; + + /* Unix dirs behave differently than AmigaOS ones. */ + /* windows dirs go where no dir has gone before... */ + if (! aino->dir) { + if ((tmpmask & (A_FIBF_WRITE | A_FIBF_DELETE)) == 0) + mode |= ATTR_READONLY; + if (tmpmask & A_FIBF_ARCHIVE) + mode |= ATTR_ARCHIVE; + //else + //mode &= ~ATTR_ARCHIVE; + + FAT_setAttr(aino->nname, mode); + } + + aino->dirty = 1; + return 0; +} + +/* Return nonzero if we can represent the amigaos_mode of AINO within the + * native FS. Return zero if that is not possible. */ +int fsdb_mode_representable_p (const a_inode *aino) +{ + int mask = aino->amigaos_mode; + int m1; + + if (aino->dir) + return aino->amigaos_mode == 0; + + /* P or S set, or E or R clear, means we can't handle it. */ + if (mask & (A_FIBF_SCRIPT | A_FIBF_PURE | A_FIBF_EXECUTE | A_FIBF_READ)) + return 0; + m1 = A_FIBF_DELETE | A_FIBF_WRITE; + /* If it's rwed, we are OK... */ + if ((mask & m1) == 0) //Both delete and write protected + return 1; + /* We can also represent r-e-, by setting the host's readonly flag. */ + if ((mask & m1) == m1) //Neither delete nor write protected + return 1; + return 0; +} + +char *fsdb_create_unique_nname (a_inode *base, const char *suggestion) +{ + char *c; + char tmp[256] = "__uae___"; + int i; + + strncat (tmp, suggestion, 240); + + /* replace the evil ones... */ + for (i=0; i < NUM_EVILCHARS; i++) + while ((c = strchr (tmp, evilchars[i])) != 0) + *c = '_'; + + while ((c = strchr (tmp, '.')) != 0) + *c = '_'; + while ((c = strchr (tmp, ' ')) != 0) + *c = '_'; + + for (;;) { + char *p = build_nname (base->nname, tmp); + struct stat st; + + if (stat(p, &st) < 0) { + write_log ("unique name: %s\n", p); + return p; + } + free (p); + + /* tmpnam isn't reentrant and I don't really want to hack configure + * right now to see whether tmpnam_r is available... */ + for (i = 0; i < 8; i++) { + tmp[i+8] = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[rand () % 63]; + } + } +} + +int dos_errno (void) +{ + int e = errno; + + switch (e) { + case ENOMEM: return ERROR_NO_FREE_STORE; + case EEXIST: return ERROR_OBJECT_EXISTS; + case EACCES: return ERROR_WRITE_PROTECTED; + case ENOENT: return ERROR_OBJECT_NOT_AROUND; + case ENOTDIR: return ERROR_OBJECT_WRONG_TYPE; + case ENOSPC: return ERROR_DISK_IS_FULL; + case EBUSY: return ERROR_OBJECT_IN_USE; + case EISDIR: return ERROR_OBJECT_WRONG_TYPE; +#if defined(ETXTBSY) + case ETXTBSY: return ERROR_OBJECT_IN_USE; +#endif +#if defined(EROFS) + case EROFS: return ERROR_DISK_WRITE_PROTECTED; +#endif +#if defined(ENOTEMPTY) +#if ENOTEMPTY != EEXIST + case ENOTEMPTY: return ERROR_DIRECTORY_NOT_EMPTY; +#endif +#endif + default: + TRACE (("FSDB: Unimplemented error: %s\n", strerror (e))); + return ERROR_NOT_IMPLEMENTED; + } +} +#endif diff --git a/src/od-wii/hrtimer.h b/src/od-wii/hrtimer.h new file mode 100644 index 0000000..c7d54d2 --- /dev/null +++ b/src/od-wii/hrtimer.h @@ -0,0 +1,38 @@ +/* + * E-UAE - The portable Amiga Emulator + * + * Generic high-resolution timer support. + * + * (c) 2005 Richard Drummond + */ + +#ifndef EUAE_OSDEP_HRTIMER_H +#define EUAE_OSDEP_HRTIMER_H + +#include +#include + +#include "machdep/rpt.h" + +STATIC_INLINE frame_time_t osdep_gethrtime (void) +{ +#if HAVE_GETTIMEOFDAY + struct timeval t; + gettimeofday (&t, 0); + return t.tv_sec * 1000000 + t.tv_usec; +#else +#error "No timer support available!" +#endif +} + +STATIC_INLINE frame_time_t osdep_gethrtimebase (void) +{ +#if HAVE_GETTIMEOFDAY + return 1000000; +#endif +} + +STATIC_INLINE void osdep_inithrtimer (void) +{ +} +#endif diff --git a/src/od-wii/main.c b/src/od-wii/main.c new file mode 100644 index 0000000..7ea6020 --- /dev/null +++ b/src/od-wii/main.c @@ -0,0 +1,66 @@ +/* + * UAE - The Un*x Amiga Emulator + * + * Copyright 2004 Richard Drummond + * + * Start-up and support functions used by Linux/Unix targets + */ + +#include "sysconfig.h" +#include "sysdeps.h" + +#include "options.h" +#include "uae.h" +#include "debug.h" + +/* + * Handle break signal + */ +#include + +#ifdef __cplusplus +static RETSIGTYPE sigbrkhandler(...) +#else +static RETSIGTYPE sigbrkhandler (int foo) +#endif +{ +#ifdef DEBUGGER + activate_debugger (); +#endif + +#if !defined(__unix) || defined(__NeXT__) + signal (SIGINT, sigbrkhandler); +#endif +} + +void setup_brkhandler (void) +{ +#if defined(__unix) && !defined(__NeXT__) + struct sigaction sa; + sa.sa_handler = sigbrkhandler; + sa.sa_flags = 0; +#ifdef SA_RESTART + sa.sa_flags = SA_RESTART; +#endif + sigemptyset (&sa.sa_mask); + sigaction (SIGINT, &sa, NULL); +#else + signal (SIGINT, sigbrkhandler); +#endif +} + +/* + * Handle target-specific cfgfile options + */ +void target_save_options (FILE *f, const struct uae_prefs *p) +{ +} + +int target_parse_option (struct uae_prefs *p, const char *option, const char *value) +{ + return 0; +} + +void target_default_options (struct uae_prefs *p) +{ +} diff --git a/src/od-wii/memory.c b/src/od-wii/memory.c new file mode 100644 index 0000000..7524749 --- /dev/null +++ b/src/od-wii/memory.c @@ -0,0 +1,45 @@ + /* + * UAE - The Un*x Amiga Emulator + * + * OS-specific memory support functions + * + * Copyright 2004 Richard Drummond + */ + +#include "sysconfig.h" +#include "sysdeps.h" + +#include "include/memory.h" + +#ifdef JIT + +#include + +/* + * Allocate executable memory for JIT cache + */ +void *cache_alloc (int size) +{ + void *cache; + + size = size < getpagesize() ? getpagesize() : size; + + if ((cache = valloc (size))) + mprotect (cache, size, PROT_READ|PROT_WRITE|PROT_EXEC); + + return cache; +} + +void cache_free (void *cache) +{ + free (cache); +} + +#ifdef NATMEM_OFFSET +void init_shm (void) +{ + canbang = 1; +} +#endif + +#endif diff --git a/src/od-wii/memory.h b/src/od-wii/memory.h new file mode 100644 index 0000000..5d21b6c --- /dev/null +++ b/src/od-wii/memory.h @@ -0,0 +1,11 @@ + /* + * UAE - The Un*x Amiga Emulator + * + * See if this OS has mmap or equivalent + * + * Copyright 1996 Bernd Schmidt + */ + +#undef USE_MAPPED_MEMORY +#undef CAN_MAP_MEMORY + diff --git a/src/savestate.c b/src/savestate.c index 0e93474..c60a0a8 100644 --- a/src/savestate.c +++ b/src/savestate.c @@ -544,7 +544,7 @@ void save_state (const char *filename, const char *description) #ifdef FILESYS if (nr_units (currprefs.mountinfo)) { - gui_message ("WARNING: State saves do not support hard drive emulation"); + gui_message ("WARNING: State saves do not support HD emulation"); } #endif