From b34182d53d9848a46364a0f94aa1320dfd08e423 Mon Sep 17 00:00:00 2001 From: TuxSH Date: Sat, 4 May 2019 21:19:15 +0200 Subject: [PATCH] gdbhio: stat structure needs to be packed --- libctru/include/3ds/gdbhio_dev.h | 4 ++-- libctru/source/gdbhio.c | 7 +++++-- libctru/source/gdbhio_dev.c | 35 +++++++++++++++++++++++++++++--- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/libctru/include/3ds/gdbhio_dev.h b/libctru/include/3ds/gdbhio_dev.h index 2dc3ca1..44fd5dc 100644 --- a/libctru/include/3ds/gdbhio_dev.h +++ b/libctru/include/3ds/gdbhio_dev.h @@ -24,7 +24,7 @@ int gdbHioDevGetStdout(void); ///< Returns a file descriptor mapping to the GDB client console's standard error stream. int gdbHioDevGetStderr(void); -///< Redirects 0 to 3 of the application's standard streams to GDB client console's. +///< Redirects 0 to 3 of the application's standard streams to GDB client console's. Returns -1, -2, or -3, resp., on failure; 0 on success. int gdbHioDevRedirectStdStreams(bool in, bool out, bool err); ///< GDB HIO POSIX function gettimeofday. @@ -34,4 +34,4 @@ int gdbHioDevGettimeofday(struct timeval *tv, void *tz); int gdbHioDevIsatty(int fd); ///< GDB HIO POSIX function system. Requires 'set remote system-call-allowed 1'. -int gdbHioDevSystem(const char *command); \ No newline at end of file +int gdbHioDevSystem(const char *command); diff --git a/libctru/source/gdbhio.c b/libctru/source/gdbhio.c index 6f85637..8796370 100644 --- a/libctru/source/gdbhio.c +++ b/libctru/source/gdbhio.c @@ -204,7 +204,8 @@ static int _gdbExportSeekFlag(int flag) } // https://sourceware.org/gdb/onlinedocs/gdb/struct-stat.html#struct-stat typedef u32 gdbhio_time_t; -struct gdbhio_stat { + +struct PACKED ALIGN(4) gdbhio_stat { u32 st_dev; /* device */ u32 st_ino; /* inode */ gdbhio_mode_t st_mode; /* protection */ @@ -261,7 +262,9 @@ static void _gdbHioImportStructTimeval(struct timeval *out, const struct gdbhio_ static void _gdbHioSetErrno(int gdbErrno, bool ctrlC) { - errno = _gdbHioImportErrno(gdbErrno); + if (gdbErrno != 0) { + errno = _gdbHioImportErrno(gdbErrno); + } g_gdbHioWasInterruptedByCtrlC = ctrlC; } diff --git a/libctru/source/gdbhio_dev.c b/libctru/source/gdbhio_dev.c index dca7fd6..3b318ab 100644 --- a/libctru/source/gdbhio_dev.c +++ b/libctru/source/gdbhio_dev.c @@ -22,6 +22,19 @@ static int _gdbHioGetFd(int fd) return *(int *)handle->fileStruct; } +static bool _gdbHioCompareFd(int fd, int fdval) +{ + __handle *handle = __get_handle(fd); + if (handle == NULL) { + return false; + } + + if(strcmp(devoptab_list[handle->device]->name, "gdbhio") != 0) { + return false; + } + return *(int *)handle->fileStruct == fdval; +} + static inline int _gdbHioGetFdFromPtr(void *fdptr) { return *(int *)fdptr; @@ -189,8 +202,24 @@ int gdbHioDevGetStderr(void) int gdbHioDevRedirectStdStreams(bool in, bool out, bool err) { int ret = 0; - if (in && (ret = dup2(gdbHioDevGetStdin(), STDIN_FILENO) < 0)) return ret; - if (out && (ret = dup2(gdbHioDevGetStdout(), STDOUT_FILENO) < 0)) return ret; - if (err && (ret = dup2(gdbHioDevGetStderr(), STDERR_FILENO) < 0)) return ret; + int fd = -1; + if (in && !_gdbHioCompareFd(STDIN_FILENO, GDBHIO_STDIN_FILENO)) { + fd = gdbHioDevGetStdin(); + ret = dup2(fd, STDIN_FILENO); + close(fd); + if (ret < 0) return -1; + } + if (out && !_gdbHioCompareFd(STDOUT_FILENO, GDBHIO_STDOUT_FILENO)) { + fd = gdbHioDevGetStdout(); + ret = dup2(fd, STDOUT_FILENO); + close(fd); + if (ret < 0) return -2; + } + if (err && !_gdbHioCompareFd(STDERR_FILENO, GDBHIO_STDERR_FILENO)) { + fd = gdbHioDevGetStderr(); + ret = dup2(fd, STDERR_FILENO); + close(fd); + if (ret < 0) return -3; + } return ret; }