Commit a1fe8b4f authored by Alexandre Julliard's avatar Alexandre Julliard

Use futimes() instead of utime() to implement SetFileTime, so that it

can be done on the client side.
parent dd46d6df
...@@ -15972,6 +15972,7 @@ fi ...@@ -15972,6 +15972,7 @@ fi
for ac_func in \ for ac_func in \
_lwp_create \ _lwp_create \
_lwp_self \ _lwp_self \
...@@ -15988,6 +15989,7 @@ for ac_func in \ ...@@ -15988,6 +15989,7 @@ for ac_func in \
fpclass \ fpclass \
ftruncate \ ftruncate \
ftruncate64 \ ftruncate64 \
futimes \
getnetbyaddr \ getnetbyaddr \
getnetbyname \ getnetbyname \
getopt_long \ getopt_long \
......
...@@ -1027,6 +1027,7 @@ AC_CHECK_FUNCS(\ ...@@ -1027,6 +1027,7 @@ AC_CHECK_FUNCS(\
fpclass \ fpclass \
ftruncate \ ftruncate \
ftruncate64 \ ftruncate64 \
futimes \
getnetbyaddr \ getnetbyaddr \
getnetbyname \ getnetbyname \
getopt_long \ getopt_long \
......
...@@ -83,6 +83,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(file); ...@@ -83,6 +83,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(file);
#define IS_OPTION_TRUE(ch) ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1') #define IS_OPTION_TRUE(ch) ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
#define SECSPERDAY 86400
#define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)SECSPERDAY)
mode_t FILE_umask; mode_t FILE_umask;
/*********************************************************************** /***********************************************************************
...@@ -1787,26 +1790,57 @@ BOOL WINAPI CopyFileExA(LPCSTR sourceFilename, LPCSTR destFilename, ...@@ -1787,26 +1790,57 @@ BOOL WINAPI CopyFileExA(LPCSTR sourceFilename, LPCSTR destFilename,
* SetFileTime (KERNEL32.@) * SetFileTime (KERNEL32.@)
*/ */
BOOL WINAPI SetFileTime( HANDLE hFile, BOOL WINAPI SetFileTime( HANDLE hFile,
const FILETIME *lpCreationTime, const FILETIME *ctime,
const FILETIME *lpLastAccessTime, const FILETIME *atime,
const FILETIME *lpLastWriteTime ) const FILETIME *mtime )
{ {
BOOL ret; #ifdef HAVE_FUTIMES
SERVER_START_REQ( set_file_time ) BOOL ret = FALSE;
NTSTATUS status;
int fd;
ULONGLONG sec, nsec;
if (!(status = wine_server_handle_to_fd( hFile, GENERIC_WRITE, &fd, NULL, NULL )))
{ {
req->handle = hFile; struct timeval tv[2];
if (lpLastAccessTime)
RtlTimeToSecondsSince1970( (PLARGE_INTEGER) lpLastAccessTime, (DWORD *)&req->access_time ); if (!atime || !mtime)
else {
req->access_time = 0; /* FIXME */ struct stat st;
if (lpLastWriteTime)
RtlTimeToSecondsSince1970( (PLARGE_INTEGER) lpLastWriteTime, (DWORD *)&req->write_time ); tv[0].tv_sec = tv[0].tv_usec = 0;
else tv[1].tv_sec = tv[1].tv_usec = 0;
req->write_time = 0; /* FIXME */ if (!fstat( fd, &st ))
ret = !wine_server_call_err( req ); {
tv[0].tv_sec = st.st_atime;
tv[1].tv_sec = st.st_mtime;
}
}
if (atime)
{
sec = ((ULONGLONG)atime->dwHighDateTime << 32) | atime->dwLowDateTime;
sec = RtlLargeIntegerDivide( sec, 10000000, &nsec );
tv[0].tv_sec = sec - SECS_1601_TO_1970;
tv[0].tv_usec = (UINT)nsec / 10;
}
if (mtime)
{
sec = ((ULONGLONG)mtime->dwHighDateTime << 32) | mtime->dwLowDateTime;
sec = RtlLargeIntegerDivide( sec, 10000000, &nsec );
tv[0].tv_sec = sec - SECS_1601_TO_1970;
tv[0].tv_usec = (UINT)nsec / 10;
}
if (!futimes( fd, tv )) ret = TRUE;
else FILE_SetDosError();
wine_server_release_fd( hFile, fd );
} }
SERVER_END_REQ; else SetLastError( RtlNtStatusToDosError(status) );
return ret; return ret;
#else
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
return FALSE;
#endif /* HAVE_FUTIMES */
} }
......
...@@ -134,6 +134,9 @@ ...@@ -134,6 +134,9 @@
/* Define to 1 if you have the `ftruncate64' function. */ /* Define to 1 if you have the `ftruncate64' function. */
#undef HAVE_FTRUNCATE64 #undef HAVE_FTRUNCATE64
/* Define to 1 if you have the `futimes' function. */
#undef HAVE_FUTIMES
/* Define to 1 if you have the `getbkgd' function. */ /* Define to 1 if you have the `getbkgd' function. */
#undef HAVE_GETBKGD #undef HAVE_GETBKGD
......
...@@ -834,20 +834,6 @@ struct truncate_file_reply ...@@ -834,20 +834,6 @@ struct truncate_file_reply
struct set_file_time_request
{
struct request_header __header;
obj_handle_t handle;
time_t access_time;
time_t write_time;
};
struct set_file_time_reply
{
struct reply_header __header;
};
struct flush_file_request struct flush_file_request
{ {
struct request_header __header; struct request_header __header;
...@@ -3197,7 +3183,6 @@ enum request ...@@ -3197,7 +3183,6 @@ enum request
REQ_get_handle_fd, REQ_get_handle_fd,
REQ_set_file_pointer, REQ_set_file_pointer,
REQ_truncate_file, REQ_truncate_file,
REQ_set_file_time,
REQ_flush_file, REQ_flush_file,
REQ_get_file_info, REQ_get_file_info,
REQ_lock_file, REQ_lock_file,
...@@ -3384,7 +3369,6 @@ union generic_request ...@@ -3384,7 +3369,6 @@ union generic_request
struct get_handle_fd_request get_handle_fd_request; struct get_handle_fd_request get_handle_fd_request;
struct set_file_pointer_request set_file_pointer_request; struct set_file_pointer_request set_file_pointer_request;
struct truncate_file_request truncate_file_request; struct truncate_file_request truncate_file_request;
struct set_file_time_request set_file_time_request;
struct flush_file_request flush_file_request; struct flush_file_request flush_file_request;
struct get_file_info_request get_file_info_request; struct get_file_info_request get_file_info_request;
struct lock_file_request lock_file_request; struct lock_file_request lock_file_request;
...@@ -3569,7 +3553,6 @@ union generic_reply ...@@ -3569,7 +3553,6 @@ union generic_reply
struct get_handle_fd_reply get_handle_fd_reply; struct get_handle_fd_reply get_handle_fd_reply;
struct set_file_pointer_reply set_file_pointer_reply; struct set_file_pointer_reply set_file_pointer_reply;
struct truncate_file_reply truncate_file_reply; struct truncate_file_reply truncate_file_reply;
struct set_file_time_reply set_file_time_reply;
struct flush_file_reply flush_file_reply; struct flush_file_reply flush_file_reply;
struct get_file_info_reply get_file_info_reply; struct get_file_info_reply get_file_info_reply;
struct lock_file_reply lock_file_reply; struct lock_file_reply lock_file_reply;
...@@ -3710,6 +3693,6 @@ union generic_reply ...@@ -3710,6 +3693,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 135 #define SERVER_PROTOCOL_VERSION 136
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -573,37 +573,6 @@ int grow_file( struct file *file, int size_high, int size_low ) ...@@ -573,37 +573,6 @@ int grow_file( struct file *file, int size_high, int size_low )
return ret; return ret;
} }
static int set_file_time( obj_handle_t handle, time_t access_time, time_t write_time )
{
struct file *file;
struct utimbuf utimbuf;
if (!(file = get_file_obj( current->process, handle, GENERIC_WRITE )))
return 0;
if (!file->name)
{
set_error( STATUS_INVALID_HANDLE );
release_object( file );
return 0;
}
if (!access_time || !write_time)
{
struct stat st;
if (stat( file->name, &st ) == -1) goto error;
if (!access_time) access_time = st.st_atime;
if (!write_time) write_time = st.st_mtime;
}
utimbuf.actime = access_time;
utimbuf.modtime = write_time;
if (utime( file->name, &utimbuf ) == -1) goto error;
release_object( file );
return 1;
error:
file_set_error();
release_object( file );
return 0;
}
/* create a file */ /* create a file */
DECL_HANDLER(create_file) DECL_HANDLER(create_file)
{ {
...@@ -659,12 +628,6 @@ DECL_HANDLER(truncate_file) ...@@ -659,12 +628,6 @@ DECL_HANDLER(truncate_file)
} }
} }
/* set a file access and modification times */
DECL_HANDLER(set_file_time)
{
set_file_time( req->handle, req->access_time, req->write_time );
}
/* lock a region of a file */ /* lock a region of a file */
DECL_HANDLER(lock_file) DECL_HANDLER(lock_file)
{ {
......
...@@ -633,14 +633,6 @@ enum fd_type ...@@ -633,14 +633,6 @@ enum fd_type
@END @END
/* Set a file access and modification times */
@REQ(set_file_time)
obj_handle_t handle; /* handle to the file */
time_t access_time; /* last access time */
time_t write_time; /* last write time */
@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 */
......
...@@ -144,7 +144,6 @@ DECL_HANDLER(alloc_file_handle); ...@@ -144,7 +144,6 @@ DECL_HANDLER(alloc_file_handle);
DECL_HANDLER(get_handle_fd); DECL_HANDLER(get_handle_fd);
DECL_HANDLER(set_file_pointer); DECL_HANDLER(set_file_pointer);
DECL_HANDLER(truncate_file); DECL_HANDLER(truncate_file);
DECL_HANDLER(set_file_time);
DECL_HANDLER(flush_file); DECL_HANDLER(flush_file);
DECL_HANDLER(get_file_info); DECL_HANDLER(get_file_info);
DECL_HANDLER(lock_file); DECL_HANDLER(lock_file);
...@@ -330,7 +329,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = ...@@ -330,7 +329,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_get_handle_fd, (req_handler)req_get_handle_fd,
(req_handler)req_set_file_pointer, (req_handler)req_set_file_pointer,
(req_handler)req_truncate_file, (req_handler)req_truncate_file,
(req_handler)req_set_file_time,
(req_handler)req_flush_file, (req_handler)req_flush_file,
(req_handler)req_get_file_info, (req_handler)req_get_file_info,
(req_handler)req_lock_file, (req_handler)req_lock_file,
......
...@@ -891,13 +891,6 @@ static void dump_truncate_file_request( const struct truncate_file_request *req ...@@ -891,13 +891,6 @@ static void dump_truncate_file_request( const struct truncate_file_request *req
fprintf( stderr, " handle=%p", req->handle ); fprintf( stderr, " handle=%p", req->handle );
} }
static void dump_set_file_time_request( const struct set_file_time_request *req )
{
fprintf( stderr, " handle=%p,", req->handle );
fprintf( stderr, " access_time=%ld,", (long)req->access_time );
fprintf( stderr, " write_time=%ld", (long)req->write_time );
}
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 );
...@@ -2608,7 +2601,6 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { ...@@ -2608,7 +2601,6 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_handle_fd_request, (dump_func)dump_get_handle_fd_request,
(dump_func)dump_set_file_pointer_request, (dump_func)dump_set_file_pointer_request,
(dump_func)dump_truncate_file_request, (dump_func)dump_truncate_file_request,
(dump_func)dump_set_file_time_request,
(dump_func)dump_flush_file_request, (dump_func)dump_flush_file_request,
(dump_func)dump_get_file_info_request, (dump_func)dump_get_file_info_request,
(dump_func)dump_lock_file_request, (dump_func)dump_lock_file_request,
...@@ -2791,7 +2783,6 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { ...@@ -2791,7 +2783,6 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_handle_fd_reply, (dump_func)dump_get_handle_fd_reply,
(dump_func)dump_set_file_pointer_reply, (dump_func)dump_set_file_pointer_reply,
(dump_func)0, (dump_func)0,
(dump_func)0,
(dump_func)dump_flush_file_reply, (dump_func)dump_flush_file_reply,
(dump_func)dump_get_file_info_reply, (dump_func)dump_get_file_info_reply,
(dump_func)dump_lock_file_reply, (dump_func)dump_lock_file_reply,
...@@ -2974,7 +2965,6 @@ static const char * const req_names[REQ_NB_REQUESTS] = { ...@@ -2974,7 +2965,6 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"get_handle_fd", "get_handle_fd",
"set_file_pointer", "set_file_pointer",
"truncate_file", "truncate_file",
"set_file_time",
"flush_file", "flush_file",
"get_file_info", "get_file_info",
"lock_file", "lock_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