diff options
Diffstat (limited to 'src/internal')
-rw-r--r-- | src/internal/ptycon_nolibc_impl.h | 1 | ||||
-rw-r--r-- | src/internal/ptycon_ntaio_impl.c | 69 |
2 files changed, 70 insertions, 0 deletions
diff --git a/src/internal/ptycon_nolibc_impl.h b/src/internal/ptycon_nolibc_impl.h index 7050c03..0359205 100644 --- a/src/internal/ptycon_nolibc_impl.h +++ b/src/internal/ptycon_nolibc_impl.h @@ -29,6 +29,7 @@ typedef struct ptyc_file FILE; int ptyc_isatty(int fildes); +int ptyc_write(int, const void *, size_t); int ptyc_fileno(void * any); int ptyc_sprintf(char * str, const char * fmt, ...); diff --git a/src/internal/ptycon_ntaio_impl.c b/src/internal/ptycon_ntaio_impl.c index 7055aa4..b0ba88b 100644 --- a/src/internal/ptycon_ntaio_impl.c +++ b/src/internal/ptycon_ntaio_impl.c @@ -5,6 +5,7 @@ /*********************************************************/ #include <ntapi/ntapi.h> +#include <stdio.h> extern const ntapi_vtbl * ptyc_ntapi; @@ -161,3 +162,71 @@ int ptyc_fileno(void * any) { return (int)(intptr_t)any; } + +int ptyc_write(int fd, const void * buf, size_t size) +{ + int32_t status; + nt_runtime_data * rtdata; + ntapi_zw_write_file * iofn; + void * hio; + void * hevent; + int fdtype; + nt_iosb iosb; + + /* size */ + if (size >= 0x80000000) + return NT_STATUS_INVALID_PARAMETER; + + /* rtdata */ + if (ptyc_ntapi->tt_get_runtime_data(&rtdata,0)) + return NT_STATUS_REINITIALIZATION_NEEDED; + + /* hio, io type */ + if (fd == STDIN_FILENO) { + hio = rtdata->hstdin; + fdtype = rtdata->stdin_type; + + } else if (fd == STDOUT_FILENO) { + hio = rtdata->hstdout; + fdtype = rtdata->stdout_type; + + } else if (fd == STDERR_FILENO) { + hio = rtdata->hstderr; + fdtype = rtdata->stderr_type; + } else { + return NT_STATUS_INVALID_PARAMETER; + } + + if (!hio) + return NT_STATUS_INVALID_HANDLE; + + /* iofn */ + iofn = (fdtype == NT_FILE_TYPE_PTY) + ? (ntapi_zw_write_file *)ptyc_ntapi->pty_write + : ptyc_ntapi->zw_write_file; + + /* hevent */ + if ((status = ptyc_ntapi->tt_create_private_event( + &hevent, + NT_NOTIFICATION_EVENT, + NT_EVENT_NOT_SIGNALED))) + return status; + + /* iowrite */ + status = iofn( + hio,hevent, + 0,0,&iosb, + (void *)buf,size, + 0,0); + + /* wait */ + if (status == NT_STATUS_PENDING) + status = ptyc_ntapi->zw_wait_for_single_object( + hevent,0,0); + + /* hevent */ + ptyc_ntapi->zw_close(hevent); + + /* ret */ + return status ? status : iosb.status; +} |