Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
aa0ebd0f
Commit
aa0ebd0f
authored
Dec 30, 1998
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added several file server requests
Added server-side pipes and consoles
parent
338e757d
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
885 additions
and
35 deletions
+885
-35
server.h
include/server.h
+76
-0
object.h
include/server/object.h
+26
-0
request.h
include/server/request.h
+24
-0
Makefile.in
server/Makefile.in
+2
-0
console.c
server/console.c
+196
-0
event.c
server/event.c
+3
-0
file.c
server/file.c
+115
-21
mutex.c
server/mutex.c
+3
-0
object.c
server/object.c
+32
-0
pipe.c
server/pipe.c
+185
-0
process.c
server/process.c
+4
-7
request.c
server/request.c
+116
-0
semaphore.c
server/semaphore.c
+3
-0
thread.c
server/thread.c
+4
-7
trace.c
server/trace.c
+96
-0
No files found.
include/server.h
View file @
aa0ebd0f
...
...
@@ -268,6 +268,50 @@ struct get_unix_handle_request
};
/* Get a Unix fd to read from a file */
struct
get_read_fd_request
{
int
handle
;
/* handle to the file */
};
/* Get a Unix fd to write to a file */
struct
get_write_fd_request
{
int
handle
;
/* handle to the file */
};
/* Set a file current position */
struct
set_file_pointer_request
{
int
handle
;
/* handle to the file */
int
low
;
/* position low word */
int
high
;
/* position high word */
int
whence
;
/* whence to seek */
};
struct
set_file_pointer_reply
{
int
low
;
/* new position low word */
int
high
;
/* new position high word */
};
/* Truncate (or extend) a file */
struct
truncate_file_request
{
int
handle
;
/* handle to the file */
};
/* Flush a file buffers */
struct
flush_file_request
{
int
handle
;
/* handle to the file */
};
/* Get information about a file */
struct
get_file_info_request
{
int
handle
;
/* handle to the file */
...
...
@@ -285,6 +329,38 @@ struct get_file_info_reply
unsigned
int
serial
;
/* volume serial number */
};
/* Create an anonymous pipe */
struct
create_pipe_request
{
int
inherit
;
/* inherit flag */
};
struct
create_pipe_reply
{
int
handle_read
;
/* handle to the read-side of the pipe */
int
handle_write
;
/* handle to the write-side of the pipe */
};
/* Create a console */
struct
create_console_request
{
int
inherit
;
/* inherit flag */
};
struct
create_console_reply
{
int
handle_read
;
/* handle to read from the console */
int
handle_write
;
/* handle to write to the console */
};
/* Set a console file descriptor */
struct
set_console_fd_request
{
int
handle
;
/* handle to the console */
};
/* client-side functions */
#ifndef __WINE_SERVER__
...
...
include/server/object.h
View file @
aa0ebd0f
...
...
@@ -34,6 +34,12 @@ struct object_ops
int
(
*
signaled
)(
struct
object
*
,
struct
thread
*
);
/* wait satisfied; return 1 if abandoned */
int
(
*
satisfied
)(
struct
object
*
,
struct
thread
*
);
/* return a Unix fd that can be used to read from the object */
int
(
*
get_read_fd
)(
struct
object
*
);
/* return a Unix fd that can be used to write to the object */
int
(
*
get_write_fd
)(
struct
object
*
);
/* flush the object buffers */
int
(
*
flush
)(
struct
object
*
);
/* destroy on refcount == 0 */
void
(
*
destroy
)(
struct
object
*
);
};
...
...
@@ -57,6 +63,11 @@ extern int init_object( struct object *obj, const struct object_ops *ops,
extern
struct
object
*
grab_object
(
void
*
obj
);
extern
void
release_object
(
void
*
obj
);
extern
struct
object
*
find_object
(
const
char
*
name
);
extern
int
no_satisfied
(
struct
object
*
obj
,
struct
thread
*
thread
);
extern
int
no_read_fd
(
struct
object
*
obj
);
extern
int
no_write_fd
(
struct
object
*
obj
);
extern
int
no_flush
(
struct
object
*
obj
);
extern
void
default_select_event
(
int
fd
,
int
event
,
void
*
private
);
/* request handlers */
...
...
@@ -161,7 +172,22 @@ extern int release_semaphore( int handle, unsigned int count, unsigned int *prev
extern
struct
object
*
create_file
(
int
fd
);
extern
int
file_get_unix_handle
(
int
handle
,
unsigned
int
access
);
extern
int
set_file_pointer
(
int
handle
,
int
*
low
,
int
*
high
,
int
whence
);
extern
int
truncate_file
(
int
handle
);
extern
int
get_file_info
(
int
handle
,
struct
get_file_info_reply
*
reply
);
extern
void
file_set_error
(
void
);
/* pipe functions */
extern
int
create_pipe
(
struct
object
*
obj
[
2
]
);
/* console functions */
extern
int
create_console
(
int
fd
,
struct
object
*
obj
[
2
]
);
extern
int
set_console_fd
(
int
handle
,
int
fd
);
extern
int
debug_level
;
...
...
include/server/request.h
View file @
aa0ebd0f
...
...
@@ -25,7 +25,15 @@ enum request
REQ_OPEN_NAMED_OBJ
,
REQ_CREATE_FILE
,
REQ_GET_UNIX_HANDLE
,
REQ_GET_READ_FD
,
REQ_GET_WRITE_FD
,
REQ_SET_FILE_POINTER
,
REQ_TRUNCATE_FILE
,
REQ_FLUSH_FILE
,
REQ_GET_FILE_INFO
,
REQ_CREATE_PIPE
,
REQ_CREATE_CONSOLE
,
REQ_SET_CONSOLE_FD
,
REQ_NB_REQUESTS
};
...
...
@@ -54,7 +62,15 @@ DECL_HANDLER(release_semaphore);
DECL_HANDLER
(
open_named_obj
);
DECL_HANDLER
(
create_file
);
DECL_HANDLER
(
get_unix_handle
);
DECL_HANDLER
(
get_read_fd
);
DECL_HANDLER
(
get_write_fd
);
DECL_HANDLER
(
set_file_pointer
);
DECL_HANDLER
(
truncate_file
);
DECL_HANDLER
(
flush_file
);
DECL_HANDLER
(
get_file_info
);
DECL_HANDLER
(
create_pipe
);
DECL_HANDLER
(
create_console
);
DECL_HANDLER
(
set_console_fd
);
static
const
struct
handler
{
void
(
*
handler
)();
...
...
@@ -80,7 +96,15 @@ static const struct handler {
{
(
void
(
*
)())
req_open_named_obj
,
sizeof
(
struct
open_named_obj_request
)
},
{
(
void
(
*
)())
req_create_file
,
sizeof
(
struct
create_file_request
)
},
{
(
void
(
*
)())
req_get_unix_handle
,
sizeof
(
struct
get_unix_handle_request
)
},
{
(
void
(
*
)())
req_get_read_fd
,
sizeof
(
struct
get_read_fd_request
)
},
{
(
void
(
*
)())
req_get_write_fd
,
sizeof
(
struct
get_write_fd_request
)
},
{
(
void
(
*
)())
req_set_file_pointer
,
sizeof
(
struct
set_file_pointer_request
)
},
{
(
void
(
*
)())
req_truncate_file
,
sizeof
(
struct
truncate_file_request
)
},
{
(
void
(
*
)())
req_flush_file
,
sizeof
(
struct
flush_file_request
)
},
{
(
void
(
*
)())
req_get_file_info
,
sizeof
(
struct
get_file_info_request
)
},
{
(
void
(
*
)())
req_create_pipe
,
sizeof
(
struct
create_pipe_request
)
},
{
(
void
(
*
)())
req_create_console
,
sizeof
(
struct
create_console_request
)
},
{
(
void
(
*
)())
req_set_console_fd
,
sizeof
(
struct
set_console_fd_request
)
},
};
#endif
/* WANT_REQUEST_HANDLERS */
...
...
server/Makefile.in
View file @
aa0ebd0f
...
...
@@ -6,10 +6,12 @@ VPATH = @srcdir@
MODULE
=
server
C_SRCS
=
\
console.c
\
event.c
\
file.c
\
mutex.c
\
object.c
\
pipe.c
\
process.c
\
request.c
\
select
.c
\
...
...
server/console.c
0 → 100644
View file @
aa0ebd0f
/*
* Server-side console management
*
* Copyright (C) 1998 Alexandre Julliard
*
* FIXME: all this stuff is a hack to avoid breaking
* the client-side console support.
*/
#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include "winerror.h"
#include "winnt.h"
#include "server/thread.h"
struct
console
{
struct
object
obj
;
/* object header */
int
fd
;
/* Unix file descriptor */
int
is_read
;
/* is this the read or write part? */
};
static
void
console_dump
(
struct
object
*
obj
,
int
verbose
);
static
void
console_add_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
);
static
void
console_remove_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
);
static
int
console_signaled
(
struct
object
*
obj
,
struct
thread
*
thread
);
static
int
console_get_read_fd
(
struct
object
*
obj
);
static
int
console_get_write_fd
(
struct
object
*
obj
);
static
void
console_destroy
(
struct
object
*
obj
);
static
const
struct
object_ops
console_ops
=
{
console_dump
,
console_add_queue
,
console_remove_queue
,
console_signaled
,
no_satisfied
,
console_get_read_fd
,
console_get_write_fd
,
no_flush
,
console_destroy
};
static
const
struct
select_ops
select_ops
=
{
default_select_event
,
NULL
/* we never set a timeout on a console */
};
int
create_console
(
int
fd
,
struct
object
*
obj
[
2
]
)
{
struct
console
*
console_read
,
*
console_write
;
int
read_fd
,
write_fd
;
if
((
read_fd
=
(
fd
!=
-
1
)
?
dup
(
fd
)
:
dup
(
0
))
==
-
1
)
{
file_set_error
();
return
0
;
}
if
((
write_fd
=
(
fd
!=
-
1
)
?
dup
(
fd
)
:
dup
(
0
))
==
-
1
)
{
file_set_error
();
close
(
read_fd
);
return
0
;
}
if
(
!
(
console_read
=
mem_alloc
(
sizeof
(
struct
console
)
)))
{
close
(
read_fd
);
close
(
write_fd
);
return
0
;
}
if
(
!
(
console_write
=
mem_alloc
(
sizeof
(
struct
console
)
)))
{
close
(
read_fd
);
close
(
write_fd
);
free
(
console_read
);
return
0
;
}
init_object
(
&
console_read
->
obj
,
&
console_ops
,
NULL
);
init_object
(
&
console_write
->
obj
,
&
console_ops
,
NULL
);
console_read
->
fd
=
read_fd
;
console_read
->
is_read
=
1
;
console_write
->
fd
=
write_fd
;
console_write
->
is_read
=
0
;
CLEAR_ERROR
();
obj
[
0
]
=
&
console_read
->
obj
;
obj
[
1
]
=
&
console_write
->
obj
;
return
1
;
}
int
set_console_fd
(
int
handle
,
int
fd
)
{
struct
console
*
console
;
if
(
!
(
console
=
(
struct
console
*
)
get_handle_obj
(
current
->
process
,
handle
,
0
,
&
console_ops
)))
return
0
;
if
((
fd
=
dup
(
fd
))
==
-
1
)
{
file_set_error
();
release_object
(
console
);
return
0
;
}
close
(
console
->
fd
);
console
->
fd
=
fd
;
release_object
(
console
);
return
1
;
}
static
void
console_dump
(
struct
object
*
obj
,
int
verbose
)
{
struct
console
*
console
=
(
struct
console
*
)
obj
;
assert
(
obj
->
ops
==
&
console_ops
);
printf
(
"Console %s fd=%d
\n
"
,
console
->
is_read
?
"input"
:
"output"
,
console
->
fd
);
}
static
void
console_add_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
)
{
struct
console
*
console
=
(
struct
console
*
)
obj
;
assert
(
obj
->
ops
==
&
console_ops
);
if
(
!
obj
->
head
)
/* first on the queue */
add_select_user
(
console
->
fd
,
console
->
is_read
?
READ_EVENT
:
WRITE_EVENT
,
&
select_ops
,
console
);
add_queue
(
obj
,
entry
);
}
static
void
console_remove_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
)
{
struct
console
*
console
=
(
struct
console
*
)
grab_object
(
obj
);
assert
(
obj
->
ops
==
&
console_ops
);
remove_queue
(
obj
,
entry
);
if
(
!
obj
->
head
)
/* last on the queue is gone */
remove_select_user
(
console
->
fd
);
release_object
(
obj
);
}
static
int
console_signaled
(
struct
object
*
obj
,
struct
thread
*
thread
)
{
fd_set
fds
;
struct
timeval
tv
=
{
0
,
0
};
struct
console
*
console
=
(
struct
console
*
)
obj
;
assert
(
obj
->
ops
==
&
console_ops
);
FD_ZERO
(
&
fds
);
FD_SET
(
console
->
fd
,
&
fds
);
if
(
console
->
is_read
)
return
select
(
console
->
fd
+
1
,
&
fds
,
NULL
,
NULL
,
&
tv
)
>
0
;
else
return
select
(
console
->
fd
+
1
,
NULL
,
&
fds
,
NULL
,
&
tv
)
>
0
;
}
static
int
console_get_read_fd
(
struct
object
*
obj
)
{
struct
console
*
console
=
(
struct
console
*
)
obj
;
assert
(
obj
->
ops
==
&
console_ops
);
if
(
!
console
->
is_read
)
{
SET_ERROR
(
ERROR_ACCESS_DENIED
);
return
-
1
;
}
return
dup
(
console
->
fd
);
}
static
int
console_get_write_fd
(
struct
object
*
obj
)
{
struct
console
*
console
=
(
struct
console
*
)
obj
;
assert
(
obj
->
ops
==
&
console_ops
);
if
(
console
->
is_read
)
{
SET_ERROR
(
ERROR_ACCESS_DENIED
);
return
-
1
;
}
return
dup
(
console
->
fd
);
}
static
void
console_destroy
(
struct
object
*
obj
)
{
struct
console
*
console
=
(
struct
console
*
)
obj
;
assert
(
obj
->
ops
==
&
console_ops
);
close
(
console
->
fd
);
free
(
console
);
}
server/event.c
View file @
aa0ebd0f
...
...
@@ -31,6 +31,9 @@ static const struct object_ops event_ops =
remove_queue
,
event_signaled
,
event_satisfied
,
no_read_fd
,
no_write_fd
,
no_flush
,
event_destroy
};
...
...
server/file.c
View file @
aa0ebd0f
...
...
@@ -30,7 +30,9 @@ static void file_dump( struct object *obj, int verbose );
static
void
file_add_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
);
static
void
file_remove_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
);
static
int
file_signaled
(
struct
object
*
obj
,
struct
thread
*
thread
);
static
int
file_satisfied
(
struct
object
*
obj
,
struct
thread
*
thread
);
static
int
file_get_read_fd
(
struct
object
*
obj
);
static
int
file_get_write_fd
(
struct
object
*
obj
);
static
int
file_flush
(
struct
object
*
obj
);
static
void
file_destroy
(
struct
object
*
obj
);
static
const
struct
object_ops
file_ops
=
...
...
@@ -39,17 +41,17 @@ static const struct object_ops file_ops =
file_add_queue
,
file_remove_queue
,
file_signaled
,
file_satisfied
,
no_satisfied
,
file_get_read_fd
,
file_get_write_fd
,
file_flush
,
file_destroy
};
static
void
file_event
(
int
fd
,
int
event
,
void
*
private
);
static
void
file_timeout
(
int
fd
,
void
*
private
);
static
const
struct
select_ops
select_ops
=
{
file
_event
,
file_timeout
default_select
_event
,
NULL
/* we never set a timeout on a file */
};
struct
object
*
create_file
(
int
fd
)
...
...
@@ -123,32 +125,74 @@ static int file_signaled( struct object *obj, struct thread *thread )
return
select
(
file
->
fd
+
1
,
&
read_fds
,
&
write_fds
,
NULL
,
&
tv
)
>
0
;
}
static
int
file_
satisfied
(
struct
object
*
obj
,
struct
thread
*
thread
)
static
int
file_
get_read_fd
(
struct
object
*
obj
)
{
/* Nothing to do */
return
0
;
/* Not abandoned */
struct
file
*
file
=
(
struct
file
*
)
obj
;
assert
(
obj
->
ops
==
&
file_ops
);
if
(
!
(
file
->
event
&
READ_EVENT
))
/* FIXME: should not be necessary */
{
SET_ERROR
(
ERROR_ACCESS_DENIED
);
return
-
1
;
}
return
dup
(
file
->
fd
);
}
static
void
file_destroy
(
struct
object
*
obj
)
static
int
file_get_write_fd
(
struct
object
*
obj
)
{
struct
file
*
file
=
(
struct
file
*
)
obj
;
assert
(
obj
->
ops
==
&
file_ops
);
close
(
file
->
fd
);
free
(
file
);
if
(
!
(
file
->
event
&
WRITE_EVENT
))
/* FIXME: should not be necessary */
{
SET_ERROR
(
ERROR_ACCESS_DENIED
);
return
-
1
;
}
return
dup
(
file
->
fd
);
}
static
void
file_event
(
int
fd
,
int
event
,
void
*
private
)
static
int
file_flush
(
struct
object
*
obj
)
{
struct
file
*
file
=
(
struct
file
*
)
private
;
assert
(
file
);
int
ret
;
struct
file
*
file
=
(
struct
file
*
)
grab_object
(
obj
);
assert
(
obj
->
ops
==
&
file_ops
);
wake_up
(
&
file
->
obj
,
0
);
ret
=
(
fsync
(
file
->
fd
)
!=
-
1
);
if
(
!
ret
)
file_set_error
();
release_object
(
file
);
return
ret
;
}
static
void
file_
timeout
(
int
fd
,
void
*
private
)
static
void
file_
destroy
(
struct
object
*
obj
)
{
/* we never set a timeout on a file */
assert
(
0
);
struct
file
*
file
=
(
struct
file
*
)
obj
;
assert
(
obj
->
ops
==
&
file_ops
);
close
(
file
->
fd
);
free
(
file
);
}
/* set the last error depending on errno */
void
file_set_error
(
void
)
{
switch
(
errno
)
{
case
EAGAIN
:
SET_ERROR
(
ERROR_SHARING_VIOLATION
);
break
;
case
EBADF
:
SET_ERROR
(
ERROR_INVALID_HANDLE
);
break
;
case
ENOSPC
:
SET_ERROR
(
ERROR_HANDLE_DISK_FULL
);
break
;
case
EACCES
:
case
EPERM
:
SET_ERROR
(
ERROR_ACCESS_DENIED
);
break
;
case
EROFS
:
SET_ERROR
(
ERROR_WRITE_PROTECT
);
break
;
case
EBUSY
:
SET_ERROR
(
ERROR_LOCK_VIOLATION
);
break
;
case
ENOENT
:
SET_ERROR
(
ERROR_FILE_NOT_FOUND
);
break
;
case
EISDIR
:
SET_ERROR
(
ERROR_CANNOT_MAKE
);
break
;
case
ENFILE
:
case
EMFILE
:
SET_ERROR
(
ERROR_NO_MORE_FILES
);
break
;
case
EEXIST
:
SET_ERROR
(
ERROR_FILE_EXISTS
);
break
;
case
EINVAL
:
SET_ERROR
(
ERROR_INVALID_PARAMETER
);
break
;
case
ESPIPE
:
SET_ERROR
(
ERROR_SEEK
);
break
;
case
ENOTEMPTY
:
SET_ERROR
(
ERROR_DIR_NOT_EMPTY
);
break
;
default:
perror
(
"file_set_error"
);
SET_ERROR
(
ERROR_UNKNOWN
);
break
;
}
}
int
file_get_unix_handle
(
int
handle
,
unsigned
int
access
)
...
...
@@ -164,6 +208,56 @@ int file_get_unix_handle( int handle, unsigned int access )
return
unix_handle
;
}
int
set_file_pointer
(
int
handle
,
int
*
low
,
int
*
high
,
int
whence
)
{
struct
file
*
file
;
int
result
;
if
(
*
high
)
{
fprintf
(
stderr
,
"set_file_pointer: offset > 4Gb not supported yet
\n
"
);
SET_ERROR
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
if
(
!
(
file
=
(
struct
file
*
)
get_handle_obj
(
current
->
process
,
handle
,
0
,
&
file_ops
)))
return
0
;
if
((
result
=
lseek
(
file
->
fd
,
*
low
,
whence
))
==
-
1
)
{
/* Check for seek before start of file */
if
((
errno
==
EINVAL
)
&&
(
whence
!=
SEEK_SET
)
&&
(
*
low
<
0
))
SET_ERROR
(
ERROR_NEGATIVE_SEEK
);
else
file_set_error
();
release_object
(
file
);
return
0
;
}
*
low
=
result
;
release_object
(
file
);
return
1
;
}
int
truncate_file
(
int
handle
)
{
struct
file
*
file
;
int
result
;
if
(
!
(
file
=
(
struct
file
*
)
get_handle_obj
(
current
->
process
,
handle
,
GENERIC_WRITE
,
&
file_ops
)))
return
0
;
if
(((
result
=
lseek
(
file
->
fd
,
0
,
SEEK_CUR
))
==
-
1
)
||
(
ftruncate
(
file
->
fd
,
result
)
==
-
1
))
{
file_set_error
();
release_object
(
file
);
return
0
;
}
release_object
(
file
);
return
1
;
}
int
get_file_info
(
int
handle
,
struct
get_file_info_reply
*
reply
)
{
struct
file
*
file
;
...
...
@@ -174,7 +268,7 @@ int get_file_info( int handle, struct get_file_info_reply *reply )
return
0
;
if
(
fstat
(
file
->
fd
,
&
st
)
==
-
1
)
{
/* file_set_error(); */
file_set_error
();
release_object
(
file
);
return
0
;
}
...
...
server/mutex.c
View file @
aa0ebd0f
...
...
@@ -34,6 +34,9 @@ static const struct object_ops mutex_ops =
remove_queue
,
mutex_signaled
,
mutex_satisfied
,
no_read_fd
,
no_write_fd
,
no_flush
,
mutex_destroy
};
...
...
server/object.c
View file @
aa0ebd0f
...
...
@@ -144,3 +144,35 @@ struct object *find_object( const char *name )
if
(
!
ptr
)
return
NULL
;
return
grab_object
(
ptr
->
obj
);
}
/* functions for unimplemented object operations */
int
no_satisfied
(
struct
object
*
obj
,
struct
thread
*
thread
)
{
return
0
;
/* not abandoned */
}
int
no_read_fd
(
struct
object
*
obj
)
{
SET_ERROR
(
ERROR_INVALID_HANDLE
);
return
-
1
;
}
int
no_write_fd
(
struct
object
*
obj
)
{
SET_ERROR
(
ERROR_INVALID_HANDLE
);
return
-
1
;
}
int
no_flush
(
struct
object
*
obj
)
{
SET_ERROR
(
ERROR_INVALID_HANDLE
);
return
0
;
}
void
default_select_event
(
int
fd
,
int
event
,
void
*
private
)
{
struct
object
*
obj
=
(
struct
object
*
)
private
;
assert
(
obj
);
wake_up
(
obj
,
0
);
}
server/pipe.c
0 → 100644
View file @
aa0ebd0f
/*
* Server-side pipe management
*
* Copyright (C) 1998 Alexandre Julliard
*/
#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include "winerror.h"
#include "winnt.h"
#include "server/thread.h"
enum
side
{
READ_SIDE
,
WRITE_SIDE
};
struct
pipe
{
struct
object
obj
;
/* object header */
struct
pipe
*
other
;
/* the pipe other end */
int
fd
;
/* Unix file descriptor */
enum
side
side
;
/* which side of the pipe is this */
};
static
void
pipe_dump
(
struct
object
*
obj
,
int
verbose
);
static
void
pipe_add_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
);
static
void
pipe_remove_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
);
static
int
pipe_signaled
(
struct
object
*
obj
,
struct
thread
*
thread
);
static
int
pipe_get_read_fd
(
struct
object
*
obj
);
static
int
pipe_get_write_fd
(
struct
object
*
obj
);
static
void
pipe_destroy
(
struct
object
*
obj
);
static
const
struct
object_ops
pipe_ops
=
{
pipe_dump
,
pipe_add_queue
,
pipe_remove_queue
,
pipe_signaled
,
no_satisfied
,
pipe_get_read_fd
,
pipe_get_write_fd
,
no_flush
,
pipe_destroy
};
static
const
struct
select_ops
select_ops
=
{
default_select_event
,
NULL
/* we never set a timeout on a pipe */
};
int
create_pipe
(
struct
object
*
obj
[
2
]
)
{
struct
pipe
*
newpipe
[
2
];
int
fd
[
2
];
if
(
pipe
(
fd
)
==
-
1
)
{
file_set_error
();
return
0
;
}
if
(
!
(
newpipe
[
0
]
=
mem_alloc
(
sizeof
(
struct
pipe
)
)))
{
close
(
fd
[
0
]
);
close
(
fd
[
1
]
);
return
0
;
}
if
(
!
(
newpipe
[
1
]
=
mem_alloc
(
sizeof
(
struct
pipe
)
)))
{
close
(
fd
[
0
]
);
close
(
fd
[
1
]
);
free
(
newpipe
[
0
]
);
return
0
;
}
init_object
(
&
newpipe
[
0
]
->
obj
,
&
pipe_ops
,
NULL
);
init_object
(
&
newpipe
[
1
]
->
obj
,
&
pipe_ops
,
NULL
);
newpipe
[
0
]
->
fd
=
fd
[
0
];
newpipe
[
0
]
->
other
=
newpipe
[
1
];
newpipe
[
0
]
->
side
=
READ_SIDE
;
newpipe
[
1
]
->
fd
=
fd
[
1
];
newpipe
[
1
]
->
other
=
newpipe
[
0
];
newpipe
[
1
]
->
side
=
WRITE_SIDE
;
obj
[
0
]
=
&
newpipe
[
0
]
->
obj
;
obj
[
1
]
=
&
newpipe
[
1
]
->
obj
;
CLEAR_ERROR
();
return
1
;
}
static
void
pipe_dump
(
struct
object
*
obj
,
int
verbose
)
{
struct
pipe
*
pipe
=
(
struct
pipe
*
)
obj
;
assert
(
obj
->
ops
==
&
pipe_ops
);
printf
(
"Pipe %s-side fd=%d
\n
"
,
(
pipe
->
side
==
READ_SIDE
)
?
"read"
:
"write"
,
pipe
->
fd
);
}
static
void
pipe_add_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
)
{
struct
pipe
*
pipe
=
(
struct
pipe
*
)
obj
;
assert
(
obj
->
ops
==
&
pipe_ops
);
if
(
!
obj
->
head
)
/* first on the queue */
add_select_user
(
pipe
->
fd
,
(
pipe
->
side
==
READ_SIDE
)
?
READ_EVENT
:
WRITE_EVENT
,
&
select_ops
,
pipe
);
add_queue
(
obj
,
entry
);
}
static
void
pipe_remove_queue
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
)
{
struct
pipe
*
pipe
=
(
struct
pipe
*
)
grab_object
(
obj
);
assert
(
obj
->
ops
==
&
pipe_ops
);
remove_queue
(
obj
,
entry
);
if
(
!
obj
->
head
)
/* last on the queue is gone */
remove_select_user
(
pipe
->
fd
);
release_object
(
obj
);
}
static
int
pipe_signaled
(
struct
object
*
obj
,
struct
thread
*
thread
)
{
struct
pipe
*
pipe
=
(
struct
pipe
*
)
obj
;
struct
timeval
tv
=
{
0
,
0
};
fd_set
fds
;
assert
(
obj
->
ops
==
&
pipe_ops
);
FD_ZERO
(
&
fds
);
FD_SET
(
pipe
->
fd
,
&
fds
);
if
(
pipe
->
side
==
READ_SIDE
)
return
select
(
pipe
->
fd
+
1
,
&
fds
,
NULL
,
NULL
,
&
tv
)
>
0
;
else
return
select
(
pipe
->
fd
+
1
,
NULL
,
&
fds
,
NULL
,
&
tv
)
>
0
;
}
static
int
pipe_get_read_fd
(
struct
object
*
obj
)
{
struct
pipe
*
pipe
=
(
struct
pipe
*
)
obj
;
assert
(
obj
->
ops
==
&
pipe_ops
);
if
(
!
pipe
->
other
)
{
SET_ERROR
(
ERROR_BROKEN_PIPE
);
return
-
1
;
}
if
(
pipe
->
side
!=
READ_SIDE
)
/* FIXME: should not be necessary */
{
SET_ERROR
(
ERROR_ACCESS_DENIED
);
return
-
1
;
}
return
dup
(
pipe
->
fd
);
}
static
int
pipe_get_write_fd
(
struct
object
*
obj
)
{
struct
pipe
*
pipe
=
(
struct
pipe
*
)
obj
;
assert
(
obj
->
ops
==
&
pipe_ops
);
if
(
!
pipe
->
other
)
{
SET_ERROR
(
ERROR_BROKEN_PIPE
);
return
-
1
;
}
if
(
pipe
->
side
!=
WRITE_SIDE
)
/* FIXME: should not be necessary */
{
SET_ERROR
(
ERROR_ACCESS_DENIED
);
return
-
1
;
}
return
dup
(
pipe
->
fd
);
}
static
void
pipe_destroy
(
struct
object
*
obj
)
{
struct
pipe
*
pipe
=
(
struct
pipe
*
)
obj
;
assert
(
obj
->
ops
==
&
pipe_ops
);
if
(
pipe
->
other
)
pipe
->
other
->
other
=
NULL
;
close
(
pipe
->
fd
);
free
(
pipe
);
}
server/process.c
View file @
aa0ebd0f
...
...
@@ -56,7 +56,6 @@ static struct process *first_process;
static
void
process_dump
(
struct
object
*
obj
,
int
verbose
);
static
int
process_signaled
(
struct
object
*
obj
,
struct
thread
*
thread
);
static
int
process_satisfied
(
struct
object
*
obj
,
struct
thread
*
thread
);
static
void
process_destroy
(
struct
object
*
obj
);
static
void
free_handles
(
struct
process
*
process
);
static
int
copy_handle_table
(
struct
process
*
process
,
struct
process
*
parent
);
...
...
@@ -67,7 +66,10 @@ static const struct object_ops process_ops =
add_queue
,
remove_queue
,
process_signaled
,
process_satisfied
,
no_satisfied
,
no_read_fd
,
no_write_fd
,
no_flush
,
process_destroy
};
...
...
@@ -130,11 +132,6 @@ static int process_signaled( struct object *obj, struct thread *thread )
return
(
process
->
running_threads
>
0
);
}
static
int
process_satisfied
(
struct
object
*
obj
,
struct
thread
*
thread
)
{
return
0
;
}
/* get a process from an id (and increment the refcount) */
struct
process
*
get_process_from_id
(
void
*
id
)
{
...
...
server/request.c
View file @
aa0ebd0f
...
...
@@ -4,6 +4,7 @@
* Copyright (C) 1998 Alexandre Julliard
*/
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
...
...
@@ -156,6 +157,8 @@ DECL_HANDLER(init_thread)
DECL_HANDLER
(
set_debug
)
{
debug_level
=
req
->
level
;
/* Make sure last_req is initialized */
current
->
last_req
=
REQ_SET_DEBUG
;
CLEAR_ERROR
();
send_reply
(
current
,
-
1
,
0
);
}
...
...
@@ -408,6 +411,64 @@ DECL_HANDLER(get_unix_handle)
send_reply
(
current
,
handle
,
0
);
}
/* get a Unix fd to read from a file */
DECL_HANDLER
(
get_read_fd
)
{
struct
object
*
obj
;
int
read_fd
;
if
((
obj
=
get_handle_obj
(
current
->
process
,
req
->
handle
,
GENERIC_READ
,
NULL
)))
{
read_fd
=
obj
->
ops
->
get_read_fd
(
obj
);
release_object
(
obj
);
}
else
read_fd
=
-
1
;
send_reply
(
current
,
read_fd
,
0
);
}
/* get a Unix fd to write to a file */
DECL_HANDLER
(
get_write_fd
)
{
struct
object
*
obj
;
int
write_fd
;
if
((
obj
=
get_handle_obj
(
current
->
process
,
req
->
handle
,
GENERIC_WRITE
,
NULL
)))
{
write_fd
=
obj
->
ops
->
get_write_fd
(
obj
);
release_object
(
obj
);
}
else
write_fd
=
-
1
;
send_reply
(
current
,
write_fd
,
0
);
}
/* set a file current position */
DECL_HANDLER
(
set_file_pointer
)
{
struct
set_file_pointer_reply
reply
=
{
req
->
low
,
req
->
high
};
set_file_pointer
(
req
->
handle
,
&
reply
.
low
,
&
reply
.
high
,
req
->
whence
);
send_reply
(
current
,
-
1
,
1
,
&
reply
,
sizeof
(
reply
)
);
}
/* truncate (or extend) a file */
DECL_HANDLER
(
truncate_file
)
{
truncate_file
(
req
->
handle
);
send_reply
(
current
,
-
1
,
0
);
}
/* flush a file buffers */
DECL_HANDLER
(
flush_file
)
{
struct
object
*
obj
;
if
((
obj
=
get_handle_obj
(
current
->
process
,
req
->
handle
,
GENERIC_WRITE
,
NULL
)))
{
obj
->
ops
->
flush
(
obj
);
release_object
(
obj
);
}
send_reply
(
current
,
-
1
,
0
);
}
/* get a file information */
DECL_HANDLER
(
get_file_info
)
{
...
...
@@ -415,3 +476,58 @@ DECL_HANDLER(get_file_info)
get_file_info
(
req
->
handle
,
&
reply
);
send_reply
(
current
,
-
1
,
1
,
&
reply
,
sizeof
(
reply
)
);
}
/* create an anonymous pipe */
DECL_HANDLER
(
create_pipe
)
{
struct
create_pipe_reply
reply
=
{
-
1
,
-
1
};
struct
object
*
obj
[
2
];
if
(
create_pipe
(
obj
))
{
reply
.
handle_read
=
alloc_handle
(
current
->
process
,
obj
[
0
],
STANDARD_RIGHTS_REQUIRED
|
SYNCHRONIZE
|
GENERIC_READ
,
req
->
inherit
);
if
(
reply
.
handle_read
!=
-
1
)
{
reply
.
handle_write
=
alloc_handle
(
current
->
process
,
obj
[
1
],
STANDARD_RIGHTS_REQUIRED
|
SYNCHRONIZE
|
GENERIC_WRITE
,
req
->
inherit
);
if
(
reply
.
handle_write
==
-
1
)
close_handle
(
current
->
process
,
reply
.
handle_read
);
}
release_object
(
obj
[
0
]
);
release_object
(
obj
[
1
]
);
}
send_reply
(
current
,
-
1
,
1
,
&
reply
,
sizeof
(
reply
)
);
}
/* create a console */
DECL_HANDLER
(
create_console
)
{
struct
create_console_reply
reply
=
{
-
1
,
-
1
};
struct
object
*
obj
[
2
];
if
(
create_console
(
fd
,
obj
))
{
reply
.
handle_read
=
alloc_handle
(
current
->
process
,
obj
[
0
],
STANDARD_RIGHTS_REQUIRED
|
SYNCHRONIZE
|
GENERIC_READ
,
req
->
inherit
);
if
(
reply
.
handle_read
!=
-
1
)
{
reply
.
handle_write
=
alloc_handle
(
current
->
process
,
obj
[
1
],
STANDARD_RIGHTS_REQUIRED
|
SYNCHRONIZE
|
GENERIC_WRITE
,
req
->
inherit
);
if
(
reply
.
handle_write
==
-
1
)
close_handle
(
current
->
process
,
reply
.
handle_read
);
}
release_object
(
obj
[
0
]
);
release_object
(
obj
[
1
]
);
}
send_reply
(
current
,
-
1
,
1
,
&
reply
,
sizeof
(
reply
)
);
}
/* set a console fd */
DECL_HANDLER
(
set_console_fd
)
{
set_console_fd
(
req
->
handle
,
fd
);
send_reply
(
current
,
-
1
,
0
);
}
server/semaphore.c
View file @
aa0ebd0f
...
...
@@ -31,6 +31,9 @@ static const struct object_ops semaphore_ops =
remove_queue
,
semaphore_signaled
,
semaphore_satisfied
,
no_read_fd
,
no_write_fd
,
no_flush
,
semaphore_destroy
};
...
...
server/thread.c
View file @
aa0ebd0f
...
...
@@ -43,7 +43,6 @@ struct thread_wait
static
void
dump_thread
(
struct
object
*
obj
,
int
verbose
);
static
int
thread_signaled
(
struct
object
*
obj
,
struct
thread
*
thread
);
static
int
thread_satisfied
(
struct
object
*
obj
,
struct
thread
*
thread
);
static
void
destroy_thread
(
struct
object
*
obj
);
static
const
struct
object_ops
thread_ops
=
...
...
@@ -52,7 +51,10 @@ static const struct object_ops thread_ops =
add_queue
,
remove_queue
,
thread_signaled
,
thread_satisfied
,
no_satisfied
,
no_read_fd
,
no_write_fd
,
no_flush
,
destroy_thread
};
...
...
@@ -153,11 +155,6 @@ static int thread_signaled( struct object *obj, struct thread *thread )
return
(
mythread
->
state
==
TERMINATED
);
}
static
int
thread_satisfied
(
struct
object
*
obj
,
struct
thread
*
thread
)
{
return
0
;
}
/* get a thread pointer from a thread id (and increment the refcount) */
struct
thread
*
get_thread_from_id
(
void
*
id
)
{
...
...
server/trace.c
View file @
aa0ebd0f
...
...
@@ -229,6 +229,46 @@ static int dump_get_unix_handle_request( struct get_unix_handle_request *req, in
return
(
int
)
sizeof
(
*
req
);
}
static
int
dump_get_read_fd_request
(
struct
get_read_fd_request
*
req
,
int
len
)
{
printf
(
" handle=%d"
,
req
->
handle
);
return
(
int
)
sizeof
(
*
req
);
}
static
int
dump_get_write_fd_request
(
struct
get_write_fd_request
*
req
,
int
len
)
{
printf
(
" handle=%d"
,
req
->
handle
);
return
(
int
)
sizeof
(
*
req
);
}
static
int
dump_set_file_pointer_request
(
struct
set_file_pointer_request
*
req
,
int
len
)
{
printf
(
" handle=%d,"
,
req
->
handle
);
printf
(
" low=%d,"
,
req
->
low
);
printf
(
" high=%d,"
,
req
->
high
);
printf
(
" whence=%d"
,
req
->
whence
);
return
(
int
)
sizeof
(
*
req
);
}
static
int
dump_set_file_pointer_reply
(
struct
set_file_pointer_reply
*
req
,
int
len
)
{
printf
(
" low=%d,"
,
req
->
low
);
printf
(
" high=%d"
,
req
->
high
);
return
(
int
)
sizeof
(
*
req
);
}
static
int
dump_truncate_file_request
(
struct
truncate_file_request
*
req
,
int
len
)
{
printf
(
" handle=%d"
,
req
->
handle
);
return
(
int
)
sizeof
(
*
req
);
}
static
int
dump_flush_file_request
(
struct
flush_file_request
*
req
,
int
len
)
{
printf
(
" handle=%d"
,
req
->
handle
);
return
(
int
)
sizeof
(
*
req
);
}
static
int
dump_get_file_info_request
(
struct
get_file_info_request
*
req
,
int
len
)
{
printf
(
" handle=%d"
,
req
->
handle
);
...
...
@@ -249,6 +289,38 @@ static int dump_get_file_info_reply( struct get_file_info_reply *req, int len )
return
(
int
)
sizeof
(
*
req
);
}
static
int
dump_create_pipe_request
(
struct
create_pipe_request
*
req
,
int
len
)
{
printf
(
" inherit=%d"
,
req
->
inherit
);
return
(
int
)
sizeof
(
*
req
);
}
static
int
dump_create_pipe_reply
(
struct
create_pipe_reply
*
req
,
int
len
)
{
printf
(
" handle_read=%d,"
,
req
->
handle_read
);
printf
(
" handle_write=%d"
,
req
->
handle_write
);
return
(
int
)
sizeof
(
*
req
);
}
static
int
dump_create_console_request
(
struct
create_console_request
*
req
,
int
len
)
{
printf
(
" inherit=%d"
,
req
->
inherit
);
return
(
int
)
sizeof
(
*
req
);
}
static
int
dump_create_console_reply
(
struct
create_console_reply
*
req
,
int
len
)
{
printf
(
" handle_read=%d,"
,
req
->
handle_read
);
printf
(
" handle_write=%d"
,
req
->
handle_write
);
return
(
int
)
sizeof
(
*
req
);
}
static
int
dump_set_console_fd_request
(
struct
set_console_fd_request
*
req
,
int
len
)
{
printf
(
" handle=%d"
,
req
->
handle
);
return
(
int
)
sizeof
(
*
req
);
}
struct
dumper
{
int
(
*
dump_req
)(
void
*
data
,
int
len
);
...
...
@@ -297,8 +369,24 @@ static const struct dumper dumpers[REQ_NB_REQUESTS] =
(
void
(
*
)())
dump_create_file_reply
},
{
(
int
(
*
)(
void
*
,
int
))
dump_get_unix_handle_request
,
(
void
(
*
)())
0
},
{
(
int
(
*
)(
void
*
,
int
))
dump_get_read_fd_request
,
(
void
(
*
)())
0
},
{
(
int
(
*
)(
void
*
,
int
))
dump_get_write_fd_request
,
(
void
(
*
)())
0
},
{
(
int
(
*
)(
void
*
,
int
))
dump_set_file_pointer_request
,
(
void
(
*
)())
dump_set_file_pointer_reply
},
{
(
int
(
*
)(
void
*
,
int
))
dump_truncate_file_request
,
(
void
(
*
)())
0
},
{
(
int
(
*
)(
void
*
,
int
))
dump_flush_file_request
,
(
void
(
*
)())
0
},
{
(
int
(
*
)(
void
*
,
int
))
dump_get_file_info_request
,
(
void
(
*
)())
dump_get_file_info_reply
},
{
(
int
(
*
)(
void
*
,
int
))
dump_create_pipe_request
,
(
void
(
*
)())
dump_create_pipe_reply
},
{
(
int
(
*
)(
void
*
,
int
))
dump_create_console_request
,
(
void
(
*
)())
dump_create_console_reply
},
{
(
int
(
*
)(
void
*
,
int
))
dump_set_console_fd_request
,
(
void
(
*
)())
0
},
};
static
const
char
*
const
req_names
[
REQ_NB_REQUESTS
]
=
...
...
@@ -323,7 +411,15 @@ static const char * const req_names[REQ_NB_REQUESTS] =
"open_named_obj"
,
"create_file"
,
"get_unix_handle"
,
"get_read_fd"
,
"get_write_fd"
,
"set_file_pointer"
,
"truncate_file"
,
"flush_file"
,
"get_file_info"
,
"create_pipe"
,
"create_console"
,
"set_console_fd"
,
};
void
trace_request
(
enum
request
req
,
void
*
data
,
int
len
,
int
fd
)
...
...
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