diff --git a/src/fdlib.c b/src/fdlib.c
index 9f5a3ac174747a4ef612ef37a83b1a22e55a0c3f..7abf10ae23fc8b31118036b3ccf2b378d9595c39 100644
--- a/src/fdlib.c
+++ b/src/fdlib.c
@@ -2643,24 +2643,81 @@ PMOD_EXPORT int debug_fd_select(int fds, FD_SET *a, FD_SET *b, FD_SET *c, struct
 PMOD_EXPORT int debug_fd_ioctl(FD fd, int cmd, void *data)
 {
   int ret;
-  SOCKET s;
 
   FDDEBUG(fprintf(stderr, "fd_ioctl(%d, %d, %p)...\n", fd, cmd, data));
 
-  if (fd_to_socket(fd, &s, 0) < 0) return -1;
+  if (((cmd >> 8) & 0xff) == 'T') {
+    /* TTY ioctl */
+    HANDLE h;
+    int type;
+    struct my_pty *pty;
+    HCON conpty;
+    struct winsize *win = data;
+    COORD coord;
+
+    if (fd_to_handle(fd, &type, &h, 0) < 0) return -1;
+
+    if ((type != FD_PTY) || !Pike_NT_ResizePseudoConsole) {
+      release_fd(fd);
+      errno = ENOTTY;
+      return -1;
+    }
+    pty = (struct my_pty *)h;
+
+    if (!(conpty = pty->conpty)) {
+      /* Slave, try looking at the master. */
+      if (!(pty = pty->other) || !(conpty = pty->conpty)) {
+	release_fd(fd);
+	errno = ENOTTY;
+	return -1;
+      }
+    }
+
+    switch(cmd) {
+    case TIOCSWINSZ:
+      coord.X = win->ws_col;
+      coord.Y = win->ws_row;
+      ret = Pike_NT_ResizePseudoConsole(conpty, coord);
+      if (ret == S_OK) {
+	pty->winsize = coord;
+      }
+      break;
+
+    case TIOCGWINSZ:
+      win->ws_col = pty->winsize.X;
+      win->ws_row = pty->winsize.Y;
+      ret = S_OK;
+      break;
+
+    default:
+      release_fd(fd);
+      errno = EINVAL;
+      return -1;
+    }
+  } else {
+    SOCKET s;
+
+    if (fd_to_socket(fd, &s, 0) < 0) {
+      return -1;
+    }
 
-  FDDEBUG(fprintf(stderr,"ioctl(%d (%ld,%d,%p)\n",
-		  fd, (long)(ptrdiff_t)s, cmd, data));
+    FDDEBUG(fprintf(stderr,"ioctl(%d (%ld,%d,%p)\n",
+		    fd, (long)(ptrdiff_t)s, cmd, data));
 
-  ret = ioctlsocket(s, cmd, data);
+    ret = ioctlsocket(s, cmd, data);
 
-  FDDEBUG(fprintf(stderr,"ioctlsocket returned %ld (%d)\n",ret,errno));
+    FDDEBUG(fprintf(stderr,"ioctlsocket returned %ld (%d)\n",ret,errno));
+  }
 
   release_fd(fd);
 
-  if(ret==SOCKET_ERROR)
+  if(ret != S_OK)
   {
-    set_errno_from_win32_error (WSAGetLastError());
+    if (ret == SOCKET_ERROR) {
+      set_errno_from_win32_error (WSAGetLastError());
+    } else {
+      set_errno_from_win32_error (GetLastError());
+    }
     return -1;
   }
 
@@ -2847,7 +2904,6 @@ PMOD_EXPORT int debug_fd_openpty(int *master, int *slave,
   struct my_pty *slave_pty = NULL;
   int master_fd = -1;
   int slave_fd = -1;
-  COORD sz;
 
   if (!Pike_NT_CreatePseudoConsole) {
     errno = ENOTSUPP;
@@ -2888,15 +2944,16 @@ PMOD_EXPORT int debug_fd_openpty(int *master, int *slave,
   }
 
   /* Some reasonable defaults. */
-  sz.X = 80;
-  sz.Y = 25;
+  master_pty->winsize.X = 80;
+  master_pty->winsize.Y = 25;
 
   if (winp) {
-    sz.X = winp->ws_col;
-    sz.Y = winp->ws_row;
+    master_pty->winsize.X = winp->ws_col;
+    master_pty->winsize.Y = winp->ws_row;
   }
 
-  if (FAILED(Pike_NT_CreatePseudoConsole(sz, slave_pty->read_pipe,
+  if (FAILED(Pike_NT_CreatePseudoConsole(master_pty->winsize,
+					 slave_pty->read_pipe,
 					 slave_pty->write_pipe,
 					 0, &master_pty->conpty))) {
     goto win32_fail;
diff --git a/src/fdlib.h b/src/fdlib.h
index b632ff734f1f757e776474f7874941eac2b54bd1..5915219b8edba1b55b2a10e0e889a6cf0ec8592a 100644
--- a/src/fdlib.h
+++ b/src/fdlib.h
@@ -116,6 +116,11 @@ struct winsize {
 };
 #endif
 
+#ifndef TIOCGWINSZ
+#define TIOCGWINSZ	_IOR('T', 0x13, struct winsize)
+#define TIOCSWINSZ	_IOW('T', 0x14, struct winsize)
+#endif
+
 #define SOCKFUN1(NAME,T1) PMOD_EXPORT int PIKE_CONCAT(debug_fd_,NAME) (FD,T1);
 #define SOCKFUN2(NAME,T1,T2) PMOD_EXPORT int PIKE_CONCAT(debug_fd_,NAME) (FD,T1,T2);
 #define SOCKFUN3(NAME,T1,T2,T3) PMOD_EXPORT int PIKE_CONCAT(debug_fd_,NAME) (FD,T1,T2,T3);
@@ -285,6 +290,7 @@ struct my_pty
   struct pid_status *clients; /* List of client processes. */
   HANDLE read_pipe;	/* Pipe that supports read(). */
   HANDLE write_pipe;	/* Pipe that supports write(). */
+  COORD winsize;	/* There's no API to fetch the window size. */
 };
 
 typedef struct my_fd_set_s my_fd_set;