Skip to content

ixemul programs: unknown DOS packets reply as success, and the path actions are missing #196

Closed

Description

@codewiz

Follow-up to #186: with #191, #187 and the GetDeviceProc fix in the PR linking here, ixemul.library programs reach handle_fs_packet for every path operation. Two things are left.

1. Unknown actions look successful

For an action it does not implement, handle_fs_packet replies Res1 = RESULT_ERROR (0xFFFFFFFF) with Res2 = ERROR_ACTION_NOT_KNOWN. For the boolean actions, 0xFFFFFFFF is DOSTRUE, so the caller sees success. An ixemul mkdir("W:x") sends ACTION_CREATE_DIR, gets Res1 = -1, returns 0, and no directory exists; the chmod() that follows (ACTION_SET_PROTECT) "succeeds" the same way:

exec.library(-366) -> PutMsg [DosPacket action 22 (fh_Arg1 0x20a6d) -> Res1 0xffffffff]
exec.library(-366) -> PutMsg [DosPacket action 21 (fh_Arg1 0x0) -> Res1 0xffffffff]
mkdir(W:x) = 0 errno 2

A handler answers an action it does not know with Res1 = DOSFALSE (0) and Res2 = ERROR_ACTION_NOT_KNOWN; that reply would make these fail visibly.

2. Actions ixemul sends that are not implemented

From ixemul's library/*.c, besides the ones #191 added (ACTION_READ, WRITE, SEEK, END, LOCATE_OBJECT, FINDINPUT/FINDOUTPUT/FINDUPDATE, EXAMINE_FH, READ_LINK):

  • ACTION_CREATE_DIR (mkdir)
  • ACTION_DELETE_OBJECT (unlink, rmdir)
  • ACTION_RENAME_OBJECT (rename)
  • ACTION_SET_PROTECT (chmod, also after mkdir and open(O_CREAT))
  • ACTION_SET_DATE (utime)
  • ACTION_SET_OWNER (chown, also after mkdir)
  • ACTION_SET_FILE_SIZE (ftruncate)
  • ACTION_DISK_INFO (statfs)
  • ACTION_WAIT_CHAR (select() on a console)
  • ACTION_MAKE_LINK (link, symlink)

Test program

fileio.c below checks mkdir, open/create, read/write/lseek, fstat, ftruncate, O_APPEND, O_EXCL, ENOENT, rename, opendir/readdir, unlink and rmdir, printing one line per failed check; the exit code is the number of failures. Built like #186's hello (gg/ from Aminet dev/lib/ixemul-80.1-m68k.lha, ranlib run on gg/lib/libc.a):

m68k-amigaos-gcc -m68020 -mcrt=ixemul -O2 -isystem gg/include -B gg/lib/ fileio.c gg/lib/libc.a -o fileio-68020
volamos --cpu 68020 --libs-dir libs020 -V W:/tmp/vol fileio-68020 W:

It currently reports 20 of 21 checks failed. I have not run it on AmigaOS yet, so a check that fails there too is a bug in the test, not in volamos.

fileio.c
/* ixemul file I/O through its own DOS packets: open/read/write/seek,
   stat/fstat, rename, unlink, mkdir/rmdir, opendir/readdir, ftruncate.
   Prints one line per failed check; exit code is the number of failures.  */
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

static int failures;

static void check(int ok, const char *what)
{
  if (!ok)
    {
      printf("FAIL: %s (errno %d)\n", what, errno);
      failures++;
    }
}

int main(int argc, char **argv)
{
  const char *dir = argc > 1 ? argv[1] : "/t";
  char d[256], f[256], g[256], buf[64];
  struct stat st;
  DIR *dp;
  struct dirent *e;
  int fd, seen = 0;

  snprintf(d, sizeof d, "%s/ixfileio", dir);
  snprintf(f, sizeof f, "%s/a", d);
  snprintf(g, sizeof g, "%s/b", d);

  rmdir(d);
  check(mkdir(d, 0755) == 0, "mkdir");
  check(stat(d, &st) == 0 && S_ISDIR(st.st_mode), "stat dir");

  fd = open(f, O_RDWR | O_CREAT | O_TRUNC, 0644);
  check(fd >= 0, "open create");
  check(write(fd, "0123456789", 10) == 10, "write");
  check(fstat(fd, &st) == 0 && S_ISREG(st.st_mode) && st.st_size == 10, "fstat size");
  check(lseek(fd, 3, SEEK_SET) == 3, "lseek");
  check(read(fd, buf, 4) == 4 && memcmp(buf, "3456", 4) == 0, "read after lseek");
  check(lseek(fd, 0, SEEK_END) == 10, "lseek end");
  check(ftruncate(fd, 5) == 0, "ftruncate");
  check(fstat(fd, &st) == 0 && st.st_size == 5, "fstat after ftruncate");
  check(close(fd) == 0, "close");

  fd = open(f, O_WRONLY | O_APPEND);
  check(fd >= 0 && write(fd, "xy", 2) == 2, "O_APPEND write");
  close(fd);
  fd = open(f, O_RDONLY);
  memset(buf, 0, sizeof buf);
  check(fd >= 0 && read(fd, buf, sizeof buf) == 7 && strcmp(buf, "01234xy") == 0,
        "read back");
  close(fd);

  check(open(f, O_WRONLY | O_CREAT | O_EXCL, 0644) == -1 && errno == EEXIST, "O_EXCL");
  check(open(g, O_RDONLY) == -1 && errno == ENOENT, "ENOENT");
  check(rename(f, g) == 0, "rename");
  check(stat(f, &st) == -1 && stat(g, &st) == 0 && st.st_size == 7, "stat after rename");

  dp = opendir(d);
  check(dp != NULL, "opendir");
  if (dp)
    {
      while ((e = readdir(dp)) != NULL)
        if (strcmp(e->d_name, "b") == 0)
          seen++;
      closedir(dp);
    }
  check(seen == 1, "readdir");

  check(unlink(g) == 0, "unlink");
  check(rmdir(d) == 0, "rmdir");
  printf("fileio: %d failures\n", failures);
  return failures;
}

This is for the gcc toolchain's ixemul runtime tests (AmigaPorts/m68k-amigaos-gcc#184).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions