Commit 4a43546b authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

server: Fix up executable permissions when renaming files.

Same as MoveFileWithProgressW(). Signed-off-by: 's avatarZebediah Figura <zfigura@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 6971fd2d
...@@ -2430,6 +2430,16 @@ static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, ...@@ -2430,6 +2430,16 @@ static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr,
goto failed; goto failed;
} }
if (is_file_executable( fd->unix_name ) != is_file_executable( name ) && !fstat( fd->unix_fd, &st ))
{
if (is_file_executable( fd->unix_name ))
/* set executable bit where read bit is set */
st.st_mode |= (st.st_mode & 0444) >> 2;
else
st.st_mode &= ~0111;
fchmod( fd->unix_fd, st.st_mode );
}
free( fd->unix_name ); free( fd->unix_name );
fd->unix_name = name; fd->unix_name = name;
fd->closed->unix_name = name; fd->closed->unix_name = name;
......
...@@ -191,6 +191,12 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_ ...@@ -191,6 +191,12 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
return &file->obj; return &file->obj;
} }
int is_file_executable( const char *name )
{
int len = strlen( name );
return len >= 4 && (!strcasecmp( name + len - 4, ".exe") || !strcasecmp( name + len - 4, ".com" ));
}
static struct object *create_file( struct fd *root, const char *nameptr, data_size_t len, static struct object *create_file( struct fd *root, const char *nameptr, data_size_t len,
unsigned int access, unsigned int sharing, int create, unsigned int access, unsigned int sharing, int create,
unsigned int options, unsigned int attrs, unsigned int options, unsigned int attrs,
...@@ -236,8 +242,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si ...@@ -236,8 +242,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
else else
mode = (attrs & FILE_ATTRIBUTE_READONLY) ? 0444 : 0666; mode = (attrs & FILE_ATTRIBUTE_READONLY) ? 0444 : 0666;
if (len >= 4 && if (is_file_executable( name ))
(!strcasecmp( name + len - 4, ".exe" ) || !strcasecmp( name + len - 4, ".com" )))
{ {
if (mode & S_IRUSR) if (mode & S_IRUSR)
mode |= S_IXUSR; mode |= S_IXUSR;
......
...@@ -149,6 +149,7 @@ extern void file_set_error(void); ...@@ -149,6 +149,7 @@ extern void file_set_error(void);
extern struct object_type *file_get_type( struct object *obj ); extern struct object_type *file_get_type( struct object *obj );
extern struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID *group ); extern struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID *group );
extern mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ); extern mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner );
extern int is_file_executable( const char *name );
/* file mapping functions */ /* file mapping functions */
......
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