Commit 72f87b8c authored by Alexandre Julliard's avatar Alexandre Julliard

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.
parent b592cbbc
......@@ -805,18 +805,6 @@ enum fd_type
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 @@ enum request
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 @@ union generic_request
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 @@ union generic_reply
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 @@ union generic_reply
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 */
......@@ -362,6 +362,7 @@ void file_set_error(void)
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 @@ static int extend_file( struct file *file, off_t size )
/* 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 @@ static int extend_file( struct file *file, off_t size )
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 @@ int grow_file( struct file *file, int size_high, int size_low )
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 @@ DECL_HANDLER(alloc_file_handle)
}
}
/* 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)
{
......
......@@ -122,7 +122,8 @@ static struct file *get_shared_file( struct mapping *mapping )
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 @@ static int build_shared_mapping( struct mapping *mapping, int fd,
/* 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 @@ static int get_image_params( struct mapping *mapping )
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 @@ static int get_image_params( struct mapping *mapping )
/* 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 );
......
......@@ -615,12 +615,6 @@ enum fd_type
#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 */
......
......@@ -142,7 +142,6 @@ DECL_HANDLER(open_semaphore);
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 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(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,
......
......@@ -243,6 +243,8 @@ void init_signals(void)
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;
......
......@@ -871,11 +871,6 @@ static void dump_get_handle_fd_reply( const struct get_handle_fd_reply *req )
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 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(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 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(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 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"create_file",
"alloc_file_handle",
"get_handle_fd",
"truncate_file",
"flush_file",
"lock_file",
"unlock_file",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment