summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEero Tamminen <oak@helsinkinet.fi>2020-10-24 21:32:51 (GMT)
committerEero Tamminen <oak@helsinkinet.fi>2020-10-24 21:41:00 (GMT)
commitcde30d816e0b69f56445bce7be6a7c1609e5c4ea (patch)
treef012eb29c4e12aa14912e5357a37b6ee367115b1
parentd20479d71d491b9e4317f62b4f33a96d0ef535b3 (diff)
downloadhatari-cde30d816e0b69f56445bce7be6a7c1609e5c4ea.zip
hatari-cde30d816e0b69f56445bce7be6a7c1609e5c4ea.tar.gz
Improve PopulateDTA()
- Replace magic return values with defines - Fix non-existing file (e.g. broken symlink) breaking showing of emulated directory contents Reported by Vincent Riviere.
-rw-r--r--doc/release-notes.txt2
-rw-r--r--src/gemdos.c27
2 files changed, 20 insertions, 9 deletions
diff --git a/doc/release-notes.txt b/doc/release-notes.txt
index 9304704..9b989ac 100644
--- a/doc/release-notes.txt
+++ b/doc/release-notes.txt
@@ -93,6 +93,8 @@ Emulator:
demand and give warning if its entries need to be re-cycled
(= cache max size is reached)
- Invalid DTA in Fsnext() return -ENMFIL, like TOS does
+ - Fix: skip non-existing host files on FSnext() instead
+ of returning an error (latter broke directory listings)
- Fix: Dsetpath/Dgetpath empty path handling
- Hatari graphics support:
- Low/med-rez line doubling uses less CPU and doubled lines in
diff --git a/src/gemdos.c b/src/gemdos.c
index a22bf46..02085ab 100644
--- a/src/gemdos.c
+++ b/src/gemdos.c
@@ -101,6 +101,13 @@ typedef struct {
char dta_name[TOS_NAMELEN];
} DTA;
+/* PopulateDTA() return values */
+typedef enum {
+ DTA_ERR = -1,
+ DTA_OK = 0,
+ DTA_SKIP = 1
+} dta_ret_t;
+
#define DTA_MAGIC_NUMBER 0x12983476
#define DTA_CACHE_INC 256 /* DTA cache initial and increment size (grows on demand) */
#define DTA_CACHE_MAX 4096 /* max DTA cache size (multiple of DTA_CACHE_INC) */
@@ -289,9 +296,9 @@ static Uint8 GemDOS_ConvertAttribute(mode_t mode)
/*-----------------------------------------------------------------------*/
/**
* Populate the DTA buffer with file info.
- * @return 0 if entry is ok, 1 if entry should be skipped, < 0 for errors.
+ * @return DTA_OK if entry is ok, DTA_SKIP if it should be skipped, DTA_ERR on errors
*/
-static int PopulateDTA(char *path, struct dirent *file, DTA *pDTA, Uint32 DTA_Gemdos)
+static dta_ret_t PopulateDTA(char *path, struct dirent *file, DTA *pDTA, Uint32 DTA_Gemdos)
{
/* TODO: host file path can be longer than MAX_GEMDOS_PATH */
char tempstr[MAX_GEMDOS_PATH];
@@ -303,23 +310,25 @@ static int PopulateDTA(char *path, struct dirent *file, DTA *pDTA, Uint32 DTA_Ge
path, PATHSEP, file->d_name) >= (int)sizeof(tempstr))
{
Log_Printf(LOG_ERROR, "PopulateDTA: path is too long.\n");
- return -1;
+ return DTA_ERR;
}
if (stat(tempstr, &filestat) != 0)
{
+ /* skip file if it doesn't exist, otherwise return an error */
+ dta_ret_t ret = (errno == ENOENT ? DTA_SKIP : DTA_ERR);
perror(tempstr);
- return -1; /* return on error */
+ return ret;
}
if (!pDTA)
- return -2; /* no DTA pointer set */
+ return DTA_ERR; /* no DTA pointer set */
/* Check file attributes (check is done according to the Profibuch) */
nFileAttr = GemDOS_ConvertAttribute(filestat.st_mode);
nAttrMask = nAttrSFirst|GEMDOS_FILE_ATTRIB_WRITECLOSE|GEMDOS_FILE_ATTRIB_READONLY;
if (nFileAttr != 0 && !(nAttrMask & nFileAttr))
- return 1;
+ return DTA_SKIP;
GemDOS_DateTime2Tos(filestat.st_mtime, &DateTime, tempstr);
@@ -337,7 +346,7 @@ static int PopulateDTA(char *path, struct dirent *file, DTA *pDTA, Uint32 DTA_Ge
do_put_mem_word(pDTA->dta_date, DateTime.dateword);
pDTA->dta_attrib = nFileAttr;
- return 0;
+ return DTA_OK;
}
@@ -2914,9 +2923,9 @@ static bool GemDOS_SNext(void)
ret = PopulateDTA(InternalDTAs[Index].path,
temp[InternalDTAs[Index].centry++],
pDTA, DTA_Gemdos);
- } while (ret == 1);
+ } while (ret == DTA_SKIP);
- if (ret < 0)
+ if (ret == DTA_ERR)
{
Log_Printf(LOG_WARN, "GEMDOS Fsnext(): Error setting DTA\n");
Regs[REG_D0] = GEMDOS_EINTRN;