-// vim:shiftwidth=2:expandtab
+/*
+ * GINGE - GINGE Is Not Gp2x Emulator
+ * (C) notaz, 2010-2011
+ *
+ * This work is licensed under the MAME license, see COPYING file for details.
+ */
#include <stdio.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <termios.h>
+#include <errno.h>
#include "realfuncs.h"
#include "header.h"
{ "/dev/fb1", FAKEDEV_FB1 },
{ "/dev/fb/1", FAKEDEV_FB1 },
{ "/dev/mmuhack", FAKEDEV_MMUHACK },
- { "/dev/tty", -1 }, // XXX hmh..
+ { "/dev/tty", FAKEDEV_TTY0 },
{ "/dev/tty0", FAKEDEV_TTY0 },
+#ifdef PND
+ { "/dev/input/event*", -1 }, // hide for now, may cause dupe events
+#endif
};
static int w_open(const char *pathname, int flags, mode_t mode)
int i, ret;
for (i = 0; i < ARRAY_SIZE(takeover_devs); i++) {
- if (strcmp(pathname, takeover_devs[i].name) == 0) {
+ const char *p, *oname;
+ int len;
+
+ oname = takeover_devs[i].name;
+ p = strchr(oname, '*');
+ if (p != NULL)
+ len = p - oname;
+ else
+ len = strlen(oname) + 1;
+
+ if (strncmp(pathname, oname, len) == 0) {
ret = takeover_devs[i].fd;
break;
}
if (ret >= 0) {
for (i = 0; emu_interesting_fds[i].name != NULL; i++) {
- if (strcmp(pathname, emu_interesting_fds[i].name) == 0) {
- emu_interesting_fds[i].fd = ret;
+ struct dev_fd_t *eifd = &emu_interesting_fds[i];
+ if (strcmp(pathname, eifd->name) == 0) {
+ eifd->fd = ret;
+ if (eifd->open_cb != NULL)
+ eifd->open_cb(ret);
break;
}
}
}
#define w_mmap2 w_mmap
+static int w_munmap(void *addr, size_t length)
+{
+ int ret;
+ ret = emu_do_munmap(addr, length);
+ if (ret == -EAGAIN)
+ ret = munmap(addr, length);
+
+ if (((long)&ret & 0xf0000000) == 0xb0000000)
+ strace("munmap(%p, %x) = %d\n", addr, length, ret);
+ return ret;
+}
+
static ssize_t w_read(int fd, void *buf, size_t count)
{
ssize_t ret;
return ret;
}
+extern char **environ;
+
+static UNUSED int w_execl(const char *path, const char *arg, ...)
+{
+ // don't allow exec (for now)
+ strace("execl(%s, %s, ...) = ?\n", path, arg);
+ exit(1);
+}
+
+static UNUSED int w_execlp(const char *file, const char *arg, ...)
+{
+ strace("execlp(%s, %s, ...) = ?\n", file, arg);
+ exit(1);
+}
+
+static UNUSED int w_execle(const char *path, const char *arg, ...)
+{
+ strace("execle(%s, %s, ...) = ?\n", path, arg);
+ exit(1);
+}
+
+static UNUSED int w_execv(const char *path, char *const argv[])
+{
+ strace("execv(%s, %p) = ?\n", path, argv);
+ return emu_do_execve(path, argv, environ);
+}
+
+static UNUSED int w_execvp(const char *file, char *const argv[])
+{
+ strace("execvp(%s, %p) = ?\n", file, argv);
+ return emu_do_execve(file, argv, environ);
+}
+
+// static note: this can't safely return because of the way it's patched in
+// static note2: can't be used, execve hangs?
+static UNUSED int w_execve(const char *filename, char *const argv[],
+ char *const envp[])
+{
+ strace("execve(%s, %p, %p) = ?\n", filename, argv, envp);
+ return emu_do_execve(filename, argv, envp);
+}
+
+static int w_chdir(const char *path)
+{
+ int ret;
+ if (path != NULL && strstr(path, "/usr/gp2x") != NULL)
+ ret = 0;
+ else
+ ret = chdir(path);
+ strace("chdir(%s) = %d\n", path, ret);
+ return ret;
+}
+
#undef open
#undef fopen
#undef mmap
+#undef munmap
#undef read
#undef ioctl
#undef sigaction
#undef tcgetattr
#undef tcsetattr
#undef system
+#undef execl
+#undef execlp
+#undef execle
+#undef execv
+#undef execvp
+#undef execve
+#undef chdir
#ifdef DL
-#define MAKE_WRAP_SYM(sym) \
+#define MAKE_WRAP_SYM_N(sym) \
/* alias wrap symbols to real names */ \
- typeof(sym) sym __attribute__((alias("w_" #sym))); \
+ typeof(sym) sym __attribute__((alias("w_" #sym)))
+
+#define MAKE_WRAP_SYM(sym) \
+ MAKE_WRAP_SYM_N(sym); \
/* wrapper to real functions, to be set up on load */ \
static typeof(sym) *p_real_##sym
+// note: update symver too
MAKE_WRAP_SYM(open);
MAKE_WRAP_SYM(fopen);
MAKE_WRAP_SYM(mmap);
+MAKE_WRAP_SYM(munmap);
MAKE_WRAP_SYM(read);
MAKE_WRAP_SYM(ioctl);
MAKE_WRAP_SYM(sigaction);
MAKE_WRAP_SYM(tcgetattr);
MAKE_WRAP_SYM(tcsetattr);
MAKE_WRAP_SYM(system);
+MAKE_WRAP_SYM_N(execl);
+MAKE_WRAP_SYM_N(execlp);
+MAKE_WRAP_SYM_N(execle);
+MAKE_WRAP_SYM_N(execv);
+MAKE_WRAP_SYM_N(execvp);
+MAKE_WRAP_SYM(execve);
+MAKE_WRAP_SYM(chdir);
typeof(mmap) mmap2 __attribute__((alias("w_mmap")));
#define REAL_FUNC_NP(name) \
REAL_FUNC_NP(open),
REAL_FUNC_NP(fopen),
REAL_FUNC_NP(mmap),
+ REAL_FUNC_NP(munmap),
REAL_FUNC_NP(read),
REAL_FUNC_NP(ioctl),
REAL_FUNC_NP(sigaction),
REAL_FUNC_NP(tcgetattr),
REAL_FUNC_NP(tcsetattr),
REAL_FUNC_NP(system),
+ // exec* - skipped
+ REAL_FUNC_NP(execve),
+ REAL_FUNC_NP(chdir),
};
#define open p_real_open
#define fopen p_real_fopen
#define mmap p_real_mmap
+#define munmap p_real_munmap
#define read p_real_read
#define ioctl p_real_ioctl
#define sigaction p_real_sigaction
#define tcgetattr p_real_tcgetattr
#define tcsetattr p_real_tcsetattr
#define system p_real_system
+#define execve p_real_execve
+#define chdir p_real_chdir
#undef MAKE_WRAP_SYM
#undef REAL_FUNC_NP
#endif
// just call real funcs for static, pointer for dynamic
-int real_open(const char *pathname, int flags, mode_t mode)
+int real_open(const char *pathname, int flags, ...)
{
+ va_list ap;
+ mode_t mode;
+
+ va_start(ap, flags);
+ mode = va_arg(ap, mode_t);
+ va_end(ap);
return open(pathname, flags, mode);
}
return mmap(addr, length, prot, flags, fd, offset);
}
+int real_munmap(void *addr, size_t length)
+{
+ return munmap(addr, length);
+}
+
int real_read(int fd, void *buf, size_t count)
{
return read(fd, buf, count);
{
return system(command);
}
+
+// real_exec* is missing intentionally - we don't need them
+
+int real_execve(const char *filename, char *const argv[],
+ char *const envp[])
+{
+ return execve(filename, argv, envp);
+}
+
+int real_chdir(const char *path)
+{
+ return chdir(path);
+}
+
+// vim:shiftwidth=2:expandtab