Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-developers-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin-developers AT sources DOT redhat DOT com Subject: Egor's daemon From: Robert Collins To: cygwin-developers AT cygwin DOT com Cc: cygwin-patches AT cygwin-com Content-Type: multipart/mixed; boundary="=-2xW0e3oLK9wHBIYlsOkp" X-Mailer: Evolution/0.13 (Preview Release) Date: 12 Sep 2001 21:52:14 +1000 Message-Id: <1000295535.30404.67.camel@lifelesswks> Mime-Version: 1.0 X-OriginalArrivalTime: 12 Sep 2001 11:39:05.0048 (UTC) FILETIME=[86BCA580:01C13B7F] --=-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 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 #include #include #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 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--