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.
This commit is contained in:
parent
b592cbbc18
commit
72f87b8c06
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue