summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/internal/ptycon_nolibc_impl.h1
-rw-r--r--src/internal/ptycon_ntaio_impl.c69
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;
+}