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
86113530
Commit
86113530
authored
Aug 29, 2000
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added the data structures and macros that will be needed to support
reentrant server requests.
parent
5e7fa021
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
171 additions
and
100 deletions
+171
-100
server.h
include/server.h
+0
-0
thread.h
include/thread.h
+8
-8
client.c
scheduler/client.c
+98
-56
thread.c
scheduler/thread.c
+2
-1
request.c
server/request.c
+20
-27
request.h
server/request.h
+12
-3
thread.c
server/thread.c
+1
-0
thread.h
server/thread.h
+1
-0
trace.c
server/trace.c
+0
-1
make_requests
tools/make_requests
+29
-4
No files found.
include/server.h
View file @
86113530
This diff is collapsed.
Click to expand it.
include/thread.h
View file @
86113530
...
@@ -15,6 +15,7 @@ struct _PDB;
...
@@ -15,6 +15,7 @@ struct _PDB;
struct
__EXCEPTION_FRAME
;
struct
__EXCEPTION_FRAME
;
struct
_SECURITY_ATTRIBUTES
;
struct
_SECURITY_ATTRIBUTES
;
struct
tagSYSLEVEL
;
struct
tagSYSLEVEL
;
struct
server_buffer_info
;
/* Thread exception block
/* Thread exception block
...
@@ -89,17 +90,16 @@ typedef struct _TEB
...
@@ -89,17 +90,16 @@ typedef struct _TEB
DWORD
unknown6
[
5
];
/* --n 1e8 Unknown */
DWORD
unknown6
[
5
];
/* --n 1e8 Unknown */
/* The following are Wine-specific fields (NT: GDI stuff) */
/* The following are Wine-specific fields (NT: GDI stuff) */
struct
_TEB
*
next
;
/* --3 1fc Global thread list */
DWORD
cleanup
;
/* --3 1fc Cleanup service handle */
DWORD
cleanup
;
/* --3 200 Cleanup service handle */
int
socket
;
/* --3 200 Socket for server communication */
int
socket
;
/* --3 204 Socket for server communication */
void
*
buffer
;
/* --3 204 Buffer shared with server */
void
*
buffer
;
/* --3 208 Buffer shared with server */
struct
server_buffer_info
*
buffer_info
;
/* --3 208 Buffer information */
int
buffer_size
;
/* --3 20c Size of server buffer */
void
*
debug_info
;
/* --3 20c Info for debugstr functions */
void
*
debug_info
;
/* --3 210 Info for debugstr functions */
void
*
pthread_data
;
/* --3 210 Data for pthread emulation */
void
*
pthread_data
;
/* --3 214 Data for pthread emulation */
/* here is plenty space for wine specific fields (don't forget to change pad6!!) */
/* here is plenty space for wine specific fields (don't forget to change pad6!!) */
/* the following are nt specific fields */
/* the following are nt specific fields */
DWORD
pad6
[
63
2
];
/* --n 218
*/
DWORD
pad6
[
63
3
];
/* --n 214
*/
UNICODE_STRING
StaticUnicodeString
;
/* -2- bf8 used by advapi32 */
UNICODE_STRING
StaticUnicodeString
;
/* -2- bf8 used by advapi32 */
USHORT
StaticUnicodeBuffer
[
261
];
/* -2- c00 used by advapi32 */
USHORT
StaticUnicodeBuffer
[
261
];
/* -2- c00 used by advapi32 */
DWORD
pad7
;
/* --n e0c */
DWORD
pad7
;
/* --n e0c */
...
...
scheduler/client.c
View file @
86113530
...
@@ -111,21 +111,54 @@ static void server_perror( const char *err )
...
@@ -111,21 +111,54 @@ static void server_perror( const char *err )
/***********************************************************************
/***********************************************************************
* server_exception_handler
*/
DWORD
server_exception_handler
(
PEXCEPTION_RECORD
record
,
EXCEPTION_FRAME
*
frame
,
CONTEXT
*
context
,
EXCEPTION_FRAME
**
pdispatcher
)
{
struct
__server_exception_frame
*
server_frame
=
(
struct
__server_exception_frame
*
)
frame
;
if
((
record
->
ExceptionFlags
&
(
EH_UNWINDING
|
EH_EXIT_UNWIND
)))
*
NtCurrentTeb
()
->
buffer_info
=
server_frame
->
info
;
return
ExceptionContinueSearch
;
}
/***********************************************************************
* server_alloc_req
*/
void
*
server_alloc_req
(
size_t
fixed_size
,
size_t
var_size
)
{
unsigned
int
pos
=
NtCurrentTeb
()
->
buffer_info
->
cur_pos
;
union
generic_request
*
req
=
(
union
generic_request
*
)((
char
*
)
NtCurrentTeb
()
->
buffer
+
pos
);
size_t
size
=
sizeof
(
*
req
)
+
var_size
;
assert
(
fixed_size
<=
sizeof
(
*
req
)
);
if
((
char
*
)
req
+
size
>
(
char
*
)
NtCurrentTeb
()
->
buffer_info
)
server_protocol_error
(
"buffer overflow %d bytes
\n
"
,
(
char
*
)
req
+
size
-
(
char
*
)
NtCurrentTeb
()
->
buffer_info
);
NtCurrentTeb
()
->
buffer_info
->
cur_pos
=
pos
+
size
;
req
->
header
.
fixed_size
=
fixed_size
;
req
->
header
.
var_size
=
var_size
;
return
req
;
}
/***********************************************************************
* send_request
* send_request
*
*
* Send a request to the server.
* Send a request to the server.
*/
*/
static
void
send_request
(
enum
request
req
)
static
void
send_request
(
enum
request
req
,
struct
request_header
*
header
)
{
{
int
ret
;
header
->
req
=
req
;
if
((
ret
=
write
(
NtCurrentTeb
()
->
socket
,
&
req
,
sizeof
(
req
)
))
==
sizeof
(
req
))
NtCurrentTeb
()
->
buffer_info
->
cur_req
=
(
char
*
)
header
-
(
char
*
)
NtCurrentTeb
()
->
buffer
;
return
;
/* write a single byte; the value is ignored anyway */
if
(
ret
==
-
1
)
if
(
write
(
NtCurrentTeb
()
->
socket
,
header
,
1
)
==
-
1
)
{
{
if
(
errno
==
EPIPE
)
SYSDEPS_ExitThread
(
0
);
if
(
errno
==
EPIPE
)
SYSDEPS_ExitThread
(
0
);
server_perror
(
"sendmsg"
);
server_perror
(
"sendmsg"
);
}
}
server_protocol_error
(
"partial msg sent %d/%d
\n
"
,
ret
,
sizeof
(
req
)
);
}
}
/***********************************************************************
/***********************************************************************
...
@@ -133,17 +166,17 @@ static void send_request( enum request req )
...
@@ -133,17 +166,17 @@ static void send_request( enum request req )
*
*
* Send a request to the server, passing a file descriptor.
* Send a request to the server, passing a file descriptor.
*/
*/
static
void
send_request_fd
(
enum
request
req
,
int
fd
)
static
void
send_request_fd
(
enum
request
req
,
struct
request_header
*
header
,
int
fd
)
{
{
int
ret
;
#ifndef HAVE_MSGHDR_ACCRIGHTS
#ifndef HAVE_MSGHDR_ACCRIGHTS
struct
cmsg_fd
cmsg
;
struct
cmsg_fd
cmsg
;
#endif
#endif
struct
msghdr
msghdr
;
struct
msghdr
msghdr
;
struct
iovec
vec
;
struct
iovec
vec
;
vec
.
iov_base
=
(
void
*
)
&
req
;
/* write a single byte; the value is ignored anyway */
vec
.
iov_len
=
sizeof
(
req
);
vec
.
iov_base
=
(
void
*
)
header
;
vec
.
iov_len
=
1
;
msghdr
.
msg_name
=
NULL
;
msghdr
.
msg_name
=
NULL
;
msghdr
.
msg_namelen
=
0
;
msghdr
.
msg_namelen
=
0
;
...
@@ -163,13 +196,13 @@ static void send_request_fd( enum request req, int fd )
...
@@ -163,13 +196,13 @@ static void send_request_fd( enum request req, int fd )
msghdr
.
msg_flags
=
0
;
msghdr
.
msg_flags
=
0
;
#endif
/* HAVE_MSGHDR_ACCRIGHTS */
#endif
/* HAVE_MSGHDR_ACCRIGHTS */
if
((
ret
=
sendmsg
(
NtCurrentTeb
()
->
socket
,
&
msghdr
,
0
))
==
sizeof
(
req
))
return
;
header
->
req
=
req
;
if
(
ret
==
-
1
)
if
(
sendmsg
(
NtCurrentTeb
()
->
socket
,
&
msghdr
,
0
)
==
-
1
)
{
{
if
(
errno
==
EPIPE
)
SYSDEPS_ExitThread
(
0
);
if
(
errno
==
EPIPE
)
SYSDEPS_ExitThread
(
0
);
server_perror
(
"sendmsg"
);
server_perror
(
"sendmsg"
);
}
}
server_protocol_error
(
"partial msg sent %d/%d
\n
"
,
ret
,
sizeof
(
req
)
);
}
}
/***********************************************************************
/***********************************************************************
...
@@ -177,24 +210,19 @@ static void send_request_fd( enum request req, int fd )
...
@@ -177,24 +210,19 @@ static void send_request_fd( enum request req, int fd )
*
*
* Wait for a reply from the server.
* Wait for a reply from the server.
*/
*/
static
unsigned
int
wait_reply
(
void
)
static
void
wait_reply
(
void
)
{
{
int
ret
;
int
ret
;
unsigned
int
res
;
char
dummy
[
1
]
;
for
(;;)
for
(;;)
{
{
if
((
ret
=
read
(
NtCurrentTeb
()
->
socket
,
&
res
,
sizeof
(
res
)
))
==
sizeof
(
res
))
if
((
ret
=
read
(
NtCurrentTeb
()
->
socket
,
dummy
,
1
))
>
0
)
return
;
return
res
;
if
(
!
ret
)
break
;
if
(
!
ret
)
break
;
if
(
ret
==
-
1
)
{
if
(
errno
==
EINTR
)
continue
;
if
(
errno
==
EINTR
)
continue
;
if
(
errno
==
EPIPE
)
break
;
if
(
errno
==
EPIPE
)
break
;
server_perror
(
"read"
);
server_perror
(
"read"
);
}
}
server_protocol_error
(
"partial msg received %d/%d
\n
"
,
ret
,
sizeof
(
res
)
);
}
/* the server closed the connection; time to die... */
/* the server closed the connection; time to die... */
SYSDEPS_ExitThread
(
0
);
SYSDEPS_ExitThread
(
0
);
}
}
...
@@ -205,11 +233,11 @@ static unsigned int wait_reply(void)
...
@@ -205,11 +233,11 @@ static unsigned int wait_reply(void)
*
*
* Wait for a reply from the server, when a file descriptor is passed.
* Wait for a reply from the server, when a file descriptor is passed.
*/
*/
static
unsigned
int
wait_reply_fd
(
int
*
fd
)
static
void
wait_reply_fd
(
int
*
fd
)
{
{
struct
iovec
vec
;
struct
iovec
vec
;
int
ret
;
int
ret
;
unsigned
int
res
;
char
dummy
[
1
]
;
#ifdef HAVE_MSGHDR_ACCRIGHTS
#ifdef HAVE_MSGHDR_ACCRIGHTS
struct
msghdr
msghdr
;
struct
msghdr
msghdr
;
...
@@ -234,27 +262,23 @@ static unsigned int wait_reply_fd( int *fd )
...
@@ -234,27 +262,23 @@ static unsigned int wait_reply_fd( int *fd )
msghdr
.
msg_namelen
=
0
;
msghdr
.
msg_namelen
=
0
;
msghdr
.
msg_iov
=
&
vec
;
msghdr
.
msg_iov
=
&
vec
;
msghdr
.
msg_iovlen
=
1
;
msghdr
.
msg_iovlen
=
1
;
vec
.
iov_base
=
(
void
*
)
&
res
;
vec
.
iov_base
=
(
void
*
)
dummy
;
vec
.
iov_len
=
sizeof
(
res
)
;
vec
.
iov_len
=
1
;
for
(;;)
for
(;;)
{
{
if
((
ret
=
recvmsg
(
NtCurrentTeb
()
->
socket
,
&
msghdr
,
0
))
==
sizeof
(
res
)
)
if
((
ret
=
recvmsg
(
NtCurrentTeb
()
->
socket
,
&
msghdr
,
0
))
>
0
)
{
{
#ifndef HAVE_MSGHDR_ACCRIGHTS
#ifndef HAVE_MSGHDR_ACCRIGHTS
*
fd
=
cmsg
.
fd
;
*
fd
=
cmsg
.
fd
;
#endif
#endif
return
res
;
return
;
}
}
if
(
!
ret
)
break
;
if
(
!
ret
)
break
;
if
(
ret
==
-
1
)
{
if
(
errno
==
EINTR
)
continue
;
if
(
errno
==
EINTR
)
continue
;
if
(
errno
==
EPIPE
)
break
;
if
(
errno
==
EPIPE
)
break
;
server_perror
(
"recvmsg"
);
server_perror
(
"recvmsg"
);
}
}
server_protocol_error
(
"partial seq received %d/%d
\n
"
,
ret
,
sizeof
(
res
)
);
}
/* the server closed the connection; time to die... */
/* the server closed the connection; time to die... */
SYSDEPS_ExitThread
(
0
);
SYSDEPS_ExitThread
(
0
);
}
}
...
@@ -267,8 +291,10 @@ static unsigned int wait_reply_fd( int *fd )
...
@@ -267,8 +291,10 @@ static unsigned int wait_reply_fd( int *fd )
*/
*/
unsigned
int
server_call_noerr
(
enum
request
req
)
unsigned
int
server_call_noerr
(
enum
request
req
)
{
{
send_request
(
req
);
void
*
req_ptr
=
get_req_buffer
();
return
wait_reply
();
send_request
(
req
,
req_ptr
);
wait_reply
();
return
((
struct
request_header
*
)
req_ptr
)
->
error
;
}
}
...
@@ -282,13 +308,16 @@ unsigned int server_call_noerr( enum request req )
...
@@ -282,13 +308,16 @@ unsigned int server_call_noerr( enum request req )
unsigned
int
server_call_fd
(
enum
request
req
,
int
fd_out
,
int
*
fd_in
)
unsigned
int
server_call_fd
(
enum
request
req
,
int
fd_out
,
int
*
fd_in
)
{
{
unsigned
int
res
;
unsigned
int
res
;
void
*
req_ptr
=
get_req_buffer
();
if
(
fd_out
==
-
1
)
send_request
(
req
,
req_ptr
);
else
send_request_fd
(
req
,
req_ptr
,
fd_out
);
if
(
fd_
out
==
-
1
)
send_request
(
req
);
if
(
fd_
in
)
wait_reply_fd
(
fd_in
);
else
send_request_fd
(
req
,
fd_out
);
else
wait_reply
(
);
if
(
fd_in
)
res
=
wait_reply_fd
(
fd_in
);
if
((
res
=
((
struct
request_header
*
)
req_ptr
)
->
error
))
else
res
=
wait_reply
();
SetLastError
(
RtlNtStatusToDosError
(
res
)
);
if
(
res
)
SetLastError
(
RtlNtStatusToDosError
(
res
)
);
return
res
;
/* error code */
return
res
;
/* error code */
}
}
...
@@ -517,37 +546,44 @@ int CLIENT_InitServer(void)
...
@@ -517,37 +546,44 @@ int CLIENT_InitServer(void)
*/
*/
int
CLIENT_InitThread
(
void
)
int
CLIENT_InitThread
(
void
)
{
{
struct
get_thread_buffer_request
*
first_req
;
struct
get_thread_buffer_request
*
req
;
struct
init_thread_request
*
req
;
TEB
*
teb
=
NtCurrentTeb
();
TEB
*
teb
=
NtCurrentTeb
();
int
fd
;
int
fd
,
ret
,
size
;
/* ignore SIGPIPE so that we get a EPIPE error instead */
/* ignore SIGPIPE so that we get a EPIPE error instead */
signal
(
SIGPIPE
,
SIG_IGN
);
signal
(
SIGPIPE
,
SIG_IGN
);
if
(
wait_reply_fd
(
&
fd
)
||
(
fd
==
-
1
))
wait_reply_fd
(
&
fd
);
server_protocol_error
(
"no fd passed on first request
\n
"
);
if
(
fd
==
-
1
)
server_protocol_error
(
"no fd passed on first request
\n
"
);
if
((
teb
->
buffer_size
=
lseek
(
fd
,
0
,
SEEK_END
))
==
-
1
)
server_perror
(
"lseek"
);
teb
->
buffer
=
mmap
(
0
,
teb
->
buffer_size
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
fd
,
0
);
if
((
size
=
lseek
(
fd
,
0
,
SEEK_END
))
==
-
1
)
server_perror
(
"lseek"
);
teb
->
buffer
=
mmap
(
0
,
size
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
fd
,
0
);
close
(
fd
);
close
(
fd
);
if
(
teb
->
buffer
==
(
void
*
)
-
1
)
server_perror
(
"mmap"
);
if
(
teb
->
buffer
==
(
void
*
)
-
1
)
server_perror
(
"mmap"
);
first_req
=
teb
->
buffer
;
teb
->
buffer_info
=
(
struct
server_buffer_info
*
)((
char
*
)
teb
->
buffer
+
size
)
-
1
;
teb
->
pid
=
first_req
->
pid
;
teb
->
tid
=
first_req
->
tid
;
req
=
(
struct
get_thread_buffer_request
*
)
teb
->
buffer
;
if
(
first_req
->
version
!=
SERVER_PROTOCOL_VERSION
)
teb
->
pid
=
req
->
pid
;
teb
->
tid
=
req
->
tid
;
if
(
req
->
version
!=
SERVER_PROTOCOL_VERSION
)
server_protocol_error
(
"version mismatch %d/%d.
\n
"
server_protocol_error
(
"version mismatch %d/%d.
\n
"
"Your %s binary was not upgraded correctly,
\n
"
"Your %s binary was not upgraded correctly,
\n
"
"or you have an older one somewhere in your PATH.
\n
"
,
"or you have an older one somewhere in your PATH.
\n
"
,
first_
req
->
version
,
SERVER_PROTOCOL_VERSION
,
req
->
version
,
SERVER_PROTOCOL_VERSION
,
(
first_
req
->
version
>
SERVER_PROTOCOL_VERSION
)
?
"wine"
:
"wineserver"
);
(
req
->
version
>
SERVER_PROTOCOL_VERSION
)
?
"wine"
:
"wineserver"
);
if
(
first_
req
->
boot
)
boot_thread_id
=
teb
->
tid
;
if
(
req
->
boot
)
boot_thread_id
=
teb
->
tid
;
else
if
(
boot_thread_id
==
teb
->
tid
)
boot_thread_id
=
0
;
else
if
(
boot_thread_id
==
teb
->
tid
)
boot_thread_id
=
0
;
req
=
teb
->
buffer
;
SERVER_START_REQ
{
struct
init_thread_request
*
req
=
server_alloc_req
(
sizeof
(
*
req
),
0
);
req
->
unix_pid
=
getpid
();
req
->
unix_pid
=
getpid
();
req
->
teb
=
teb
;
req
->
teb
=
teb
;
req
->
entry
=
teb
->
entry_point
;
req
->
entry
=
teb
->
entry_point
;
return
server_call_noerr
(
REQ_INIT_THREAD
);
ret
=
server_call_noerr
(
REQ_INIT_THREAD
);
}
SERVER_END_REQ
;
return
ret
;
}
}
/***********************************************************************
/***********************************************************************
...
@@ -557,9 +593,15 @@ int CLIENT_InitThread(void)
...
@@ -557,9 +593,15 @@ int CLIENT_InitThread(void)
*/
*/
int
CLIENT_BootDone
(
int
debug_level
)
int
CLIENT_BootDone
(
int
debug_level
)
{
{
struct
boot_done_request
*
req
=
get_req_buffer
();
int
ret
;
SERVER_START_REQ
{
struct
boot_done_request
*
req
=
server_alloc_req
(
sizeof
(
*
req
),
0
);
req
->
debug_level
=
debug_level
;
req
->
debug_level
=
debug_level
;
return
server_call
(
REQ_BOOT_DONE
);
ret
=
server_call
(
REQ_BOOT_DONE
);
}
SERVER_END_REQ
;
return
ret
;
}
}
...
...
scheduler/thread.c
View file @
86113530
...
@@ -105,7 +105,8 @@ static void CALLBACK THREAD_FreeTEB( TEB *teb )
...
@@ -105,7 +105,8 @@ static void CALLBACK THREAD_FreeTEB( TEB *teb )
if
(
teb
->
socket
!=
-
1
)
close
(
teb
->
socket
);
if
(
teb
->
socket
!=
-
1
)
close
(
teb
->
socket
);
if
(
teb
->
stack_sel
)
SELECTOR_FreeBlock
(
teb
->
stack_sel
,
1
);
if
(
teb
->
stack_sel
)
SELECTOR_FreeBlock
(
teb
->
stack_sel
,
1
);
SELECTOR_FreeBlock
(
teb
->
teb_sel
,
1
);
SELECTOR_FreeBlock
(
teb
->
teb_sel
,
1
);
if
(
teb
->
buffer
)
munmap
(
teb
->
buffer
,
teb
->
buffer_size
);
if
(
teb
->
buffer
)
munmap
(
(
void
*
)
teb
->
buffer
,
(
char
*
)(
teb
->
buffer_info
+
1
)
-
(
char
*
)
teb
->
buffer
);
if
(
teb
->
debug_info
)
HeapFree
(
GetProcessHeap
(),
0
,
teb
->
debug_info
);
if
(
teb
->
debug_info
)
HeapFree
(
GetProcessHeap
(),
0
,
teb
->
debug_info
);
VirtualFree
(
teb
->
stack_base
,
0
,
MEM_RELEASE
);
VirtualFree
(
teb
->
stack_base
,
0
,
MEM_RELEASE
);
}
}
...
...
server/request.c
View file @
86113530
...
@@ -129,11 +129,14 @@ void fatal_perror( const char *err, ... )
...
@@ -129,11 +129,14 @@ void fatal_perror( const char *err, ... )
}
}
/* call a request handler */
/* call a request handler */
static
inline
void
call_req_handler
(
struct
thread
*
thread
,
enum
request
req
)
static
inline
void
call_req_handler
(
struct
thread
*
thread
)
{
{
enum
request
req
;
current
=
thread
;
current
=
thread
;
clear_error
();
clear_error
();
req
=
((
struct
request_header
*
)
current
->
buffer
)
->
req
;
if
(
debug_level
)
trace_request
(
req
);
if
(
debug_level
)
trace_request
(
req
);
if
(
req
<
REQ_NB_REQUESTS
)
if
(
req
<
REQ_NB_REQUESTS
)
...
@@ -165,7 +168,7 @@ void send_reply( struct thread *thread )
...
@@ -165,7 +168,7 @@ void send_reply( struct thread *thread )
void
read_request
(
struct
thread
*
thread
)
void
read_request
(
struct
thread
*
thread
)
{
{
int
ret
;
int
ret
;
enum
request
req
;
char
dummy
[
1
]
;
#ifdef HAVE_MSGHDR_ACCRIGHTS
#ifdef HAVE_MSGHDR_ACCRIGHTS
msghdr
.
msg_accrightslen
=
sizeof
(
int
);
msghdr
.
msg_accrightslen
=
sizeof
(
int
);
...
@@ -178,43 +181,42 @@ void read_request( struct thread *thread )
...
@@ -178,43 +181,42 @@ void read_request( struct thread *thread )
assert
(
thread
->
pass_fd
==
-
1
);
assert
(
thread
->
pass_fd
==
-
1
);
myiovec
.
iov_base
=
(
void
*
)
&
req
;
myiovec
.
iov_base
=
dummy
;
myiovec
.
iov_len
=
sizeof
(
req
)
;
myiovec
.
iov_len
=
1
;
ret
=
recvmsg
(
thread
->
obj
.
fd
,
&
msghdr
,
0
);
ret
=
recvmsg
(
thread
->
obj
.
fd
,
&
msghdr
,
0
);
#ifndef HAVE_MSGHDR_ACCRIGHTS
#ifndef HAVE_MSGHDR_ACCRIGHTS
thread
->
pass_fd
=
cmsg
.
fd
;
thread
->
pass_fd
=
cmsg
.
fd
;
#endif
#endif
if
(
ret
==
sizeof
(
req
)
)
if
(
ret
>
0
)
{
{
call_req_handler
(
thread
,
req
);
call_req_handler
(
thread
);
thread
->
pass_fd
=
-
1
;
thread
->
pass_fd
=
-
1
;
return
;
return
;
}
}
if
(
ret
==
-
1
)
{
perror
(
"recvmsg"
);
thread
->
exit_code
=
1
;
kill_thread
(
thread
,
1
);
return
;
}
if
(
!
ret
)
/* closed pipe */
if
(
!
ret
)
/* closed pipe */
{
{
kill_thread
(
thread
,
0
);
kill_thread
(
thread
,
0
);
return
;
return
;
}
}
fatal_protocol_error
(
thread
,
"partial message received %d/%d
\n
"
,
ret
,
sizeof
(
req
)
);
perror
(
"recvmsg"
);
thread
->
exit_code
=
1
;
kill_thread
(
thread
,
1
);
}
}
/* send a message to a client that is ready to receive something */
/* send a message to a client that is ready to receive something */
int
write_request
(
struct
thread
*
thread
)
int
write_request
(
struct
thread
*
thread
)
{
{
int
ret
;
int
ret
;
struct
request_header
*
header
=
thread
->
buffer
;
header
->
error
=
thread
->
error
;
if
(
thread
->
pass_fd
==
-
1
)
if
(
thread
->
pass_fd
==
-
1
)
{
{
ret
=
write
(
thread
->
obj
.
fd
,
&
thread
->
error
,
sizeof
(
thread
->
error
)
);
/* write a single byte; the value is ignored anyway */
ret
=
write
(
thread
->
obj
.
fd
,
header
,
1
);
}
}
else
/* we have an fd to send */
else
/* we have an fd to send */
{
{
...
@@ -227,20 +229,18 @@ int write_request( struct thread *thread )
...
@@ -227,20 +229,18 @@ int write_request( struct thread *thread )
cmsg
.
fd
=
thread
->
pass_fd
;
cmsg
.
fd
=
thread
->
pass_fd
;
#endif
/* HAVE_MSGHDR_ACCRIGHTS */
#endif
/* HAVE_MSGHDR_ACCRIGHTS */
myiovec
.
iov_base
=
(
void
*
)
&
thread
->
erro
r
;
myiovec
.
iov_base
=
(
void
*
)
heade
r
;
myiovec
.
iov_len
=
sizeof
(
thread
->
error
)
;
myiovec
.
iov_len
=
1
;
ret
=
sendmsg
(
thread
->
obj
.
fd
,
&
msghdr
,
0
);
ret
=
sendmsg
(
thread
->
obj
.
fd
,
&
msghdr
,
0
);
close
(
thread
->
pass_fd
);
close
(
thread
->
pass_fd
);
thread
->
pass_fd
=
-
1
;
thread
->
pass_fd
=
-
1
;
}
}
if
(
ret
==
sizeof
(
thread
->
error
)
)
if
(
ret
>
0
)
{
{
set_select_events
(
&
thread
->
obj
,
POLLIN
);
set_select_events
(
&
thread
->
obj
,
POLLIN
);
return
1
;
return
1
;
}
}
if
(
ret
==
-
1
)
{
if
(
errno
==
EWOULDBLOCK
)
return
0
;
/* not a fatal error */
if
(
errno
==
EWOULDBLOCK
)
return
0
;
/* not a fatal error */
if
(
errno
==
EPIPE
)
if
(
errno
==
EPIPE
)
{
{
...
@@ -252,13 +252,6 @@ int write_request( struct thread *thread )
...
@@ -252,13 +252,6 @@ int write_request( struct thread *thread )
thread
->
exit_code
=
1
;
thread
->
exit_code
=
1
;
kill_thread
(
thread
,
1
);
kill_thread
(
thread
,
1
);
}
}
}
else
{
thread
->
exit_code
=
1
;
kill_thread
(
thread
,
1
);
fprintf
(
stderr
,
"Partial message sent %d/%d
\n
"
,
ret
,
sizeof
(
thread
->
error
)
);
}
return
-
1
;
return
-
1
;
}
}
...
...
server/request.h
View file @
86113530
...
@@ -48,17 +48,26 @@ static inline void *get_req_ptr( struct thread *thread )
...
@@ -48,17 +48,26 @@ static inline void *get_req_ptr( struct thread *thread )
return
thread
->
buffer
;
return
thread
->
buffer
;
}
}
/* get the request vararg data */
inline
static
void
*
get_req_data
(
const
void
*
req
)
{
return
((
union
generic_request
*
)
req
+
1
);
}
#define REQUEST_END(req) ((char *)(req) + MAX_REQUEST_LENGTH - sizeof(struct server_buffer_info))
/* get the remaining size in the request buffer for object of a given size */
/* get the remaining size in the request buffer for object of a given size */
static
inline
int
get_req_size
(
const
void
*
req
,
const
void
*
ptr
,
size_t
typesize
)
static
inline
int
get_req_size
(
const
void
*
req
,
const
void
*
ptr
,
size_t
typesize
)
{
{
return
(
(
char
*
)
req
+
MAX_REQUEST_LENGTH
-
(
char
*
)
ptr
)
/
typesize
;
return
(
REQUEST_END
(
req
)
-
(
char
*
)
ptr
)
/
typesize
;
}
}
/* get the length of a request string, without going past the end of the request */
/* get the length of a request string, without going past the end of the request */
static
inline
size_t
get_req_strlen
(
const
void
*
req
,
const
char
*
str
)
static
inline
size_t
get_req_strlen
(
const
void
*
req
,
const
char
*
str
)
{
{
const
char
*
p
=
str
;
const
char
*
p
=
str
;
while
(
*
p
&&
(
p
<
(
char
*
)
req
+
MAX_REQUEST_LENGTH
-
1
))
p
++
;
while
(
*
p
&&
(
p
<
REQUEST_END
(
req
)
-
1
))
p
++
;
return
p
-
str
;
return
p
-
str
;
}
}
...
@@ -66,7 +75,7 @@ static inline size_t get_req_strlen( const void *req, const char *str )
...
@@ -66,7 +75,7 @@ static inline size_t get_req_strlen( const void *req, const char *str )
static
inline
size_t
get_req_strlenW
(
const
void
*
req
,
const
WCHAR
*
str
)
static
inline
size_t
get_req_strlenW
(
const
void
*
req
,
const
WCHAR
*
str
)
{
{
const
WCHAR
*
p
=
str
;
const
WCHAR
*
p
=
str
;
while
(
*
p
&&
(
p
<
(
WCHAR
*
)
req
+
MAX_REQUEST_LENGTH
/
sizeof
(
WCHAR
)
-
1
))
p
++
;
while
(
*
p
&&
(
p
<
(
WCHAR
*
)
REQUEST_END
(
req
)
-
1
))
p
++
;
return
p
-
str
;
return
p
-
str
;
}
}
...
...
server/thread.c
View file @
86113530
...
@@ -96,6 +96,7 @@ static int alloc_client_buffer( struct thread *thread )
...
@@ -96,6 +96,7 @@ static int alloc_client_buffer( struct thread *thread )
if
(
ftruncate
(
fd
,
MAX_REQUEST_LENGTH
)
==
-
1
)
goto
error
;
if
(
ftruncate
(
fd
,
MAX_REQUEST_LENGTH
)
==
-
1
)
goto
error
;
if
((
thread
->
buffer
=
mmap
(
0
,
MAX_REQUEST_LENGTH
,
PROT_READ
|
PROT_WRITE
,
if
((
thread
->
buffer
=
mmap
(
0
,
MAX_REQUEST_LENGTH
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
fd
,
0
))
==
(
void
*
)
-
1
)
goto
error
;
MAP_SHARED
,
fd
,
0
))
==
(
void
*
)
-
1
)
goto
error
;
thread
->
buffer_info
=
(
struct
server_buffer_info
*
)((
char
*
)
thread
->
buffer
+
MAX_REQUEST_LENGTH
)
-
1
;
/* build the first request into the buffer and send it */
/* build the first request into the buffer and send it */
req
=
thread
->
buffer
;
req
=
thread
->
buffer
;
req
->
pid
=
get_process_id
(
thread
->
process
);
req
->
pid
=
get_process_id
(
thread
->
process
);
...
...
server/thread.h
View file @
86113530
...
@@ -59,6 +59,7 @@ struct thread
...
@@ -59,6 +59,7 @@ struct thread
int
affinity
;
/* affinity mask */
int
affinity
;
/* affinity mask */
int
suspend
;
/* suspend count */
int
suspend
;
/* suspend count */
void
*
buffer
;
/* buffer for communication with the client */
void
*
buffer
;
/* buffer for communication with the client */
struct
server_buffer_info
*
buffer_info
;
/* buffer information structure */
enum
request
last_req
;
/* last request received (for debugging) */
enum
request
last_req
;
/* last request received (for debugging) */
};
};
...
...
server/trace.c
View file @
86113530
...
@@ -787,7 +787,6 @@ static void dump_alloc_console_reply( const struct alloc_console_request *req )
...
@@ -787,7 +787,6 @@ static void dump_alloc_console_reply( const struct alloc_console_request *req )
static
void
dump_free_console_request
(
const
struct
free_console_request
*
req
)
static
void
dump_free_console_request
(
const
struct
free_console_request
*
req
)
{
{
fprintf
(
stderr
,
" dummy=%d"
,
req
->
dummy
);
}
}
static
void
dump_open_console_request
(
const
struct
open_console_request
*
req
)
static
void
dump_open_console_request
(
const
struct
open_console_request
*
req
)
...
...
tools/make_requests
View file @
86113530
...
@@ -9,7 +9,6 @@
...
@@ -9,7 +9,6 @@
%
formats
=
%
formats
=
(
(
"int"
=>
"%d"
,
"int"
=>
"%d"
,
"long"
=>
"%ld"
,
"char"
=>
"%c"
,
"char"
=>
"%c"
,
"unsigned char"
=>
"%02x"
,
"unsigned char"
=>
"%02x"
,
"unsigned int"
=>
"%08x"
,
"unsigned int"
=>
"%08x"
,
...
@@ -70,8 +69,13 @@ my @server_lines = ();
...
@@ -70,8 +69,13 @@ my @server_lines = ();
push
@server_lines
,
"enum request\n{\n"
;
push
@server_lines
,
"enum request\n{\n"
;
foreach
$req
(
@requests
)
{
push
@server_lines
,
" REQ_\U$req,\n"
;
}
foreach
$req
(
@requests
)
{
push
@server_lines
,
" REQ_\U$req,\n"
;
}
push
@server_lines
,
" REQ_NB_REQUESTS\n};\n"
;
push
@server_lines
,
" REQ_NB_REQUESTS\n};\n\n"
;
push
@server_lines
,
"\n#define SERVER_PROTOCOL_VERSION $protocol\n"
;
push
@server_lines
,
"union generic_request\n{\n"
;
push
@server_lines
,
" struct request_max_size max_size;\n"
;
push
@server_lines
,
" struct request_header header;\n"
;
foreach
$req
(
@requests
)
{
push
@server_lines
,
" struct ${req}_request $req;\n"
;
}
push
@server_lines
,
"};\n\n"
;
push
@server_lines
,
"#define SERVER_PROTOCOL_VERSION $protocol\n"
;
REPLACE_IN_FILE
(
"include/server.h"
,
@server_lines
);
REPLACE_IN_FILE
(
"include/server.h"
,
@server_lines
);
...
@@ -98,6 +102,7 @@ sub DO_REQUEST
...
@@ -98,6 +102,7 @@ sub DO_REQUEST
my
$name
=
shift
;
my
$name
=
shift
;
my
@in_struct
=
();
my
@in_struct
=
();
my
@out_struct
=
();
my
@out_struct
=
();
my
$got_header
=
0
;
while
(
<
SERVER
>
)
while
(
<
SERVER
>
)
{
{
my
(
$dir
,
$type
,
$var
);
my
(
$dir
,
$type
,
$var
);
...
@@ -105,14 +110,34 @@ sub DO_REQUEST
...
@@ -105,14 +110,34 @@ sub DO_REQUEST
next
if
/^{$/
;
next
if
/^{$/
;
s!/\*.*\*/!!g
;
s!/\*.*\*/!!g
;
next
if
/^\s*$/
;
next
if
/^\s*$/
;
/^\s*(IN|OUT)\s*(\w+\**(\s+\w+\**)*)\s+(\w+)(\[[1]\])?;/
or
die
"Unrecognized syntax $_"
;
if
(
/REQUEST_HEADER/
)
{
die
"Duplicated header"
if
$got_header
;
die
"Header must be first"
if
(
$#in_struct
!=
-
1
||
$#out_struct
!=
-
1
);
$got_header
++
;
next
;
}
if
(
/^\s*(IN|OUT)\s*VARARG\((\w+),(\w+)\)/
)
{
$dir
=
$1
;
$var
=
$2
;
$type
=
"&"
.
$3
;
}
elsif
(
/^\s*(IN|OUT)\s*(\w+\**(\s+\w+\**)*)\s+(\w+)(\[[1]\])?;/
)
{
$dir
=
$1
;
$dir
=
$1
;
$type
=
$2
.
(
$5
||
""
);
$type
=
$2
.
(
$5
||
""
);
$var
=
$4
;
$var
=
$4
;
die
"Unrecognized type $type"
unless
(
defined
(
$formats
{
$type
})
||
$5
);
die
"Unrecognized type $type"
unless
(
defined
(
$formats
{
$type
})
||
$5
);
}
else
{
die
"Unrecognized syntax $_"
;
}
if
(
$dir
=~
/IN/
)
{
push
@in_struct
,
$type
,
$var
;
}
if
(
$dir
=~
/IN/
)
{
push
@in_struct
,
$type
,
$var
;
}
if
(
$dir
=~
/OUT/
)
{
push
@out_struct
,
$type
,
$var
;
}
if
(
$dir
=~
/OUT/
)
{
push
@out_struct
,
$type
,
$var
;
}
}
}
die
"Missing header"
unless
$got_header
;
push
@requests
,
$name
;
push
@requests
,
$name
;
&
DO_DUMP_FUNC
(
$name
,
"request"
,
@in_struct
);
&
DO_DUMP_FUNC
(
$name
,
"request"
,
@in_struct
);
if
(
$#out_struct
>=
0
)
if
(
$#out_struct
>=
0
)
...
...
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