diff -ru screen-4.0.2.orig/attacher.c screen-4.0.2/attacher.c
--- screen-4.0.2.orig/attacher.c	2003-09-08 23:24:48.000000000 +0900
+++ screen-4.0.2/attacher.c	2004-12-01 15:34:27.009755200 +0900
@@ -274,7 +274,7 @@
     }
   debug1("Attach decided, it is '%s'\n", SockPath);
   debug1("Attach found MasterPid == %d\n", MasterPid);
-  if (stat(SockPath, &st) == -1)
+  if (screen_stat(SockPath, &st) == -1)
     Panic(errno, "stat %s", SockPath);
   if ((st.st_mode & 0600) != 0600)
     Panic(0, "Socket is in wrong mode (%03o)", (int)st.st_mode);
@@ -420,7 +420,7 @@
   debug("AttacherFinit();\n");
   signal(SIGHUP, SIG_IGN);
   /* Check if signal comes from backend */
-  if (stat(SockPath, &statb) == 0 && (statb.st_mode & 0777) != 0600)
+  if (screen_stat(SockPath, &statb) == 0 && (statb.st_mode & 0777) != 0600)
     {
       debug("Detaching backend!\n");
       bzero((char *) &m, sizeof(m));
diff -ru screen-4.0.2.orig/config.h.in screen-4.0.2/config.h.in
--- screen-4.0.2.orig/config.h.in	2003-12-05 22:59:39.000000000 +0900
+++ screen-4.0.2/config.h.in	2004-12-01 15:34:27.009755200 +0900
@@ -184,6 +184,15 @@
 #undef RXVT_OSC
 #undef COLORS256
 
+#ifdef __CYGWIN__
+# define CYGWIN_FILEMODE
+#else
+# undef CYGWIN_FILEMODE
+#endif
+#ifdef CYGWIN_FILEMODE
+# undef MULTIUSER
+#endif
+
 
 /*
  * If you have a braille display you should define HAVE_BRAILLE.
diff -ru screen-4.0.2.orig/display.c screen-4.0.2/display.c
--- screen-4.0.2.orig/display.c	2003-12-05 22:45:41.000000000 +0900
+++ screen-4.0.2/display.c	2004-12-01 15:34:27.019769600 +0900
@@ -94,6 +94,9 @@
 /*
  * tputs needs this to calculate the padding
  */
+#if defined(__CYGWIN__) && !defined(NCURSES_STATIC)
+__declspec(dllimport)
+#endif
 #ifndef NEED_OSPEED
 extern
 #endif /* NEED_OSPEED */
diff -ru screen-4.0.2.orig/extern.h screen-4.0.2/extern.h
--- screen-4.0.2.orig/extern.h	2003-08-22 21:27:57.000000000 +0900
+++ screen-4.0.2/extern.h	2004-12-01 15:34:27.019769600 +0900
@@ -490,3 +490,19 @@
 # endif
 #endif
 extern int   EncodeChar __P((char *, int, int, int *));
+
+#ifdef CYGWIN_FILEMODE
+extern int screen_stat __P((char *, struct stat *));
+extern int screen_chmod __P((char *, mode_t));
+# ifdef NAMEDPIPE
+extern int screen_mkfifo __P((char *, mode_t));
+# endif
+extern int screen_unlink __P((char *));
+#else /* CYGWIN_FILEMODE */
+# define screen_stat(path, st) stat(path, st)
+# define screen_chmod(path, mode) chmod(path, mode)
+# ifdef NAMEDPIPE
+#  define screen_mkfifo(path, mode) mkfifo(path, mode)
+# endif
+# define screen_unlink(path) unlink(path)
+#endif /* CYGWIN_FILEMODE */
diff -ru screen-4.0.2.orig/misc.c screen-4.0.2/misc.c
--- screen-4.0.2.orig/misc.c	2003-12-05 22:45:41.000000000 +0900
+++ screen-4.0.2/misc.c	2004-12-01 15:34:27.019769600 +0900
@@ -613,7 +613,7 @@
    */
 # endif /* NEEDSETENV */
 #else /* USESETENV */
-# if defined(linux) || defined(__convex__) || (BSD >= 199103)
+# if defined(linux) || defined(__convex__) || (BSD >= 199103) || defined(__CYGWIN__)
   setenv(var, value, 1);
 # else
   setenv(var, value);
@@ -632,6 +632,9 @@
 int (*outc) __P((int));
 {
   int pad;
+#if defined(__CYGWIN__) && !defined(NCURSES_STATIC)
+__declspec(dllimport)
+#endif
   extern short ospeed;
   static short osp2pad[] = {
     0,2000,1333,909,743,666,500,333,166,83,55,41,20,10,5,2,1,1
diff -ru screen-4.0.2.orig/pty.c screen-4.0.2/pty.c
--- screen-4.0.2.orig/pty.c	2003-09-08 23:26:18.000000000 +0900
+++ screen-4.0.2/pty.c	2004-12-01 15:34:27.029784000 +0900
@@ -34,7 +34,7 @@
 #endif
 
 /* for solaris 2.1, Unixware (SVR4.2) and possibly others */
-#ifdef HAVE_SVR4_PTYS
+#if defined(HAVE_SVR4_PTYS) && !defined(__CYGWIN__)
 # include <sys/stropts.h>
 #endif
 
diff -ru screen-4.0.2.orig/resize.c screen-4.0.2/resize.c
--- screen-4.0.2.orig/resize.c	2003-09-08 23:26:31.000000000 +0900
+++ screen-4.0.2/resize.c	2004-12-01 15:35:15.158990400 +0900
@@ -993,7 +993,11 @@
 
   /* signal new size to window */
 #ifdef TIOCSWINSZ
+#ifndef __CYGWIN__ /* really needed? */
   if (wi && (p->w_width != wi || p->w_height != he) && p->w_ptyfd >= 0 && p->w_pid)
+#else
+  if (wi && (p->w_width != wi || p->w_height != he) && p->w_ptyfd >= 0)
+#endif
     {
       glwz.ws_col = wi;
       glwz.ws_row = he;
diff -ru screen-4.0.2.orig/screen.c screen-4.0.2/screen.c
--- screen-4.0.2.orig/screen.c	2003-09-08 23:26:41.000000000 +0900
+++ screen-4.0.2/screen.c	2004-12-01 15:34:27.029784000 +0900
@@ -890,7 +890,7 @@
   if (!detached && !lsflag && !cmdflag && !(dflag && !mflag && !rflag && !xflag))
     {
       /* ttyname implies isatty */
-      if (!(attach_tty = ttyname(0)))
+      if (!(attach_tty = strdup(ttyname(0))))
         Panic(0, "Must be connected to a terminal.");
       if (strlen(attach_tty) >= MAXPATHLEN)
 	Panic(0, "TtyName too long - sorry.");
@@ -1023,8 +1023,10 @@
       if ((int)st.st_uid != real_uid)
 	Panic(0, "You are not the owner of %s.", SockPath);
     }
+#ifndef CYGWIN_FILEMODE
   if ((st.st_mode & 0777) != 0700)
     Panic(0, "Directory %s must have mode 700.", SockPath);
+#endif
   if (SockMatch && index(SockMatch, '/'))
     Panic(0, "Bad session name '%s'", SockMatch);
   SockName = SockPath + strlen(SockPath) + 1;
@@ -1070,7 +1072,7 @@
       char *sty = 0;
 
       /* attach_tty is not mandatory */
-      if ((attach_tty = ttyname(0)) == 0)
+      if ((attach_tty = strdup(ttyname(0))) == 0)
         attach_tty = "";
       if (strlen(attach_tty) >= MAXPATHLEN)
 	Panic(0, "TtyName too long - sorry.");
@@ -1418,7 +1420,7 @@
       signal(SIGCHLD, SigChld);
 #endif
     }
-  if (stat(SockPath, &st) == -1)
+  if (screen_stat(SockPath, &st) == -1)
     {
       debug1("SigChldHandler: Yuck! cannot stat '%s'\n", SockPath);
       if (!RecoverSocket())
@@ -1637,7 +1639,7 @@
       xseteuid(real_uid);
       xsetegid(real_gid);
 #endif
-      (void) unlink(SockPath);
+      (void) screen_unlink(SockPath);
 #ifdef USE_SETEUID
       xseteuid(eff_uid);
       xsetegid(eff_gid);
@@ -1675,7 +1677,7 @@
       debug1("we unlink(%s)\n", SockPath);
       setgid(real_gid);
       setuid(real_uid);
-      (void) unlink(SockPath);
+      (void) screen_unlink(SockPath);
     }
   exit(e);
 }
diff -ru screen-4.0.2.orig/socket.c screen-4.0.2/socket.c
--- screen-4.0.2.orig/socket.c	2003-09-08 23:26:50.000000000 +0900
+++ screen-4.0.2/socket.c	2004-12-01 15:34:27.039798400 +0900
@@ -81,6 +81,12 @@
 # define SOCKMODE (S_IWRITE | S_IREAD | (displays ? S_IEXEC : 0))
 #endif
 
+#ifdef O_BINARY
+# define MY_O_BINARY O_BINARY
+#else
+# define MY_O_BINARY 0
+#endif
+
 
 /*
  *  Socket directory manager
@@ -181,7 +187,7 @@
       errno = 0;
       debug2("uid = %d, gid = %d\n", getuid(), getgid());
       debug2("euid = %d, egid = %d\n", geteuid(), getegid());
-      if (stat(SockPath, &st))
+      if (screen_stat(SockPath, &st))
 	{
 	  debug1("errno = %d\n", errno);
 	  continue;
@@ -260,7 +266,7 @@
 	  sent->mode = -1;
 	  if (wipeflag)
 	    {
-	      if (unlink(SockPath) == 0)
+	      if (screen_unlink(SockPath) == 0)
 		{
 		  sent->mode = -2;
 		  nwipe++;
@@ -416,7 +422,7 @@
 	  eexit(11);
 	}
       Msg(0, "There is already a screen running on %s.", Filename(SockPath));
-      if (stat(SockPath, &st) == -1)
+      if (screen_stat(SockPath, &st) == -1)
 	Panic(errno, "stat");
       if ((int)st.st_uid != real_uid)
 	Panic(0, "Unfortunatelly you are not its owner.");
@@ -427,13 +433,13 @@
       /* NOTREACHED */
     }
 # ifdef USE_SETEUID
-  (void) unlink(SockPath);
-  if (mkfifo(SockPath, SOCKMODE))
+  (void) screen_unlink(SockPath);
+  if (screen_mkfifo(SockPath, SOCKMODE))
     Panic(0, "mkfifo %s failed", SockPath);
 #  ifdef BROKEN_PIPE
-  if ((s = open(SockPath, O_RDWR | O_NONBLOCK, 0)) < 0)
+  if ((s = open(SockPath, O_RDWR | O_NONBLOCK | MY_O_BINARY, 0)) < 0)
 #  else
-  if ((s = open(SockPath, O_RDONLY | O_NONBLOCK, 0)) < 0)
+  if ((s = open(SockPath, O_RDONLY | O_NONBLOCK | MY_O_BINARY, 0)) < 0)
 #  endif
     Panic(errno, "open fifo %s", SockPath);
   xseteuid(eff_uid);
@@ -442,15 +448,15 @@
 # else /* !USE_SETEUID */
   if (UserContext() > 0)
     {
-      (void) unlink(SockPath);
-      UserReturn(mkfifo(SockPath, SOCKMODE));
+      (void) screen_unlink(SockPath);
+      UserReturn(screen_mkfifo(SockPath, SOCKMODE));
     }
   if (UserStatus())
     Panic(0, "mkfifo %s failed", SockPath);
 #  ifdef BROKEN_PIPE
-  if ((s = secopen(SockPath, O_RDWR | O_NONBLOCK, 0)) < 0)
+  if ((s = secopen(SockPath, O_RDWR | O_NONBLOCK | MY_O_BINARY, 0)) < 0)
 #  else
-  if ((s = secopen(SockPath, O_RDONLY | O_NONBLOCK, 0)) < 0)
+  if ((s = secopen(SockPath, O_RDONLY | O_NONBLOCK | MY_O_BINARY, 0)) < 0)
 #  endif
     Panic(errno, "open fifo %s", SockPath);
   return s;
@@ -464,7 +470,7 @@
 {
   register int s = 0;
 
-  if ((s = secopen(SockPath, O_WRONLY | O_NONBLOCK, 0)) >= 0)
+  if ((s = secopen(SockPath, O_WRONLY | O_NONBLOCK | MY_O_BINARY, 0)) >= 0)
     {
       (void) fcntl(s, F_SETFL, 0);
       return s;
@@ -508,7 +514,7 @@
 	  eexit(11);
 	}
       Msg(0, "There is already a screen running on %s.", Filename(SockPath));
-      if (stat(SockPath, &st) == -1)
+      if (screen_stat(SockPath, &st) == -1)
 	Panic(errno, "stat");
       if (st.st_uid != real_uid)
 	Panic(0, "Unfortunatelly you are not its owner.");
@@ -523,7 +529,7 @@
   if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
     Panic(errno, "reopen socket");
 #endif
-  (void) unlink(SockPath);
+  (void) screen_unlink(SockPath);
   if (bind(s, (struct sockaddr *) & a, strlen(SockPath) + 2) == -1)
     Panic(errno, "bind (%s)", SockPath);
 #ifdef SOCK_NOT_IN_FS
@@ -534,7 +540,7 @@
       close(f);
     }
 #else
-  chmod(SockPath, SOCKMODE);
+  screen_chmod(SockPath, SOCKMODE);
 # ifndef USE_SETEUID
   chown(SockPath, real_uid, real_gid);
 # endif
@@ -823,7 +829,8 @@
 # ifndef BROKEN_PIPE
   /* Reopen pipe to prevent EOFs at the select() call */
   close(ServerSocket);
-  if ((ServerSocket = secopen(SockPath, O_RDONLY | O_NONBLOCK, 0)) < 0)
+  if ((ServerSocket = secopen(SockPath,
+		  O_RDONLY | O_NONBLOCK | MY_O_BINARY, 0)) < 0)
     Panic(errno, "reopen fifo %s", SockPath);
   evdeq(&serv_read);
   serv_read.fd = ServerSocket;
@@ -908,7 +915,11 @@
 	  Msg(0, "Attach attempt with bad pid(%d)!", m.m.attach.apid);
           break;
 	}
+#ifndef O_NOCTTY
       if ((i = secopen(m.m_tty, O_RDWR | O_NONBLOCK, 0)) < 0)
+#else /* O_NOCTTY */
+      if ((i = secopen(m.m_tty, O_RDWR | O_NONBLOCK | O_NOCTTY, 0)) < 0)
+#endif
 	{
 	  Msg(errno, "Attach: Could not open %s!", m.m_tty);
 	  Kill(m.m.attach.apid, SIG_BYE);
@@ -1045,7 +1056,7 @@
   int x;
 
   sap = (struct sockaddr_un *)sapp;
-  if (stat(sap->sun_path, &st))
+  if (screen_stat(sap->sun_path, &st))
     return -1;
   chmod(sap->sun_path, 0);
   x = connect(s, (struct sockaddr *) sap, len);
@@ -1067,7 +1078,7 @@
       if (UserContext() <= 0)
         return UserStatus();
     }
-  r = chmod(SockPath, SOCKMODE);
+  r = screen_chmod(SockPath, SOCKMODE);
   /* 
    * Sockets usually reside in the /tmp/ area, where sysadmin scripts
    * may be happy to remove old files. We manually prevent the socket
@@ -1090,11 +1101,11 @@
   if ((int)geteuid() != real_uid)
     {
       if (UserContext() > 0)
-	UserReturn(unlink(SockPath));
+	UserReturn(screen_unlink(SockPath));
       (void)UserStatus();
     }
   else
-    (void) unlink(SockPath);
+    (void) screen_unlink(SockPath);
 
   if ((ServerSocket = MakeServerSocket()) < 0)
     return 0;
@@ -1424,3 +1435,157 @@
   EffectiveAclUser = 0;
 #endif
 }
+
+#ifdef CYGWIN_FILEMODE
+/* On cygwin (without ntea/ntsec), the mode of the UNIX domain
+ * socket is always either 755 or 655. Unfortunately, screen
+ * saves the socket state as the file mode.
+ *
+ * Therefore, we emulate the file mode, creating a special
+ * key file. This is ugly and possibly unsecure hack, but not
+ * critical on single-user system.
+ */
+
+static char *GetModeKeyPath __P((char *));
+static int CreateModeKeyFile __P((char *, mode_t));
+static int ReadModeKeyFile __P((char *, mode_t *));
+static char modekey_format[] = "$$ screen: socket mode=0%o $$\n";
+
+int
+screen_stat(path, st)
+char *path;
+struct stat *st;
+{
+  mode_t modetmp;
+
+  if (stat(SockPath, st))
+    return -1;
+  if (!ReadModeKeyFile(path, &modetmp))
+    st->st_mode = (st->st_mode & ~07777) | modetmp;
+  errno = 0;
+  return 0;
+}
+
+int
+screen_chmod(path, mode)
+char *path;
+mode_t mode;
+{
+  if (chmod(path, mode))
+    return -1;
+  CreateModeKeyFile(path, mode);
+  errno = 0;
+  return 0;
+}
+
+#ifdef NAMEDPIPE
+int
+screen_mkfifo(path, mode)
+char *path;
+mode_t mode;
+{
+  if (mkfifo(path, mode))
+    return -1;
+  CreateModeKeyFile(path, mode);
+  errno = 0;
+  return 0;
+}
+#endif
+
+int
+screen_unlink(path)
+char *path;
+{
+  char *modekey_path;
+  
+  if (unlink(path))
+    return -1;
+  if ((modekey_path = GetModeKeyPath(path)) == NULL)
+    return -1;
+  unlink(modekey_path);
+  free(modekey_path);
+  errno = 0;
+  return 0;
+}
+
+static char *
+GetModeKeyPath(path)
+char *path;
+{
+  char *keypath;
+  char *base;
+
+  keypath = malloc(strlen(path) + 7);
+  if (keypath == NULL) {
+    Panic (0, strnomem);
+    return NULL;
+  }
+  base = strrchr(path, '/');
+  if (base == NULL)
+    base = path;
+  else
+    base++;
+  strncpy(keypath, path, base-path);
+  sprintf(keypath+(base-path), ".%s.mode", base);
+  return keypath;
+}
+
+static int
+CreateModeKeyFile(path, mode)
+char *path;
+mode_t mode;
+{
+  int err = 0;
+  char *modekey_path;
+  FILE *keyfile;
+
+  if ((modekey_path = GetModeKeyPath(path)) == NULL)
+    return -1;
+  if ((keyfile = fopen(modekey_path, "w")) == NULL) {
+    err = errno;
+  } else {
+    errno = 0;
+    fprintf(keyfile, modekey_format, (unsigned int)mode);
+    if (errno)
+      err = errno;
+    if (fclose(keyfile))
+      err = errno;
+# ifndef USE_SETEUID
+    if (chown(modekey_path, getuid(), getgid()))
+      err = errno;
+# endif
+  }
+  free(modekey_path);
+  errno = err;
+  return (err) ? -1 : 0;
+}
+
+static int
+ReadModeKeyFile(path, modep)
+char *path;
+mode_t *modep;
+{
+  int err = 0;
+  char *modekey_path;
+  FILE *keyfile;
+  unsigned int mode_u;
+
+  if ((modekey_path = GetModeKeyPath(path)) == NULL)
+    return -1;
+
+  if ((keyfile = fopen(modekey_path, "r")) == NULL) {
+    err = errno;
+  } else {
+    if (fscanf(keyfile, modekey_format, &mode_u) != 1)
+      err=errno;
+    if (fclose(keyfile))
+      err=errno;
+  }
+  free(modekey_path);
+  errno = err;
+  if (err)
+    return -1;
+  *modep = (mode_t)mode_u;
+  return 0;
+}
+#endif /* CYGWIN_FILEMODE */
diff -ru screen-4.0.2.orig/utmp.c screen-4.0.2/utmp.c
--- screen-4.0.2.orig/utmp.c	2003-09-08 23:27:17.000000000 +0900
+++ screen-4.0.2/utmp.c	2004-12-01 15:34:27.039798400 +0900
@@ -89,7 +89,7 @@
 static int  initutmp __P((void));
 static void setutent __P((void));
 #endif
-#if defined(linux) && defined(GETUTENT)
+#if (defined(linux) || defined(__CYGWIN__)) && defined(GETUTENT)
 static struct utmp *xpututline __P((struct utmp *utmp));
 # define pututline xpututline
 #endif
@@ -589,7 +589,7 @@
 struct utmp *u;
 {
   u->ut_type = DEAD_PROCESS;
-#if !defined(linux) || defined(EMPTY)
+#if !defined(__CYGWIN__) && (!defined(linux) || defined(EMPTY))
   u->ut_exit.e_termination = 0;
   u->ut_exit.e_exit = 0;
 #endif
@@ -858,7 +858,7 @@
 }
 # endif /* BUGGYGETLOGIN */
 
-#if defined(linux) && defined(GETUTENT)
+#if (defined(linux) || defined(__CYGWIN__)) && defined(GETUTENT)
 # undef pututline
 
 /* aargh, linux' pututline returns void! */
