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 flush_file_request
|
||||||
{
|
{
|
||||||
struct request_header __header;
|
struct request_header __header;
|
||||||
|
@ -3138,7 +3126,6 @@ enum request
|
||||||
REQ_create_file,
|
REQ_create_file,
|
||||||
REQ_alloc_file_handle,
|
REQ_alloc_file_handle,
|
||||||
REQ_get_handle_fd,
|
REQ_get_handle_fd,
|
||||||
REQ_truncate_file,
|
|
||||||
REQ_flush_file,
|
REQ_flush_file,
|
||||||
REQ_lock_file,
|
REQ_lock_file,
|
||||||
REQ_unlock_file,
|
REQ_unlock_file,
|
||||||
|
@ -3322,7 +3309,6 @@ union generic_request
|
||||||
struct create_file_request create_file_request;
|
struct create_file_request create_file_request;
|
||||||
struct alloc_file_handle_request alloc_file_handle_request;
|
struct alloc_file_handle_request alloc_file_handle_request;
|
||||||
struct get_handle_fd_request get_handle_fd_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 flush_file_request flush_file_request;
|
||||||
struct lock_file_request lock_file_request;
|
struct lock_file_request lock_file_request;
|
||||||
struct unlock_file_request unlock_file_request;
|
struct unlock_file_request unlock_file_request;
|
||||||
|
@ -3504,7 +3490,6 @@ union generic_reply
|
||||||
struct create_file_reply create_file_reply;
|
struct create_file_reply create_file_reply;
|
||||||
struct alloc_file_handle_reply alloc_file_handle_reply;
|
struct alloc_file_handle_reply alloc_file_handle_reply;
|
||||||
struct get_handle_fd_reply get_handle_fd_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 flush_file_reply flush_file_reply;
|
||||||
struct lock_file_reply lock_file_reply;
|
struct lock_file_reply lock_file_reply;
|
||||||
struct unlock_file_reply unlock_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;
|
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 */
|
#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 ENOTEMPTY: set_error( STATUS_DIRECTORY_NOT_EMPTY ); break;
|
||||||
case EIO: set_error( STATUS_ACCESS_VIOLATION ); break;
|
case EIO: set_error( STATUS_ACCESS_VIOLATION ); break;
|
||||||
case ENOTDIR: set_error( STATUS_NOT_A_DIRECTORY ); break;
|
case ENOTDIR: set_error( STATUS_NOT_A_DIRECTORY ); break;
|
||||||
|
case EFBIG: set_error( STATUS_SECTION_TOO_BIG ); break;
|
||||||
#ifdef EOVERFLOW
|
#ifdef EOVERFLOW
|
||||||
case EOVERFLOW: set_error( STATUS_INVALID_PARAMETER ); break;
|
case EOVERFLOW: set_error( STATUS_INVALID_PARAMETER ); break;
|
||||||
#endif
|
#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 */
|
/* extend the file one byte beyond the requested size and then truncate it */
|
||||||
/* this should work around ftruncate implementations that can't extend files */
|
/* this should work around ftruncate implementations that can't extend files */
|
||||||
if ((lseek( unix_fd, size, SEEK_SET ) != -1) &&
|
if (pwrite( unix_fd, &zero, 1, size ) != -1)
|
||||||
(write( unix_fd, &zero, 1 ) != -1))
|
|
||||||
{
|
{
|
||||||
ftruncate( unix_fd, size );
|
ftruncate( unix_fd, size );
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -397,31 +397,12 @@ static int extend_file( struct file *file, off_t size )
|
||||||
return 0;
|
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 */
|
/* try to grow the file to the specified size */
|
||||||
int grow_file( struct file *file, int size_high, int size_low )
|
int grow_file( struct file *file, int size_high, int size_low )
|
||||||
{
|
{
|
||||||
int ret = 0;
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int unix_fd = get_file_unix_fd( file );
|
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)
|
if (fstat( unix_fd, &st ) == -1)
|
||||||
{
|
{
|
||||||
|
@ -429,10 +410,7 @@ int grow_file( struct file *file, int size_high, int size_low )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (st.st_size >= size) return 1; /* already large enough */
|
if (st.st_size >= size) return 1; /* already large enough */
|
||||||
old_pos = lseek( unix_fd, 0, SEEK_CUR ); /* save old pos */
|
return extend_file( file, size );
|
||||||
ret = extend_file( file, size );
|
|
||||||
lseek( unix_fd, old_pos, SEEK_SET ); /* restore file pos */
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create a file */
|
/* 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 */
|
/* lock a region of a file */
|
||||||
DECL_HANDLER(lock_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,
|
static int build_shared_mapping( struct mapping *mapping, int fd,
|
||||||
IMAGE_SECTION_HEADER *sec, int nb_sec )
|
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;
|
char *buffer = NULL;
|
||||||
int shared_fd;
|
int shared_fd;
|
||||||
long toread;
|
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 */
|
/* 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_SHARED)) continue;
|
||||||
if (!(sec[i].Characteristics & IMAGE_SCN_MEM_WRITE)) continue;
|
if (!(sec[i].Characteristics & IMAGE_SCN_MEM_WRITE)) continue;
|
||||||
if (lseek( shared_fd, pos, SEEK_SET ) != pos) goto error;
|
write_pos = shared_pos;
|
||||||
pos += ROUND_SIZE( 0, sec[i].Misc.VirtualSize );
|
shared_pos += ROUND_SIZE( 0, sec[i].Misc.VirtualSize );
|
||||||
if ((sec[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) &&
|
if ((sec[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) &&
|
||||||
!(sec[i].Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)) continue;
|
!(sec[i].Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)) continue;
|
||||||
if (!sec[i].PointerToRawData || !sec[i].SizeOfRawData) 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;
|
toread = sec[i].SizeOfRawData;
|
||||||
while (toread)
|
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;
|
if (res <= 0) goto error;
|
||||||
toread -= res;
|
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 );
|
free( buffer );
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -190,29 +194,35 @@ static int get_image_params( struct mapping *mapping )
|
||||||
IMAGE_NT_HEADERS nt;
|
IMAGE_NT_HEADERS nt;
|
||||||
IMAGE_SECTION_HEADER *sec = NULL;
|
IMAGE_SECTION_HEADER *sec = NULL;
|
||||||
struct fd *fd;
|
struct fd *fd;
|
||||||
int unix_fd, filepos, size;
|
off_t pos;
|
||||||
|
int unix_fd, size;
|
||||||
|
|
||||||
/* load the headers */
|
/* load the headers */
|
||||||
|
|
||||||
if (!(fd = mapping_get_fd( &mapping->obj ))) return 0;
|
if (!(fd = mapping_get_fd( &mapping->obj ))) return 0;
|
||||||
unix_fd = get_unix_fd( fd );
|
unix_fd = get_unix_fd( fd );
|
||||||
filepos = lseek( unix_fd, 0, SEEK_SET );
|
if (pread( unix_fd, &dos, sizeof(dos), 0 ) != sizeof(dos)) goto error;
|
||||||
if (read( unix_fd, &dos, sizeof(dos) ) != sizeof(dos)) goto error;
|
|
||||||
if (dos.e_magic != IMAGE_DOS_SIGNATURE) 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 (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 */
|
/* zero out Optional header in the case it's not present or partial */
|
||||||
memset(&nt.OptionalHeader, 0, sizeof(nt.OptionalHeader));
|
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 */
|
/* load the section headers */
|
||||||
|
|
||||||
size = sizeof(*sec) * nt.FileHeader.NumberOfSections;
|
size = sizeof(*sec) * nt.FileHeader.NumberOfSections;
|
||||||
if (!(sec = malloc( size ))) goto error;
|
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;
|
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 */
|
/* sanity check */
|
||||||
if (mapping->header_size > mapping->size_low) goto error;
|
if (mapping->header_size > mapping->size_low) goto error;
|
||||||
|
|
||||||
lseek( unix_fd, filepos, SEEK_SET );
|
|
||||||
free( sec );
|
free( sec );
|
||||||
release_object( fd );
|
release_object( fd );
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
lseek( unix_fd, filepos, SEEK_SET );
|
|
||||||
if (sec) free( sec );
|
if (sec) free( sec );
|
||||||
release_object( fd );
|
release_object( fd );
|
||||||
set_error( STATUS_INVALID_FILE_FOR_SECTION );
|
set_error( STATUS_INVALID_FILE_FOR_SECTION );
|
||||||
|
|
|
@ -615,12 +615,6 @@ enum fd_type
|
||||||
#define FD_FLAG_SEND_SHUTDOWN 0x08
|
#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 */
|
/* Flush a file buffers */
|
||||||
@REQ(flush_file)
|
@REQ(flush_file)
|
||||||
obj_handle_t handle; /* handle to the file */
|
obj_handle_t handle; /* handle to the file */
|
||||||
|
|
|
@ -142,7 +142,6 @@ DECL_HANDLER(open_semaphore);
|
||||||
DECL_HANDLER(create_file);
|
DECL_HANDLER(create_file);
|
||||||
DECL_HANDLER(alloc_file_handle);
|
DECL_HANDLER(alloc_file_handle);
|
||||||
DECL_HANDLER(get_handle_fd);
|
DECL_HANDLER(get_handle_fd);
|
||||||
DECL_HANDLER(truncate_file);
|
|
||||||
DECL_HANDLER(flush_file);
|
DECL_HANDLER(flush_file);
|
||||||
DECL_HANDLER(lock_file);
|
DECL_HANDLER(lock_file);
|
||||||
DECL_HANDLER(unlock_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_create_file,
|
||||||
(req_handler)req_alloc_file_handle,
|
(req_handler)req_alloc_file_handle,
|
||||||
(req_handler)req_get_handle_fd,
|
(req_handler)req_get_handle_fd,
|
||||||
(req_handler)req_truncate_file,
|
|
||||||
(req_handler)req_flush_file,
|
(req_handler)req_flush_file,
|
||||||
(req_handler)req_lock_file,
|
(req_handler)req_lock_file,
|
||||||
(req_handler)req_unlock_file,
|
(req_handler)req_unlock_file,
|
||||||
|
|
|
@ -243,6 +243,8 @@ void init_signals(void)
|
||||||
action.sa_handler = do_sigterm;
|
action.sa_handler = do_sigterm;
|
||||||
sigaction( SIGQUIT, &action, NULL );
|
sigaction( SIGQUIT, &action, NULL );
|
||||||
sigaction( SIGTERM, &action, NULL );
|
sigaction( SIGTERM, &action, NULL );
|
||||||
|
action.sa_handler = SIG_IGN;
|
||||||
|
sigaction( SIGXFSZ, &action, NULL );
|
||||||
#ifdef HAVE_SIGINFO_T_SI_FD
|
#ifdef HAVE_SIGINFO_T_SI_FD
|
||||||
action.sa_sigaction = do_sigio;
|
action.sa_sigaction = do_sigio;
|
||||||
action.sa_flags = SA_SIGINFO;
|
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 );
|
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 )
|
static void dump_flush_file_request( const struct flush_file_request *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " handle=%p", req->handle );
|
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_create_file_request,
|
||||||
(dump_func)dump_alloc_file_handle_request,
|
(dump_func)dump_alloc_file_handle_request,
|
||||||
(dump_func)dump_get_handle_fd_request,
|
(dump_func)dump_get_handle_fd_request,
|
||||||
(dump_func)dump_truncate_file_request,
|
|
||||||
(dump_func)dump_flush_file_request,
|
(dump_func)dump_flush_file_request,
|
||||||
(dump_func)dump_lock_file_request,
|
(dump_func)dump_lock_file_request,
|
||||||
(dump_func)dump_unlock_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_create_file_reply,
|
||||||
(dump_func)dump_alloc_file_handle_reply,
|
(dump_func)dump_alloc_file_handle_reply,
|
||||||
(dump_func)dump_get_handle_fd_reply,
|
(dump_func)dump_get_handle_fd_reply,
|
||||||
(dump_func)0,
|
|
||||||
(dump_func)dump_flush_file_reply,
|
(dump_func)dump_flush_file_reply,
|
||||||
(dump_func)dump_lock_file_reply,
|
(dump_func)dump_lock_file_reply,
|
||||||
(dump_func)0,
|
(dump_func)0,
|
||||||
|
@ -2921,7 +2914,6 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
||||||
"create_file",
|
"create_file",
|
||||||
"alloc_file_handle",
|
"alloc_file_handle",
|
||||||
"get_handle_fd",
|
"get_handle_fd",
|
||||||
"truncate_file",
|
|
||||||
"flush_file",
|
"flush_file",
|
||||||
"lock_file",
|
"lock_file",
|
||||||
"unlock_file",
|
"unlock_file",
|
||||||
|
|
Loading…
Reference in New Issue