Make serial fd blocking mode depend on FILE_FLAG_OVERLAPPED.

diff --git a/files/dos_fs.c b/files/dos_fs.c
index 0716360..39b270f 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -705,13 +705,13 @@
 /**************************************************************************
  *         DOSFS_CreateCommPort
  */
-static HANDLE DOSFS_CreateCommPort(LPCSTR name, DWORD access)
+static HANDLE DOSFS_CreateCommPort(LPCSTR name, DWORD access, DWORD attributes)
 {
     HANDLE ret;
     char devname[40];
     size_t len;
 
-    TRACE("%s %lx\n", name, access);
+    TRACE_(file)("%s %lx %lx\n", name, access, attributes);
 
     PROFILE_GetWineIniString("serialports",name,"",devname,sizeof devname);
     if(!devname[0])
@@ -724,6 +724,7 @@
     {
         req->access  = access;
         req->inherit = 0;  /*FIXME*/
+        req->attributes = attributes;
         req->sharing = FILE_SHARE_READ|FILE_SHARE_WRITE;
         memcpy( server_data_ptr(req), devname, len );
         SetLastError(0);
@@ -745,7 +746,7 @@
  * Open a DOS device. This might not map 1:1 into the UNIX device concept.
  * Returns 0 on failure.
  */
-HANDLE DOSFS_OpenDevice( const char *name, DWORD access )
+HANDLE DOSFS_OpenDevice( const char *name, DWORD access, DWORD attributes )
 {
     int i;
     const char *p;
@@ -790,7 +791,7 @@
                     return FILE_CreateDevice( i, access, NULL );
 		}
 
-                if( (handle=DOSFS_CreateCommPort(DOSFS_Devices[i].name,access)) )
+                if( (handle=DOSFS_CreateCommPort(DOSFS_Devices[i].name,access,attributes)) )
                     return handle;
                 FIXME("device open %s not supported (yet)\n",DOSFS_Devices[i].name);
     		return 0;
diff --git a/files/file.c b/files/file.c
index ff3c4b5..4ec9a40 100644
--- a/files/file.c
+++ b/files/file.c
@@ -488,7 +488,7 @@
     {
         TRACE("opening device '%s'\n", filename );
 
-        if (!(ret = DOSFS_OpenDevice( filename, access )))
+        if (!(ret = DOSFS_OpenDevice( filename, access, attributes )))
         {
             /* Do not silence this please. It is a critical error. -MM */
             ERR("Couldn't open device '%s'!\n",filename);
diff --git a/include/file.h b/include/file.h
index ba67781..9f668d1 100644
--- a/include/file.h
+++ b/include/file.h
@@ -98,7 +98,7 @@
 extern BOOL DOSFS_ToDosFCBFormat( LPCSTR name, LPSTR buffer );
 extern const DOS_DEVICE *DOSFS_GetDevice( const char *name );
 extern const DOS_DEVICE *DOSFS_GetDeviceByHandle( HFILE hFile );
-extern HANDLE DOSFS_OpenDevice( const char *name, DWORD access );
+extern HANDLE DOSFS_OpenDevice( const char *name, DWORD access, DWORD attributes );
 extern BOOL DOSFS_FindUnixName( LPCSTR path, LPCSTR name, LPSTR long_buf,
                                   INT long_len, LPSTR short_buf,
                                   BOOL ignore_case );
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index bbac77a..2df3002 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -576,6 +576,7 @@
 #define FD_TYPE_DEFAULT    1
 #define FD_TYPE_CONSOLE    2
 #define FD_TYPE_OVERLAPPED 3
+#define FD_TYPE_TIMEOUT    4
 
 
 
@@ -1454,6 +1455,7 @@
     struct request_header __header;
     unsigned int access;
     int          inherit;
+    unsigned int attributes;
     unsigned int sharing;
     /* VARARG(name,string); */
     handle_t     handle;
@@ -1917,6 +1919,6 @@
     struct get_window_tree_request get_window_tree;
 };
 
-#define SERVER_PROTOCOL_VERSION 54
+#define SERVER_PROTOCOL_VERSION 55
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def
index e519beb..a7b7a2d 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -532,6 +532,7 @@
 #define FD_TYPE_DEFAULT    1
 #define FD_TYPE_CONSOLE    2
 #define FD_TYPE_OVERLAPPED 3
+#define FD_TYPE_TIMEOUT    4
 
 
 /* Set a file current position */
@@ -1299,6 +1300,7 @@
 @REQ(create_serial)
     unsigned int access;       /* wanted access rights */
     int          inherit;      /* inherit flag */
+    unsigned int attributes;   /* eg. FILE_FLAG_OVERLAPPED */
     unsigned int sharing;      /* sharing flags */
     VARARG(name,string);       /* file name */
 @REPLY
diff --git a/server/serial.c b/server/serial.c
index d6a1ea4..c16ccd7 100644
--- a/server/serial.c
+++ b/server/serial.c
@@ -44,6 +44,7 @@
 {
     struct object       obj;
     unsigned int        access;
+    unsigned int        attrib;
 
     /* timeout values */
     unsigned int        readinterval;
@@ -78,7 +79,7 @@
 
 /* SERIAL PORT functions */
 
-static struct serial *create_serial( const char *nameptr, size_t len, unsigned int access )
+static struct serial *create_serial( const char *nameptr, size_t len, unsigned int access, int attributes )
 {
     struct serial *serial;
     struct termios tios;
@@ -115,8 +116,14 @@
         return NULL;
     }
 
+    /* set the fd back to blocking if necessary */
+    if( ! (attributes & FILE_FLAG_OVERLAPPED) )
+       if(0>fcntl(fd, F_SETFL, 0))
+           perror("fcntl");
+
     if ((serial = alloc_object( &serial_ops, fd )))
     {
+        serial->attrib       = attributes;
         serial->access       = access;
         serial->readinterval = 0;
         serial->readmult     = 0;
@@ -160,6 +167,9 @@
 
 static int serial_get_info( struct object *obj, struct get_file_info_request *req )
 {
+    struct serial *serial = (struct serial *) obj;
+    assert( obj->ops == &serial_ops );
+
     if (req)
     {
         req->type        = FILE_TYPE_CHAR;
@@ -173,7 +183,11 @@
         req->index_low   = 0;
         req->serial      = 0;
     }
-    return FD_TYPE_DEFAULT;
+
+    if(serial->attrib & FILE_FLAG_OVERLAPPED)
+        return FD_TYPE_OVERLAPPED;
+
+    return FD_TYPE_TIMEOUT;
 }
 
 /* these function calculates the timeout for an async operation
@@ -202,7 +216,7 @@
     struct serial *serial;
 
     req->handle = 0;
-    if ((serial = create_serial( get_req_data(req), get_req_data_size(req), req->access )))
+    if ((serial = create_serial( get_req_data(req), get_req_data_size(req), req->access, req->attributes )))
     {
         req->handle = alloc_handle( current->process, serial, req->access, req->inherit );
         release_object( serial );
diff --git a/server/trace.c b/server/trace.c
index eeb323c..9ce6400 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1556,6 +1556,7 @@
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
+    fprintf( stderr, " attributes=%08x,", req->attributes );
     fprintf( stderr, " sharing=%08x,", req->sharing );
     fprintf( stderr, " name=" );
     cur_pos += dump_varargs_string( req );