Mail Archives: cygwin-developers/2001/09/12/07:51:49
--=-2xW0e3oLK9wHBIYlsOkp
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
Attached is a slightly reworked daemon that will not impact 95 in speed
(well at dll load for non-forked process's it will, but not after that
first request).
Egors original message with changelogs describing this beast is
available
http://sources.redhat.com/ml/cygwin-patches/2001-q1/msg00260.html here.
I've altered the layout slightly - I consider the daemon more core than
(say) cygcheck, so I placed it all in cygwin.
The point of all this is that while this daemon won't run on 95, 95
users won't suffer *should* it get added post 1.3.3....
Rob
--=-2xW0e3oLK9wHBIYlsOkp
Content-Type: text/plain
Content-Disposition: attachment; filename=daemon.patch
Content-ID: <1000295378 DOT 30340 DOT 61 DOT camel AT lifelesswks>
Content-Transfer-Encoding: 7bit
? currentstate.patch
? cygserver.cc
? cygserver.cygwin.ChangeLog
? cygserver.diff
? cygserver.utils.ChangeLog
? cygserver_client.cc
? daemon.patch
? fhandler_ums.cc
? host_dependent.cc
? mutexsviacriticalsections.patch
? pthchange
? umsdos_gen.h
? virtualquery.patch
? include/cygwin/cygserver.h
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/Makefile.in,v
retrieving revision 1.60
diff -u -p -r1.60 Makefile.in
--- Makefile.in 2001/09/11 20:01:00 1.60
+++ Makefile.in 2001/09/12 11:47:41
@@ -116,13 +116,13 @@ MALLOC_OFILES=@MALLOC_OFILES@
DLL_IMPORTS:=$(w32api_lib)/libkernel32.a
-DLL_OFILES:=assert.o autoload.o cygheap.o dcrt0.o debug.o delqueue.o dir.o \
+DLL_OFILES:=assert.o autoload.o cygheap.o cygserver_client.o dcrt0.o debug.o delqueue.o dir.o \
dlfcn.o dll_init.o dtable.o environ.o errno.o exceptions.o exec.o \
external.o fcntl.o fhandler.o fhandler_clipboard.o fhandler_console.o \
fhandler_dsp.o fhandler_floppy.o fhandler_mem.o fhandler_random.o \
fhandler_raw.o fhandler_serial.o fhandler_socket.o fhandler_tape.o \
fhandler_termios.o fhandler_tty.o fhandler_windows.o fhandler_zero.o \
- fork.o glob.o grp.o heap.o init.o ioctl.o localtime.o malloc.o \
+ fork.o glob.o grp.o heap.o host_dependent.o init.o ioctl.o localtime.o malloc.o \
miscfuncs.o mmap.o net.o ntea.o passwd.o path.o pinfo.o pipe.o poll.o \
pthread.o regexp.o regerror.o regsub.o registry.o resource.o scandir.o \
sched.o sec_acl.o sec_helper.o security.o select.o shared.o shortcut.o signal.o sigproc.o \
@@ -144,14 +144,17 @@ install_host=@install_host@
all: new-$(DLL_NAME) $(all_host) all_target
-all_target: $(LIBGMON_A) $(LIB_NAME) automode.o binmode.o textmode.o
+all_target: $(LIBGMON_A) $(LIB_NAME) automode.o binmode.o textmode.o cygserver.exe
all_host: new-$(LIB_NAME) cygrun.exe
force:
-install: install-libs install-headers $(install_host) $(install_target)
+install: install-bin install-libs install-headers $(install_host) $(install_target)
+install-bin: cygserver.exe
+ $(INSTALL_PROGRAM) cygserver.exe $(bindir)/cygserver.exe
+
install-libs: $(LIB_NAME)
$(INSTALL_DATA) new-$(DLL_NAME) $(bindir)/$(DLL_NAME); \
for i in $(LIB_NAME) $(GMON_START) $(LIBGMON_A) automode.o binmode.o textmode.o ; do \
@@ -218,6 +221,14 @@ winver_stamp: mkvers.sh include/cygwin/v
cygrun.exe : cygrun.o $(LIB_NAME) $(w32api_lib)/libuser32.a \
$(w32api_lib)/libshell32.a $(w32api_lib)/libkernel32.a
$(CC) -nodefaultlibs -o $@ $^
+
+cygserver.exe: cygserver.cc host_dependent.cc smallprint.o
+ifdef VERBOSE
+ $(CXX) $(MINGW_CXXFLAGS) -o $@ ${wordlist 1,3,$^} -B$(mingw_build)/ $(MINGW_LDFLAGS)
+else
+ @echo $(CXX) -o $@ ${wordlist 1,3,$^} ${filter-out -B%, $(MINGW_CXXFLAGS) $(MINGW_LDFLAGS)};\
+ $(CXX) $(MINGW_CXXFLAGS) -o $@ ${wordlist 1,3,$^} -B$(mingw_build)/ $(MINGW_LDFLAGS)
+endif
#
Index: dcrt0.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/dcrt0.cc,v
retrieving revision 1.108
diff -u -p -r1.108 dcrt0.cc
--- dcrt0.cc 2001/09/11 08:15:39 1.108
+++ dcrt0.cc 2001/09/12 11:47:42
@@ -35,6 +35,7 @@ details. */
#include "cygwin_version.h"
#include "dll_init.h"
#include "host_dependent.h"
+#include "cygwin/cygserver.h"
#define MAX_AT_FILE_LEVEL 10
@@ -155,94 +156,8 @@ do_global_ctors (void (**in_pfunc)(), in
atexit (do_global_dtors);
}
-/* remember the type of Win32 OS being run for future use. */
-os_type NO_COPY os_being_run;
-char NO_COPY osname[40];
-bool iswinnt;
-
-/* set_os_type: Set global variable os_being_run with type of Win32
- operating system being run. This information is used internally
- to manage the inconsistency in Win32 API calls between Win32 OSes. */
-/* Cygwin internal */
-static void
-set_os_type ()
-{
- OSVERSIONINFO os_version_info;
- const char *os;
-
- memset (&os_version_info, 0, sizeof os_version_info);
- os_version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
- GetVersionEx (&os_version_info);
-
- iswinnt = 0;
- switch (os_version_info.dwPlatformId)
- {
- case VER_PLATFORM_WIN32_NT:
- os_being_run = winNT;
- os = "NT";
- iswinnt = 1;
- break;
- case VER_PLATFORM_WIN32_WINDOWS:
- if (os_version_info.dwMinorVersion == 0)
- {
- os_being_run = win95;
- os = "95";
- }
- else if (os_version_info.dwMinorVersion < 90)
- {
- os_being_run = win98;
- os = "98";
- }
- else /* os_version_info.dwMinorVersion == 90 */
- {
- os_being_run = winME;
- os = "ME";
- }
- break;
- default:
- os_being_run = unknown;
- os = "??";
- break;
- }
- __small_sprintf (osname, "%s-%d.%d", os, os_version_info.dwMajorVersion,
- os_version_info.dwMinorVersion);
-}
-
host_dependent_constants NO_COPY host_dependent;
-/* Constructor for host_dependent_constants. */
-
-void
-host_dependent_constants::init ()
-{
- extern DWORD chunksize;
- /* fhandler_disk_file::lock needs a platform specific upper word
- value for locking entire files.
-
- fhandler_base::open requires host dependent file sharing
- attributes. */
-
- switch (os_being_run)
- {
- case winNT:
- win32_upper = 0xffffffff;
- shared = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
- break;
-
- case winME:
- case win98:
- case win95:
- case win32s:
- win32_upper = 0x00000000;
- shared = FILE_SHARE_READ | FILE_SHARE_WRITE;
- chunksize = 32 * 1024 * 1024;
- break;
-
- default:
- api_fatal ("unrecognized system type");
- }
-}
-
/*
* Replaces -@file in the command line with the contents of the file.
* There may be multiple -@file's in a single command line
@@ -777,6 +692,8 @@ dll_crt0_1 ()
/* Initialize signal/subprocess handling. */
sigproc_init ();
+
+ cygserver_init ();
/* Connect to tty. */
tty_init ();
Index: fhandler.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler.h,v
retrieving revision 1.76
diff -u -p -r1.76 fhandler.h
--- fhandler.h 2001/09/11 20:01:00 1.76
+++ fhandler.h 2001/09/12 11:47:43
@@ -832,6 +832,8 @@ public:
off_t lseek (off_t, int) { return 0; }
select_record *select_read (select_record *s);
int ready_for_read (int fd, DWORD howlong, int ignra);
+
+ int cygserver_attach_tty (HANDLE*, HANDLE*);
};
class fhandler_pty_master: public fhandler_tty_common
Index: fhandler_tty.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler_tty.cc,v
retrieving revision 1.47
diff -u -p -r1.47 fhandler_tty.cc
--- fhandler_tty.cc 2001/09/07 21:32:04 1.47
+++ fhandler_tty.cc 2001/09/12 11:47:44
@@ -25,6 +25,7 @@ details. */
#include "pinfo.h"
#include "cygheap.h"
#include "shared_info.h"
+#include "cygwin/cygserver.h"
/* Tty master stuff */
@@ -523,42 +524,74 @@ fhandler_tty_slave::open (const char *,
return 0;
}
- HANDLE tty_owner = OpenProcess (PROCESS_DUP_HANDLE, FALSE,
- get_ttyp ()->master_pid);
- if (tty_owner == NULL)
- {
- termios_printf ("can't open tty (%d) handle process %d",
- ttynum, get_ttyp ()->master_pid);
- __seterrno ();
- return 0;
- }
+ HANDLE from_master_local, to_master_local;
- HANDLE nh;
- if (!DuplicateHandle (tty_owner, get_ttyp ()->from_master, hMainProc, &nh, 0, TRUE,
- DUPLICATE_SAME_ACCESS))
+ if (!cygserver_running || !cygserver_attach_tty ( &from_master_local, &to_master_local))
{
- termios_printf ("can't duplicate input, %E");
- __seterrno ();
- return 0;
- }
- set_io_handle (nh);
- ProtectHandle1 (nh, from_pty);
- termios_printf ("duplicated from_master %p->%p from tty_owner %p",
- get_ttyp ()->from_master, nh, tty_owner);
- if (!DuplicateHandle (tty_owner, get_ttyp ()->to_master, hMainProc, &nh, 0, TRUE,
- DUPLICATE_SAME_ACCESS))
- {
- termios_printf ("can't duplicate output, %E");
- __seterrno ();
- return 0;
- }
- set_output_handle (nh);
- ProtectHandle1 (nh, to_pty);
- CloseHandle (tty_owner);
+ termios_printf ("cannot dup handles via server. using old method.");
+ HANDLE tty_owner = OpenProcess (PROCESS_DUP_HANDLE, FALSE,
+ get_ttyp ()->master_pid);
+ if (tty_owner == NULL)
+ {
+ termios_printf ("can't open tty (%d) handle process %d",
+ ttynum, get_ttyp ()->master_pid);
+ __seterrno ();
+ return 0;
+ }
+
+ if (!DuplicateHandle (tty_owner, get_ttyp ()->from_master,
+ hMainProc, &from_master_local, 0, TRUE,
+ DUPLICATE_SAME_ACCESS))
+ {
+ termios_printf ("can't duplicate input, %E");
+ __seterrno ();
+ return 0;
+ }
+ termios_printf ("duplicated from_master %p->%p from tty_owner %p",
+ get_ttyp ()->from_master, from_master_local, tty_owner);
+
+ if (!DuplicateHandle (tty_owner, get_ttyp ()->to_master,
+ hMainProc, &to_master_local, 0, TRUE,
+ DUPLICATE_SAME_ACCESS))
+ {
+ termios_printf ("can't duplicate output, %E");
+ __seterrno ();
+ return 0;
+ }
+ termios_printf ("duplicated to_master %p->%p from tty_owner %p",
+ get_ttyp ()->to_master, to_master_local, tty_owner);
+ CloseHandle (tty_owner);
+ }
+
+ set_io_handle (from_master_local);
+ ProtectHandle1 (from_master_local, from_pty);
+ set_output_handle (to_master_local);
+ ProtectHandle1 (to_master_local, to_pty);
+
set_open_status ();
termios_printf ("tty%d opened", ttynum);
+ return 1;
+}
+
+int
+fhandler_tty_slave::cygserver_attach_tty (HANDLE* from_master_ptr,
+ HANDLE* to_master_ptr)
+{
+ if (!from_master_ptr || !to_master_ptr)
+ return 0;
+
+ struct request_attach_tty req;
+ INIT_REQUEST (req, CYGSERVER_REQUEST_ATTACH_TTY);
+ req.pid = GetCurrentProcessId ();
+ req.master_pid = get_ttyp ()->master_pid;
+ req.from_master = get_ttyp ()->from_master;
+ req.to_master = get_ttyp ()->to_master;
+ if (cygserver_request ((struct request_header*) &req) != 0)
+ return 0;
+ *from_master_ptr = req.from_master;
+ *to_master_ptr = req.to_master;
return 1;
}
Index: fork.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fork.cc,v
retrieving revision 1.62
diff -u -p -r1.62 fork.cc
--- fork.cc 2001/09/11 08:15:39 1.62
+++ fork.cc 2001/09/12 11:47:44
@@ -35,7 +35,7 @@ static int npid_max;
static pid_t fork_pids[100];
#endif
-DWORD NO_COPY chunksize = 0;
+extern DWORD chunksize;
/* Timeout to wait for child to start, parent to init child, etc. */
/* FIXME: Once things stabilize, bump up to a few minutes. */
#define FORK_WAIT_TIMEOUT (300 * 1000) /* 300 seconds */
Index: host_dependent.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/host_dependent.h,v
retrieving revision 1.2
diff -u -p -r1.2 host_dependent.h
--- host_dependent.h 2001/06/24 22:26:51 1.2
+++ host_dependent.h 2001/09/12 11:47:44
@@ -28,3 +28,4 @@ class host_dependent_constants
};
extern host_dependent_constants host_dependent;
+extern void set_os_type();
Index: tty.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/tty.cc,v
retrieving revision 1.28
diff -u -p -r1.28 tty.cc
--- tty.cc 2001/09/06 04:41:59 1.28
+++ tty.cc 2001/09/12 11:47:44
@@ -23,6 +23,7 @@ details. */
#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
+#include "cygwin/cygserver.h"
#include "shared_info.h"
extern fhandler_tty_master *tty_master;
@@ -393,6 +394,7 @@ tty::common_init (fhandler_pty_master *p
/* Allow the others to open us (for handle duplication) */
if ((iswinnt) &&
+ !cygserver_running &&
(SetKernelObjectSecurity (hMainProc, DACL_SECURITY_INFORMATION,
get_null_sd ()) == FALSE))
small_printf ("Can't set process security, %E");
Index: winsup.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/winsup.h,v
retrieving revision 1.68
diff -u -p -r1.68 winsup.h
--- winsup.h 2001/09/09 16:52:37 1.68
+++ winsup.h 2001/09/12 11:47:45
@@ -72,6 +72,8 @@ extern bool iswinnt;
enum codepage_type {ansi_cp, oem_cp};
extern codepage_type current_codepage;
+extern int cygserver_running;
+
/* Used to check if Cygwin DLL is dynamically loaded. */
extern int dynamically_loaded;
--=-2xW0e3oLK9wHBIYlsOkp
Content-Type: text/x-c
Content-Disposition: attachment; filename=cygserver.cc
Content-ID: <1000295523 DOT 30340 DOT 65 DOT camel AT lifelesswks>
Content-Transfer-Encoding: 7bit
/* cygserver.cc
Copyright 2001 Red Hat Inc.
Written by Egor Duda <deo AT logos-m DOT ru>
This file is part of Cygwin.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include <errno.h>
#include <stdio.h>
#include <windows.h>
#include "cygwin/cygserver.h"
SECURITY_ATTRIBUTES sec_none_nih, sec_all_nih;
GENERIC_MAPPING pipe_mapping;
DWORD request_count = 0;
void
init_security ()
{
static SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl (&sd, TRUE, 0, FALSE);
sec_none_nih.nLength = sec_all_nih.nLength = sizeof (SECURITY_ATTRIBUTES);
sec_none_nih.bInheritHandle = sec_all_nih.bInheritHandle = FALSE;
sec_none_nih.lpSecurityDescriptor = NULL;
sec_all_nih.lpSecurityDescriptor = &sd;
pipe_mapping.GenericRead = FILE_READ_DATA;
pipe_mapping.GenericWrite = FILE_WRITE_DATA;
pipe_mapping.GenericExecute = 0;
pipe_mapping.GenericAll = FILE_READ_DATA | FILE_WRITE_DATA;
}
BOOL
setup_privileges ()
{
BOOL rc, ret_val;
HANDLE hToken = NULL;
TOKEN_PRIVILEGES sPrivileges;
rc = OpenProcessToken ( GetCurrentProcess() , TOKEN_ALL_ACCESS , &hToken ) ;
if ( !rc )
{
printf ( "error opening process token (%lu)\n", GetLastError () );
ret_val = FALSE;
goto out;
}
rc = LookupPrivilegeValue ( NULL, SE_DEBUG_NAME, &sPrivileges.Privileges[0].Luid );
if ( !rc )
{
printf ( "error getting prigilege luid (%lu)\n", GetLastError () );
ret_val = FALSE;
goto out;
}
sPrivileges.PrivilegeCount = 1 ;
sPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED ;
rc = AdjustTokenPrivileges ( hToken, FALSE, &sPrivileges, 0, NULL, NULL ) ;
if ( !rc )
{
printf ( "error adjusting prigilege level. (%lu)\n", GetLastError () );
ret_val = FALSE;
goto out;
}
ret_val = TRUE;
out:
CloseHandle ( hToken );
return ret_val;
}
void
get_version (struct request_header* req)
{
struct request_get_version* request = (struct request_get_version*) req;
if (req->cb != sizeof (struct request_get_version))
{
req->error_code = EINVAL;
return;
}
req->error_code = 0;
request->major = CYGWIN_SERVER_VERSION_MAJOR;
request->api = CYGWIN_SERVER_VERSION_API;
request->minor = CYGWIN_SERVER_VERSION_MINOR;
request->patch = CYGWIN_SERVER_VERSION_PATCH;
}
int
check_and_dup_handle (HANDLE from_process, HANDLE to_process,
HANDLE from_process_token,
DWORD access,
HANDLE from_handle,
HANDLE* to_handle_ptr)
{
HANDLE local_handle = NULL;
int ret_val = EACCES;
char sd_buf [1024];
PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR) &sd_buf;
DWORD bytes_needed;
PRIVILEGE_SET ps;
DWORD ps_len = sizeof (ps);
BOOL status;
if (!DuplicateHandle (from_process, from_handle,
GetCurrentProcess (), &local_handle,
0, FALSE,
DUPLICATE_SAME_ACCESS))
{
printf ( "error getting handle(%d) to server (%lu)\n", from_handle, GetLastError ());
goto out;
}
if (!GetKernelObjectSecurity (local_handle,
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
sd, sizeof (sd_buf), &bytes_needed))
{
printf ( "error getting handle SD (%lu)\n", GetLastError ());
goto out;
}
MapGenericMask (&access, &pipe_mapping);
if (!AccessCheck (sd, from_process_token, access, &pipe_mapping,
&ps, &ps_len, &access, &status))
{
printf ( "error checking access rights (%lu)\n", GetLastError ());
goto out;
}
if (!status)
{
printf ( "access to object denied\n");
goto out;
}
if (!DuplicateHandle (from_process, from_handle,
to_process, to_handle_ptr,
access, FALSE, 0))
{
printf ( "error getting handle to client (%lu)\n", GetLastError ());
goto out;
}
ret_val = 0;
out:
if (local_handle)
CloseHandle (local_handle);
return (ret_val);
}
void
attach_tty (HANDLE pipe, struct request_header* req)
{
HANDLE from_process_handle = NULL;
HANDLE to_process_handle = NULL;
HANDLE token_handle = NULL;
DWORD rc;
struct request_attach_tty* request = (struct request_attach_tty*) req;
if (req->cb != sizeof (struct request_attach_tty))
{
req->error_code = EINVAL;
return;
}
#ifdef DEBUG
printf ("%d:(%d,%d) -> %d\n", request->master_pid,
request->from_master, request->to_master,
request->pid);
#endif
from_process_handle = OpenProcess (PROCESS_DUP_HANDLE, FALSE, request->master_pid);
to_process_handle = OpenProcess (PROCESS_DUP_HANDLE, FALSE, request->pid);
if (!from_process_handle || !to_process_handle)
{
printf ("error opening process (%lu)\n", GetLastError ());
req->error_code = EACCES;
goto out;
}
ImpersonateNamedPipeClient (pipe);
rc = OpenThreadToken (GetCurrentThread (),
TOKEN_QUERY,
TRUE,
&token_handle);
RevertToSelf ();
if (!rc)
{
printf ("error opening thread token (%lu)\n", GetLastError ());
req->error_code = EACCES;
goto out;
}
if (check_and_dup_handle (from_process_handle, to_process_handle,
token_handle,
GENERIC_READ,
request->from_master,
&request->from_master) != 0)
{
printf ("error duplicating from_master handle (%lu)\n", GetLastError ());
req->error_code = EACCES;
goto out;
}
if (request->to_master)
{
if (check_and_dup_handle (from_process_handle, to_process_handle,
token_handle,
GENERIC_WRITE,
request->to_master,
&request->to_master) != 0)
{
printf ("error duplicating to_master handle (%lu)\n", GetLastError ());
req->error_code = EACCES;
goto out;
}
}
#ifdef DEBUG
printf ("%d -> %d(%d,%d)\n", request->master_pid, request->pid,
request->from_master, request->to_master);
#endif
req->error_code = 0;
out:
if (from_process_handle)
CloseHandle (from_process_handle);
if (to_process_handle)
CloseHandle (to_process_handle);
if (token_handle)
CloseHandle (token_handle);
}
int
process_request (HANDLE pipe, struct request_header* req)
{
if (!req) return -1;
switch (req->req_id)
{
case CYGSERVER_REQUEST_GET_VERSION:
get_version (req);
break;
case CYGSERVER_REQUEST_ATTACH_TTY:
attach_tty (pipe, req);
break;
default:
req->error_code = ENOSYS;
break;
}
}
DWORD
process_client (HANDLE pipe)
{
DWORD bytes_read, bytes_written, rc;
char request_buffer [MAX_REQUEST_SIZE];
struct request_header* req_ptr = (struct request_header*) &request_buffer;
rc = ReadFile (pipe, &request_buffer,
sizeof (struct request_header), &bytes_read, NULL);
if (!rc || bytes_read != sizeof (struct request_header))
{
printf ("error reading from pipe (%lu)\n", GetLastError ());
goto out;
}
if (req_ptr->cb > MAX_REQUEST_SIZE ||
req_ptr->cb < sizeof (struct request_header))
{
printf ("broken request, size (%lu)\n", req_ptr->cb);
goto out;
}
rc = ReadFile (pipe, ((char*) &request_buffer) + sizeof (struct request_header),
req_ptr->cb - sizeof (struct request_header),
&bytes_read, NULL);
if (!rc || bytes_read != req_ptr->cb - sizeof (struct request_header))
{
printf ("error reading from pipe (%lu)\n", GetLastError ());
goto out;
}
process_request (pipe, req_ptr);
rc = WriteFile (pipe, &request_buffer, req_ptr->cb, &bytes_written, NULL);
if (!rc || bytes_written != req_ptr->cb)
{
printf ("error writing to pipe (%lu)\n", GetLastError ());
goto out;
}
out:
FlushFileBuffers (pipe);
DisconnectNamedPipe (pipe);
CloseHandle ( pipe );
return 0;
}
int
serve_requests ()
{
char pipe_name [MAX_PATH];
init_security ();
sprintf (pipe_name, "\\\\.\\pipe\\cygwin_lpc");
while (TRUE)
{
HANDLE pipe = NULL;
HANDLE thread = NULL;
DWORD tid;
pipe = CreateNamedPipe (pipe_name,
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
0, 0, 1000,
&sec_all_nih );
if (pipe == INVALID_HANDLE_VALUE)
{
printf ("error creating pipe (%lu)\n.", GetLastError ());
goto err;
}
if ( !ConnectNamedPipe ( pipe, NULL ) &&
GetLastError () != ERROR_PIPE_CONNECTED)
{
printf ("error connecting to pipe (%lu)\n.", GetLastError ());
goto err;
}
#ifdef DEBUG
printf ( "request received. total:%8d\n", ++request_count);
#endif
thread = CreateThread (NULL, 0,
(LPTHREAD_START_ROUTINE) process_client,
pipe,
0,
&tid);
if (!thread)
{
printf ("error creating thread (%lu)\n.", GetLastError ());
goto err;
}
CloseHandle (thread);
continue;
err:
if (pipe && pipe != INVALID_HANDLE_VALUE)
CloseHandle (pipe);
Sleep (100);
}
return 0;
}
int
main (int argc, char** argv)
{
init_security ();
setup_privileges ();
serve_requests ();
}
--=-2xW0e3oLK9wHBIYlsOkp
Content-Type: text/x-c
Content-Disposition: attachment; filename=cygserver_client.cc
Content-ID: <1000295528 DOT 30340 DOT 66 DOT camel AT lifelesswks>
Content-Transfer-Encoding: 7bit
/* cygserver_client.cc
Copyright 2001 Red Hat Inc.
Written by Egor Duda <deo AT logos-m DOT ru>
This file is part of Cygwin.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "winsup.h"
#include "cygwin/cygserver.h"
#include "security.h"
int cygserver_running;
const char* pipe_name = "\\\\.\\pipe\\cygwin_lpc";
int
cygserver_request (struct request_header* req)
{
HANDLE pipe = NULL;
int ret_val = -1;
DWORD bytes_read, bytes_written;
if (!cygserver_running)
return ret_val;
if (!req || req->cb > MAX_REQUEST_SIZE)
goto out;
while (TRUE)
{
pipe = CreateFile (pipe_name,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
&sec_all_nih,
OPEN_EXISTING,
0,
NULL);
if (pipe != INVALID_HANDLE_VALUE)
break;
if (GetLastError () != ERROR_PIPE_BUSY)
goto out;
if (!WaitNamedPipe (pipe_name, 20000))
system_printf ( "error connecting to server pipe (%lu)\n", GetLastError () );
}
if (!WriteFile (pipe, req, req->cb, &bytes_written, NULL) ||
bytes_written != req->cb)
goto out;
if (!ReadFile (pipe, req, sizeof (struct request_header),
&bytes_read, NULL) ||
bytes_read != sizeof (struct request_header) ||
req->cb > MAX_REQUEST_SIZE ||
req->cb < sizeof (struct request_header) ||
!ReadFile (pipe, ((char*) req) + sizeof (struct request_header),
req->cb - sizeof (struct request_header),
&bytes_read, NULL) ||
bytes_read != req->cb - sizeof (struct request_header))
goto out;
ret_val = req->error_code;
out:
if (pipe && pipe != INVALID_HANDLE_VALUE)
CloseHandle (pipe);
return (ret_val);
}
BOOL
check_cygserver_available ()
{
BOOL ret_val = FALSE;
HANDLE pipe = CreateFile (pipe_name,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
&sec_all_nih,
OPEN_EXISTING,
0,
NULL);
if (pipe != INVALID_HANDLE_VALUE || GetLastError () != ERROR_PIPE_BUSY)
ret_val = TRUE;
if (pipe && pipe != INVALID_HANDLE_VALUE)
CloseHandle (pipe);
return (ret_val);
}
void
cygserver_init ()
{
int rc;
struct request_get_version request;
INIT_REQUEST (request, CYGSERVER_REQUEST_GET_VERSION);
rc = cygserver_request ((struct request_header*) &request);
if (rc < 0)
cygserver_running = FALSE;
else if (rc > 0)
api_fatal ( "error connecting to cygwin server. error: %d", rc );
else if (request.major != CYGWIN_SERVER_VERSION_MAJOR ||
request.api != CYGWIN_SERVER_VERSION_API ||
request.minor > CYGWIN_SERVER_VERSION_MINOR)
api_fatal ( "incompatible version of cygwin server.\n\
client version %d.%d.%d.%d, server version%d.%d.%d.%d",
CYGWIN_SERVER_VERSION_MAJOR,
CYGWIN_SERVER_VERSION_API,
CYGWIN_SERVER_VERSION_MINOR,
CYGWIN_SERVER_VERSION_PATCH,
request.major,
request.api,
request.minor,
request.patch );
else
cygserver_running = TRUE;
}
--=-2xW0e3oLK9wHBIYlsOkp--
- Raw text -