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",