Use pread/pwrite everywhere to avoid changing the file position while
the client is using it.
Get rid of the no longer used truncate_file request.

diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 1fa002f..91dab38 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -805,18 +805,6 @@
 
 
 
-struct truncate_file_request
-{
-    struct request_header __header;
-    obj_handle_t handle;
-};
-struct truncate_file_reply
-{
-    struct reply_header __header;
-};
-
-
-
 struct flush_file_request
 {
     struct request_header __header;
@@ -3138,7 +3126,6 @@
     REQ_create_file,
     REQ_alloc_file_handle,
     REQ_get_handle_fd,
-    REQ_truncate_file,
     REQ_flush_file,
     REQ_lock_file,
     REQ_unlock_file,
@@ -3322,7 +3309,6 @@
     struct create_file_request create_file_request;
     struct alloc_file_handle_request alloc_file_handle_request;
     struct get_handle_fd_request get_handle_fd_request;
-    struct truncate_file_request truncate_file_request;
     struct flush_file_request flush_file_request;
     struct lock_file_request lock_file_request;
     struct unlock_file_request unlock_file_request;
@@ -3504,7 +3490,6 @@
     struct create_file_reply create_file_reply;
     struct alloc_file_handle_reply alloc_file_handle_reply;
     struct get_handle_fd_reply get_handle_fd_reply;
-    struct truncate_file_reply truncate_file_reply;
     struct flush_file_reply flush_file_reply;
     struct lock_file_reply lock_file_reply;
     struct unlock_file_reply unlock_file_reply;
@@ -3644,6 +3629,6 @@
     struct set_global_windows_reply set_global_windows_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 139
+#define SERVER_PROTOCOL_VERSION 140
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/file.c b/server/file.c
index 3fb6d5c..73363dd 100644
--- a/server/file.c
+++ b/server/file.c
@@ -362,6 +362,7 @@
     case ENOTEMPTY: set_error( STATUS_DIRECTORY_NOT_EMPTY ); break;
     case EIO:       set_error( STATUS_ACCESS_VIOLATION ); break;
     case ENOTDIR:   set_error( STATUS_NOT_A_DIRECTORY ); break;
+    case EFBIG:     set_error( STATUS_SECTION_TOO_BIG ); break;
 #ifdef EOVERFLOW
     case EOVERFLOW: set_error( STATUS_INVALID_PARAMETER ); break;
 #endif
@@ -387,8 +388,7 @@
 
     /* extend the file one byte beyond the requested size and then truncate it */
     /* this should work around ftruncate implementations that can't extend files */
-    if ((lseek( unix_fd, size, SEEK_SET ) != -1) &&
-        (write( unix_fd, &zero, 1 ) != -1))
+    if (pwrite( unix_fd, &zero, 1, size ) != -1)
     {
         ftruncate( unix_fd, size );
         return 1;
@@ -397,31 +397,12 @@
     return 0;
 }
 
-/* truncate file at current position */
-static int truncate_file( struct file *file )
-{
-    int ret = 0;
-    int unix_fd = get_file_unix_fd( file );
-    off_t pos = lseek( unix_fd, 0, SEEK_CUR );
-    off_t eof = lseek( unix_fd, 0, SEEK_END );
-
-    if (eof < pos) ret = extend_file( file, pos );
-    else
-    {
-        if (ftruncate( unix_fd, pos ) != -1) ret = 1;
-        else file_set_error();
-    }
-    lseek( unix_fd, pos, SEEK_SET );  /* restore file pos */
-    return ret;
-}
-
 /* try to grow the file to the specified size */
 int grow_file( struct file *file, int size_high, int size_low )
 {
-    int ret = 0;
     struct stat st;
     int unix_fd = get_file_unix_fd( file );
-    off_t old_pos, size = size_low + (((off_t)size_high)<<32);
+    off_t size = size_low + (((off_t)size_high)<<32);
 
     if (fstat( unix_fd, &st ) == -1)
     {
@@ -429,10 +410,7 @@
         return 0;
     }
     if (st.st_size >= size) return 1;  /* already large enough */
-    old_pos = lseek( unix_fd, 0, SEEK_CUR );  /* save old pos */
-    ret = extend_file( file, size );
-    lseek( unix_fd, old_pos, SEEK_SET );  /* restore file pos */
-    return ret;
+    return extend_file( file, size );
 }
 
 /* create a file */
@@ -468,18 +446,6 @@
     }
 }
 
-/* truncate (or extend) a file */
-DECL_HANDLER(truncate_file)
-{
-    struct file *file;
-
-    if ((file = get_file_obj( current->process, req->handle, GENERIC_WRITE )))
-    {
-        truncate_file( file );
-        release_object( file );
-    }
-}
-
 /* lock a region of a file */
 DECL_HANDLER(lock_file)
 {
diff --git a/server/mapping.c b/server/mapping.c
index 2cac776..44bc331 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -122,7 +122,8 @@
 static int build_shared_mapping( struct mapping *mapping, int fd,
                                  IMAGE_SECTION_HEADER *sec, int nb_sec )
 {
-    int i, max_size, total_size, pos;
+    int i, max_size, total_size;
+    off_t shared_pos, read_pos, write_pos;
     char *buffer = NULL;
     int shared_fd;
     long toread;
@@ -154,24 +155,27 @@
 
     /* copy the shared sections data into the temp file */
 
-    for (i = pos = 0; i < nb_sec; i++)
+    shared_pos = 0;
+    for (i = 0; i < nb_sec; i++)
     {
         if (!(sec[i].Characteristics & IMAGE_SCN_MEM_SHARED)) continue;
         if (!(sec[i].Characteristics & IMAGE_SCN_MEM_WRITE)) continue;
-        if (lseek( shared_fd, pos, SEEK_SET ) != pos) goto error;
-        pos += ROUND_SIZE( 0, sec[i].Misc.VirtualSize );
+        write_pos = shared_pos;
+        shared_pos += ROUND_SIZE( 0, sec[i].Misc.VirtualSize );
         if ((sec[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) &&
             !(sec[i].Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)) continue;
         if (!sec[i].PointerToRawData || !sec[i].SizeOfRawData) continue;
-        if (lseek( fd, sec[i].PointerToRawData, SEEK_SET ) != sec[i].PointerToRawData) goto error;
+        read_pos = sec[i].PointerToRawData;
         toread = sec[i].SizeOfRawData;
         while (toread)
         {
-            long res = read( fd, buffer + sec[i].SizeOfRawData - toread, toread );
+            long res = pread( fd, buffer + sec[i].SizeOfRawData - toread, toread, read_pos );
             if (res <= 0) goto error;
             toread -= res;
+            read_pos += res;
         }
-        if (write( shared_fd, buffer, sec[i].SizeOfRawData ) != sec[i].SizeOfRawData) goto error;
+        if (pwrite( shared_fd, buffer, sec[i].SizeOfRawData, write_pos ) != sec[i].SizeOfRawData)
+            goto error;
     }
     free( buffer );
     return 1;
@@ -190,29 +194,35 @@
     IMAGE_NT_HEADERS nt;
     IMAGE_SECTION_HEADER *sec = NULL;
     struct fd *fd;
-    int unix_fd, filepos, size;
+    off_t pos;
+    int unix_fd, size;
 
     /* load the headers */
 
     if (!(fd = mapping_get_fd( &mapping->obj ))) return 0;
     unix_fd = get_unix_fd( fd );
-    filepos = lseek( unix_fd, 0, SEEK_SET );
-    if (read( unix_fd, &dos, sizeof(dos) ) != sizeof(dos)) goto error;
+    if (pread( unix_fd, &dos, sizeof(dos), 0 ) != sizeof(dos)) goto error;
     if (dos.e_magic != IMAGE_DOS_SIGNATURE) goto error;
-    if (lseek( unix_fd, dos.e_lfanew, SEEK_SET ) == -1) goto error;
+    pos = dos.e_lfanew;
 
-    if (read( unix_fd, &nt.Signature, sizeof(nt.Signature) ) != sizeof(nt.Signature)) goto error;
+    if (pread( unix_fd, &nt.Signature, sizeof(nt.Signature), pos ) != sizeof(nt.Signature))
+        goto error;
+    pos += sizeof(nt.Signature);
     if (nt.Signature != IMAGE_NT_SIGNATURE) goto error;
-    if (read( unix_fd, &nt.FileHeader, sizeof(nt.FileHeader) ) != sizeof(nt.FileHeader)) goto error;
+    if (pread( unix_fd, &nt.FileHeader, sizeof(nt.FileHeader), pos ) != sizeof(nt.FileHeader))
+        goto error;
+    pos += sizeof(nt.FileHeader);
     /* zero out Optional header in the case it's not present or partial */
     memset(&nt.OptionalHeader, 0, sizeof(nt.OptionalHeader));
-    if (read( unix_fd, &nt.OptionalHeader, nt.FileHeader.SizeOfOptionalHeader) != nt.FileHeader.SizeOfOptionalHeader) goto error;
+    if (pread( unix_fd, &nt.OptionalHeader, nt.FileHeader.SizeOfOptionalHeader,
+               pos ) != nt.FileHeader.SizeOfOptionalHeader) goto error;
+    pos += nt.FileHeader.SizeOfOptionalHeader;
 
     /* load the section headers */
 
     size = sizeof(*sec) * nt.FileHeader.NumberOfSections;
     if (!(sec = malloc( size ))) goto error;
-    if (read( unix_fd, sec, size ) != size) goto error;
+    if (pread( unix_fd, sec, size, pos ) != size) goto error;
 
     if (!build_shared_mapping( mapping, unix_fd, sec, nt.FileHeader.NumberOfSections )) goto error;
 
@@ -232,13 +242,11 @@
     /* sanity check */
     if (mapping->header_size > mapping->size_low) goto error;
 
-    lseek( unix_fd, filepos, SEEK_SET );
     free( sec );
     release_object( fd );
     return 1;
 
  error:
-    lseek( unix_fd, filepos, SEEK_SET );
     if (sec) free( sec );
     release_object( fd );
     set_error( STATUS_INVALID_FILE_FOR_SECTION );
diff --git a/server/protocol.def b/server/protocol.def
index 847eb9e..f54b0c6 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -615,12 +615,6 @@
 #define FD_FLAG_SEND_SHUTDOWN      0x08
 
 
-/* Truncate (or extend) a file */
-@REQ(truncate_file)
-    obj_handle_t handle;        /* handle to the file */
-@END
-
-
 /* Flush a file buffers */
 @REQ(flush_file)
     obj_handle_t handle;        /* handle to the file */
diff --git a/server/request.h b/server/request.h
index 80b4d18..77d9ffc 100644
--- a/server/request.h
+++ b/server/request.h
@@ -142,7 +142,6 @@
 DECL_HANDLER(create_file);
 DECL_HANDLER(alloc_file_handle);
 DECL_HANDLER(get_handle_fd);
-DECL_HANDLER(truncate_file);
 DECL_HANDLER(flush_file);
 DECL_HANDLER(lock_file);
 DECL_HANDLER(unlock_file);
@@ -325,7 +324,6 @@
     (req_handler)req_create_file,
     (req_handler)req_alloc_file_handle,
     (req_handler)req_get_handle_fd,
-    (req_handler)req_truncate_file,
     (req_handler)req_flush_file,
     (req_handler)req_lock_file,
     (req_handler)req_unlock_file,
diff --git a/server/signal.c b/server/signal.c
index 593b88a..99d9b82 100644
--- a/server/signal.c
+++ b/server/signal.c
@@ -243,6 +243,8 @@
     action.sa_handler = do_sigterm;
     sigaction( SIGQUIT, &action, NULL );
     sigaction( SIGTERM, &action, NULL );
+    action.sa_handler = SIG_IGN;
+    sigaction( SIGXFSZ, &action, NULL );
 #ifdef HAVE_SIGINFO_T_SI_FD
     action.sa_sigaction = do_sigio;
     action.sa_flags = SA_SIGINFO;
diff --git a/server/trace.c b/server/trace.c
index 094a332..f9c6f06 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -871,11 +871,6 @@
     fprintf( stderr, " flags=%d", req->flags );
 }
 
-static void dump_truncate_file_request( const struct truncate_file_request *req )
-{
-    fprintf( stderr, " handle=%p", req->handle );
-}
-
 static void dump_flush_file_request( const struct flush_file_request *req )
 {
     fprintf( stderr, " handle=%p", req->handle );
@@ -2561,7 +2556,6 @@
     (dump_func)dump_create_file_request,
     (dump_func)dump_alloc_file_handle_request,
     (dump_func)dump_get_handle_fd_request,
-    (dump_func)dump_truncate_file_request,
     (dump_func)dump_flush_file_request,
     (dump_func)dump_lock_file_request,
     (dump_func)dump_unlock_file_request,
@@ -2741,7 +2735,6 @@
     (dump_func)dump_create_file_reply,
     (dump_func)dump_alloc_file_handle_reply,
     (dump_func)dump_get_handle_fd_reply,
-    (dump_func)0,
     (dump_func)dump_flush_file_reply,
     (dump_func)dump_lock_file_reply,
     (dump_func)0,
@@ -2921,7 +2914,6 @@
     "create_file",
     "alloc_file_handle",
     "get_handle_fd",
-    "truncate_file",
     "flush_file",
     "lock_file",
     "unlock_file",