Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
a2813f7c
Commit
a2813f7c
authored
Feb 20, 2006
by
Mike McCormack
Committed by
Alexandre Julliard
Feb 20, 2006
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Distinguish between a directory and a file changing in
ReadDirectoryChangesW. Add a test for it.
parent
88aa6703
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
136 additions
and
11 deletions
+136
-11
change.c
dlls/kernel/tests/change.c
+80
-0
change.c
server/change.c
+56
-11
No files found.
dlls/kernel/tests/change.c
View file @
a2813f7c
...
...
@@ -560,6 +560,85 @@ static void test_readdirectorychanges_null(void)
ok
(
r
==
TRUE
,
"failed to remove directory
\n
"
);
}
static
void
test_readdirectorychanges_filedir
(
void
)
{
NTSTATUS
r
;
HANDLE
hdir
,
hfile
;
char
buffer
[
0x1000
];
DWORD
fflags
,
filter
=
0
;
OVERLAPPED
ov
;
WCHAR
path
[
MAX_PATH
],
subdir
[
MAX_PATH
],
file
[
MAX_PATH
];
static
const
WCHAR
szBoo
[]
=
{
'\\'
,
'b'
,
'o'
,
'o'
,
0
};
static
const
WCHAR
szHoo
[]
=
{
'\\'
,
'h'
,
'o'
,
'o'
,
0
};
static
const
WCHAR
szFoo
[]
=
{
'\\'
,
'f'
,
'o'
,
'o'
,
0
};
PFILE_NOTIFY_INFORMATION
pfni
;
r
=
GetTempPathW
(
MAX_PATH
,
path
);
ok
(
r
!=
0
,
"temp path failed
\n
"
);
if
(
!
r
)
return
;
lstrcatW
(
path
,
szBoo
);
lstrcpyW
(
subdir
,
path
);
lstrcatW
(
subdir
,
szHoo
);
lstrcpyW
(
file
,
path
);
lstrcatW
(
file
,
szFoo
);
DeleteFileW
(
file
);
RemoveDirectoryW
(
subdir
);
RemoveDirectoryW
(
path
);
r
=
CreateDirectoryW
(
path
,
NULL
);
ok
(
r
==
TRUE
,
"failed to create directory
\n
"
);
fflags
=
FILE_FLAG_BACKUP_SEMANTICS
|
FILE_FLAG_OVERLAPPED
;
hdir
=
CreateFileW
(
path
,
GENERIC_READ
|
SYNCHRONIZE
|
FILE_LIST_DIRECTORY
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
OPEN_EXISTING
,
fflags
,
NULL
);
ok
(
hdir
!=
INVALID_HANDLE_VALUE
,
"failed to open directory
\n
"
);
ov
.
hEvent
=
CreateEvent
(
NULL
,
0
,
0
,
NULL
);
filter
=
FILE_NOTIFY_CHANGE_FILE_NAME
;
r
=
pReadDirectoryChangesW
(
hdir
,
buffer
,
sizeof
buffer
,
TRUE
,
filter
,
NULL
,
&
ov
,
NULL
);
ok
(
r
==
TRUE
,
"should return true
\n
"
);
r
=
WaitForSingleObject
(
ov
.
hEvent
,
10
);
ok
(
r
==
WAIT_TIMEOUT
,
"should timeout
\n
"
);
r
=
CreateDirectoryW
(
subdir
,
NULL
);
ok
(
r
==
TRUE
,
"failed to create directory
\n
"
);
hfile
=
CreateFileW
(
file
,
GENERIC_READ
|
GENERIC_WRITE
,
0
,
NULL
,
CREATE_ALWAYS
,
0
,
NULL
);
ok
(
hfile
!=
INVALID_HANDLE_VALUE
,
"failed to create file
\n
"
);
ok
(
CloseHandle
(
hfile
),
"failed toc lose file
\n
"
);
r
=
WaitForSingleObject
(
ov
.
hEvent
,
INFINITE
);
ok
(
r
==
WAIT_OBJECT_0
,
"event should be ready
\n
"
);
ok
(
ov
.
Internal
==
STATUS_SUCCESS
,
"ov.Internal wrong
\n
"
);
ok
(
ov
.
InternalHigh
==
0x12
,
"ov.InternalHigh wrong
\n
"
);
pfni
=
(
PFILE_NOTIFY_INFORMATION
)
buffer
;
ok
(
pfni
->
NextEntryOffset
==
0
,
"offset wrong
\n
"
);
ok
(
pfni
->
Action
==
FILE_ACTION_ADDED
,
"action wrong
\n
"
);
ok
(
pfni
->
FileNameLength
==
6
,
"len wrong
\n
"
);
ok
(
!
memcmp
(
pfni
->
FileName
,
&
szFoo
[
1
],
6
),
"name wrong
\n
"
);
r
=
DeleteFileW
(
file
);
ok
(
r
==
TRUE
,
"failed to delete file
\n
"
);
r
=
RemoveDirectoryW
(
subdir
);
ok
(
r
==
TRUE
,
"failed to remove directory
\n
"
);
CloseHandle
(
hdir
);
r
=
RemoveDirectoryW
(
path
);
ok
(
r
==
TRUE
,
"failed to remove directory
\n
"
);
}
START_TEST
(
change
)
{
HMODULE
hkernel32
=
GetModuleHandle
(
"kernel32"
);
...
...
@@ -570,4 +649,5 @@ START_TEST(change)
test_ffcn
();
test_readdirectorychanges
();
test_readdirectorychanges_null
();
test_readdirectorychanges_filedir
();
}
server/change.c
View file @
a2813f7c
...
...
@@ -485,24 +485,20 @@ static int inotify_get_poll_events( struct fd *fd )
return
POLLIN
;
}
static
void
inotify_do_change_notify
(
struct
dir
*
dir
,
struct
inotify_event
*
ie
)
static
void
inotify_do_change_notify
(
struct
dir
*
dir
,
unsigned
int
action
,
const
char
*
relpath
)
{
struct
change_record
*
record
;
if
(
dir
->
want_data
)
{
size_t
len
=
strlen
(
ie
->
name
);
size_t
len
=
strlen
(
relpath
);
record
=
malloc
(
offsetof
(
struct
change_record
,
name
[
len
])
);
if
(
!
record
)
return
;
if
(
ie
->
mask
&
IN_CREATE
)
record
->
action
=
FILE_ACTION_ADDED
;
else
if
(
ie
->
mask
&
IN_DELETE
)
record
->
action
=
FILE_ACTION_REMOVED
;
else
record
->
action
=
FILE_ACTION_MODIFIED
;
memcpy
(
record
->
name
,
ie
->
name
,
len
);
record
->
action
=
action
;
memcpy
(
record
->
name
,
relpath
,
len
);
record
->
len
=
len
;
list_add_tail
(
&
dir
->
change_records
,
&
record
->
entry
);
...
...
@@ -535,11 +531,39 @@ static unsigned int filter_from_event( struct inotify_event *ie )
return
filter
;
}
static
int
inode_entry_is_dir
(
struct
inode
*
inode
,
const
char
*
name
)
{
/* distinguish a created file from a directory */
char
*
path
;
struct
list
*
head
;
struct
stat
st
;
int
unix_fd
,
r
;
head
=
list_head
(
&
inode
->
dirs
);
if
(
!
head
)
return
-
1
;
path
=
malloc
(
strlen
(
name
)
+
32
);
if
(
!
path
)
return
-
1
;
unix_fd
=
get_unix_fd
(
LIST_ENTRY
(
head
,
struct
dir
,
in_entry
)
->
fd
);
sprintf
(
path
,
"/proc/self/fd/%u/%s"
,
unix_fd
,
name
);
r
=
stat
(
path
,
&
st
);
free
(
path
);
if
(
-
1
==
r
)
return
-
1
;
if
(
S_ISDIR
(
st
.
st_mode
))
return
1
;
return
0
;
}
static
void
inotify_notify_all
(
struct
inotify_event
*
ie
)
{
unsigned
int
filter
,
action
;
struct
inode
*
inode
;
struct
dir
*
dir
;
unsigned
int
filter
;
inode
=
inode_from_wd
(
ie
->
wd
);
if
(
!
inode
)
...
...
@@ -549,10 +573,31 @@ static void inotify_notify_all( struct inotify_event *ie )
}
filter
=
filter_from_event
(
ie
);
if
(
ie
->
mask
&
IN_CREATE
)
{
switch
(
inode_entry_is_dir
(
inode
,
ie
->
name
))
{
case
1
:
filter
&=
~
FILE_NOTIFY_CHANGE_FILE_NAME
;
break
;
case
0
:
filter
&=
~
FILE_NOTIFY_CHANGE_DIR_NAME
;
break
;
default:
break
;
/* Maybe the file disappeared before we could check it? */
}
action
=
FILE_ACTION_ADDED
;
}
else
if
(
ie
->
mask
&
IN_DELETE
)
action
=
FILE_ACTION_REMOVED
;
else
action
=
FILE_ACTION_MODIFIED
;
LIST_FOR_EACH_ENTRY
(
dir
,
&
inode
->
dirs
,
struct
dir
,
in_entry
)
if
(
filter
&
dir
->
filter
)
inotify_do_change_notify
(
dir
,
i
e
);
inotify_do_change_notify
(
dir
,
action
,
ie
->
nam
e
);
}
static
void
inotify_poll_event
(
struct
fd
*
fd
,
int
event
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment