diff --git a/ports/include/noux_session/sysio.h b/ports/include/noux_session/sysio.h index 1d3386fd0..a3d126ab0 100644 --- a/ports/include/noux_session/sysio.h +++ b/ports/include/noux_session/sysio.h @@ -92,7 +92,10 @@ namespace Noux { */ struct Ioctl_in { - enum Opcode { OP_UNDEFINED, OP_TIOCGWINSZ, OP_FIONBIO }; + enum Opcode { OP_UNDEFINED, OP_TIOCGWINSZ, OP_TIOCSETAF, + OP_TIOCSETAW, OP_FIONBIO }; + + enum Val { VAL_NULL, VAL_ECHO, VAL_ECHONL }; Opcode request; int argp; @@ -312,6 +315,8 @@ namespace Noux { enum Write_error { WRITE_ERR_AGAIN, WRITE_ERR_WOULD_BLOCK, WRITE_ERR_INVALID, WRITE_ERR_IO }; + enum Ioctl_error { IOCTL_ERR_INVALID, IOCTL_ERR_NOTTY }; + /** * Socket related errors */ @@ -363,6 +368,7 @@ namespace Noux { Symlink_error symlink; Read_error read; Write_error write; + Ioctl_error ioctl; Accept_error accept; Bind_error bind; Connect_error connect; diff --git a/ports/src/lib/libc_noux/plugin.cc b/ports/src/lib/libc_noux/plugin.cc index 39eb88c7f..70993c078 100644 --- a/ports/src/lib/libc_noux/plugin.cc +++ b/ports/src/lib/libc_noux/plugin.cc @@ -951,6 +951,34 @@ namespace { break; + case TIOCSETAF: + { + sysio()->ioctl_in.request = Noux::Sysio::Ioctl_in::OP_TIOCSETAF; + + ::termios *termios = (::termios *)argp; + + /** + * For now only enabling/disabling of ECHO is supported + */ + if (termios->c_lflag & (ECHO | ECHONL)) { + sysio()->ioctl_in.argp = (Noux::Sysio::Ioctl_in::VAL_ECHO | + Noux::Sysio::Ioctl_in::VAL_ECHONL); + } + else { + sysio()->ioctl_in.argp = Noux::Sysio::Ioctl_in::VAL_NULL; + } + + break; + } + + case TIOCSETAW: + { + sysio()->ioctl_in.request = Noux::Sysio::Ioctl_in::OP_TIOCSETAW; + sysio()->ioctl_in.argp = argp ? *(int*)argp : 0; + + break; + } + case FIONBIO: { if (verbose) @@ -958,6 +986,8 @@ namespace { sysio()->ioctl_in.request = Noux::Sysio::Ioctl_in::OP_FIONBIO; sysio()->ioctl_in.argp = argp ? *(int*)argp : 0; + + break; } default: @@ -973,8 +1003,12 @@ namespace { /* perform syscall */ if (!noux()->syscall(Noux::Session::SYSCALL_IOCTL)) { - PERR("ioctl error"); - /* XXX set errno */ + switch (sysio()->error.ioctl) { + case Noux::Sysio::IOCTL_ERR_INVALID: errno = EINVAL; break; + case Noux::Sysio::IOCTL_ERR_NOTTY: errno = ENOTTY; break; + default: errno = 0; break; + } + return -1; } @@ -990,6 +1024,9 @@ namespace { winsize->ws_col = sysio()->ioctl_out.tiocgwinsz.columns; return 0; } + case TIOCSETAF: + case TIOCSETAW: + return 0; case FIONBIO: return 0;