? cygwin-daemon/.new.ROADMAP ? cygwin-daemon/fhandler.h_new_af_local ? cygwin-daemon/fhandler_local.cc ? cygwin-daemon/fhandler_socket.cc_new_af_local ? cygwin-daemon/net.cc_new_af_local ? cygwin-daemon/SharedMem.cc ? cygwin-daemon/SharedMem.h Index: cygwin-daemon//Makefile.in =================================================================== RCS file: /cvs/src/src/winsup/cygwin/Makefile.in,v retrieving revision 1.63.2.11 diff -u -b -B -r1.63.2.11 Makefile.in --- Makefile.in 2002/01/29 09:48:25 1.63.2.11 +++ Makefile.in 2002/02/10 20:28:49 @@ -51,7 +51,7 @@ # FIXME: Which is it, CC or CC_FOR_TARGET? CC_FOR_TARGET:=$(CC) CFLAGS:=@CFLAGS@ -CFLAGS+=-MMD -fbuiltin +CFLAGS+=-MMD -fbuiltin -DNEW_NET CXX:=@CXX@ CXXFLAGS:=@CXXFLAGS@ @@ -71,7 +71,7 @@ # # Include common definitions for winsup directory # -include $(srcdir)/../Makefile.common +include $(srcdir)/../Makefile.common-daemon INSTALL_DATA:=$(SHELL) $(updir1)/install-sh -c @@ -202,8 +202,8 @@ $(INSTALL_DATA) $$i $(tooldir)/man/man7/`basename $$i` ; \ done -install_target: cygserver.exe - $(INSTALL_PROGRAM) cygserver.exe $(bindir)/cygserver.exe +install-bin: cygserver.exe + $(INSTALL_DATA) cygserver.exe $(bindir)/cygserver.exe install_host: Index: cygwin-daemon//fhandler.h =================================================================== RCS file: /cvs/src/src/winsup/cygwin/fhandler.h,v retrieving revision 1.83.2.4 diff -u -b -B -r1.83.2.4 fhandler.h --- fhandler.h 2002/01/04 03:56:07 1.83.2.4 +++ fhandler.h 2002/02/10 20:28:53 @@ -402,7 +402,41 @@ void signal_secret_event (); void close_secret_event (); int __stdcall fstat (struct stat *buf, path_conv *) __attribute__ ((regparm (3))); +#if NEW_NET + // a FIXME means, this functions isn't moved into class fhandler_socket + // a CHECK means, check this function of valid functionality + + // FIXME: move from net.cc to fhandler_socker.cc + int socketpair (int family, int type, int protocol, int *sb); + // FIXME: move from net.cc to fhandler_socker.cc + int socket (int af, int type, int protocol); + // CHECK: + int bind (const struct sockaddr *my_addr, int addrlen); + // CHECK: + int listen (int backlog); + // CHECK: + int accept (struct sockaddr *peer, int *len); + // CHECK: + int recv (const void *buf, int len, unsigned int flags); + // CHECK: + int send (const void *buf, int len, unsigned int flags); + // CHECK: + int connect (const struct sockaddr *name, int namelen); + // CHECK: + int shutdown (int how); + // CHECK: + int getsockname (struct sockaddr *addr, int *namelen); + // CHECK: + int getpeername (struct sockaddr *name, int *len); +#endif }; + +class fhandler_local: public fhandler_socket +{ + private: + + public: +}; class fhandler_pipe: public fhandler_base { Index: cygwin-daemon//fhandler_socket.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/fhandler_socket.cc,v retrieving revision 1.24.2.2 diff -u -b -B -r1.24.2.2 fhandler_socket.cc --- fhandler_socket.cc 2002/01/04 03:56:08 1.24.2.2 +++ fhandler_socket.cc 2002/02/10 20:28:55 @@ -10,11 +10,14 @@ /* #define DEBUG_NEST_ON 1 */ +#define DEBUG 1 + #define __INSIDE_CYGWIN_NET__ #include "winsup.h" #include #include +#include #include #include @@ -93,7 +96,7 @@ struct sockaddr_in sin; int sin_len = sizeof (sin); - if (getsockname (get_socket (), (struct sockaddr*) &sin, &sin_len)) + if (::getsockname (get_socket (), (struct sockaddr*) &sin, &sin_len)) { debug_printf ("error getting local socket name (%d)", WSAGetLastError ()); return NULL; @@ -255,7 +258,7 @@ fhandler_socket::read (void *ptr, size_t len) { sigframe thisframe (mainthread); - int res = recv (get_socket (), (char *) ptr, len, 0); + int res = ::recv (get_socket (), (char *) ptr, len, 0); if (res == SOCKET_ERROR) set_winsock_errno (); return res; @@ -265,7 +268,7 @@ fhandler_socket::write (const void *ptr, size_t len) { sigframe thisframe (mainthread); - int res = send (get_socket (), (const char *) ptr, len, 0); + int res = ::send (get_socket (), (const char *) ptr, len, 0); if (res == SOCKET_ERROR) { set_winsock_errno (); @@ -488,3 +491,394 @@ cfree (sun_path); sun_path = cstrdup (path); } + +#if NEW_NET +fhandler_socket * +fdsock (int& fd, const char *name, SOCKET soc); + +// FIXME: this class definition is a copy from net.cc and has to updated +// there in case of making any changes here. +// The hack is done, because putting this class from net.cc into fhandler.h +// needs some more work, which I cannot oversee yet. +class wsock_event +{ + WSAEVENT event; + WSAOVERLAPPED ovr; +public: + wsock_event () : event (NULL) {}; + ~wsock_event () + { + if (event) + WSACloseEvent (event); + event = NULL; + }; + + LPWSAOVERLAPPED prepare (); + int wait (int socket, LPDWORD flags); +}; + + +int fhandler_socket::socket (int af, int type, int protocol) +{ + return -1; +} + +int fhandler_socket::bind (const struct sockaddr *my_addr, int addrlen) +{ + int res = -1; + + if (my_addr->sa_family == AF_LOCAL) + { +#define un_addr ((struct sockaddr_un *) my_addr) + struct sockaddr_in sin; + int len = sizeof sin; + + if (strlen (un_addr->sun_path) >= UNIX_PATH_LEN) + { + set_errno (ENAMETOOLONG); + goto out; + } + + sin.sin_family = AF_INET; + sin.sin_port = 0; + sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + if (::bind (get_socket (), (sockaddr *) &sin, len)) + { + syscall_printf ("AF_LOCAL: bind failed %d", get_errno ()); + set_winsock_errno (); + goto out; + } + if (::getsockname (get_socket (), (sockaddr *) &sin, &len)) + { + syscall_printf ("AF_LOCAL: getsockname failed %d", get_errno ()); + set_winsock_errno (); + goto out; + } + + sin.sin_port = ntohs (sin.sin_port); + debug_printf ("AF_LOCAL: socket bound to port %u", sin.sin_port); + + /* bind must fail if file system socket object already exists + so _open () is called with O_EXCL flag. */ + int _fd = _open (un_addr->sun_path, + O_WRONLY | O_CREAT | O_EXCL | O_BINARY, + 0); + if (_fd < 0) + { + if (get_errno () == EEXIST) + set_errno (EADDRINUSE); + goto out; + } + + set_connect_secret (); + + char buf[sizeof (SOCKET_COOKIE) + 80]; + __small_sprintf (buf, "%s%u ", SOCKET_COOKIE, sin.sin_port); + get_connect_secret (strchr (buf, '\0')); + len = strlen (buf) + 1; + + /* Note that the terminating nul is written. */ + if (_write (_fd, buf, len) != len) + { + save_errno here; + _close (_fd); + _unlink (un_addr->sun_path); + } + else + { + _close (_fd); + chmod (un_addr->sun_path, + (S_IFSOCK | S_IRWXU | S_IRWXG | S_IRWXO) & ~cygheap->umask); + set_sun_path (un_addr->sun_path); + res = 0; + } +#undef un_addr + } + else if (::bind (get_socket (), my_addr, addrlen)) + set_winsock_errno (); + else + res = 0; + +out: + return res; +} + +int fhandler_socket::listen (int backlog) +{ + int res = ::listen (get_socket (), backlog); + if (res) + set_winsock_errno (); + return res; +} + +int fhandler_socket::accept (struct sockaddr *peer, int *len) +{ + BOOL secret_check_failed = FALSE; + BOOL in_progress = FALSE; + sigframe thisframe (mainthread); + int res = -1; + { + /* Allows NULL peer and len parameters. */ + struct sockaddr_in peer_dummy; + int len_dummy; + + if (!peer) + peer = (struct sockaddr *) &peer_dummy; + if (!len) + { + len_dummy = sizeof (struct sockaddr_in); + len = &len_dummy; + } + + /* accept on NT fails if len < sizeof (sockaddr_in) + * some programs set len to + * sizeof (name.sun_family) + strlen (name.sun_path) for UNIX domain + */ + if (len && ((unsigned) *len < sizeof (struct sockaddr_in))) + *len = sizeof (struct sockaddr_in); + + res = ::accept (get_socket (), peer, len); // can't use a blocking call inside a lock + + if ((SOCKET) res == (SOCKET) INVALID_SOCKET && + WSAGetLastError () == WSAEWOULDBLOCK) + in_progress = TRUE; + + if (get_addr_family () == AF_LOCAL) + { + if ((SOCKET) res != (SOCKET) INVALID_SOCKET || in_progress) + { + if (!create_secret_event ()) + secret_check_failed = TRUE; + else if (in_progress) + signal_secret_event (); + } + + if (!secret_check_failed && + (SOCKET) res != (SOCKET) INVALID_SOCKET) + { + if (!check_peer_secret_event ((struct sockaddr_in*) peer)) + { + debug_printf ("connect from unauthorized client"); + secret_check_failed = TRUE; + } + } + + if (secret_check_failed) + { + close_secret_event (); + if ((SOCKET) res != (SOCKET) INVALID_SOCKET) + closesocket (res); + set_errno (ECONNABORTED); + res = -1; + goto done; + } + } + + + cygheap_fdnew res_fd; + if (res_fd < 0) + /* FIXME: what is correct errno? */; + else if ((SOCKET) res == (SOCKET) INVALID_SOCKET) + set_winsock_errno (); + else + { + fhandler_socket* res_fh = fdsock (res_fd, get_name (), res); + if (get_addr_family () == AF_LOCAL) + res_fh->set_sun_path (get_sun_path ()); + res_fh->set_addr_family (get_addr_family ()); + res = res_fd; + } + } + done: + return res; + } + +int fhandler_socket::recv (const void *buf, int len, unsigned int flags) +{ + int res = -1; + wsock_event wsock_evt; + LPWSAOVERLAPPED ovr; + sigframe thisframe (mainthread); + + if (is_nonblocking () || !(ovr = wsock_evt.prepare ())) + { + debug_printf ("Fallback to winsock 1 recv call"); + if ((res = ::recv (get_socket (), (char *) buf, len, flags)) + == SOCKET_ERROR) + { + set_winsock_errno (); + res = -1; + } + } + else + { + WSABUF wsabuf = { len, (char *) buf }; + DWORD ret = 0; + if (::WSARecv (get_socket (), &wsabuf, 1, &ret, (DWORD *)&flags, + ovr, NULL) != SOCKET_ERROR) + res = ret; + else if ((res = WSAGetLastError ()) != WSA_IO_PENDING) + { + set_winsock_errno (); + res = -1; + } + else if ((res = wsock_evt.wait (get_socket (), (DWORD *)&flags)) == -1) + set_winsock_errno (); + } + return res; +} + +int fhandler_socket::send (const void *buf, int len, unsigned int flags) +{ + wsock_event wsock_evt; + LPWSAOVERLAPPED ovr; + int res = -1; + sigframe thisframe (mainthread); + + if (is_nonblocking () || !(ovr = wsock_evt.prepare ())) + { + debug_printf ("Fallback to winsock 1 send call"); + if ((res = ::send (get_socket (), (const char *) buf, len, flags)) + == SOCKET_ERROR) + { + set_winsock_errno (); + res = -1; + } + } + else + { + WSABUF wsabuf = { len, (char *) buf }; + DWORD ret = 0; + if (::WSASend (get_socket (), &wsabuf, 1, &ret, (DWORD)flags, + ovr, NULL) != SOCKET_ERROR) + res = ret; + else if ((res = WSAGetLastError ()) != WSA_IO_PENDING) + { + set_winsock_errno (); + res = -1; + } + else if ((res = wsock_evt.wait (get_socket (), (DWORD *)&flags)) == -1) + set_winsock_errno (); + } + return res; +} + +int fhandler_socket::connect (const struct sockaddr *name, int namelen) +{ + BOOL secret_check_failed = FALSE; + BOOL in_progress = FALSE; + sockaddr_in sin; + int secret [4]; + sigframe thisframe (mainthread); + + int res = ::connect (get_socket (), (sockaddr *) &sin, namelen); + if (res) + { + /* Special handling for connect to return the correct error code + when called on a non-blocking socket. */ + if (is_nonblocking ()) + { + DWORD err = WSAGetLastError (); + if (err == WSAEWOULDBLOCK || err == WSAEALREADY) + { + WSASetLastError (WSAEINPROGRESS); + in_progress = TRUE; + } + else if (err == WSAEINVAL) + WSASetLastError (WSAEISCONN); + } + set_winsock_errno (); + } + if (get_addr_family () == AF_LOCAL) + { + if (!res || in_progress) + { + if (!create_secret_event (secret)) + { + secret_check_failed = TRUE; + } + else if (in_progress) + signal_secret_event (); + } + + if (!secret_check_failed && !res) + { + if (!check_peer_secret_event (&sin, secret)) + { + debug_printf ( "accept from unauthorized server" ); + secret_check_failed = TRUE; + } + } + + if (secret_check_failed) + { + close_secret_event (); + if (res) + closesocket (res); + set_errno (ECONNREFUSED); + res = -1; + } + } + return res; +} + +int fhandler_socket::shutdown (int how) +{ + int res = ::shutdown (get_socket (), how); + if (res) + set_winsock_errno (); + else + switch (how) + { + case SHUT_RD: + set_shutdown_read (); + break; + case SHUT_WR: + set_shutdown_write (); + break; + case SHUT_RDWR: + set_shutdown_read (); + set_shutdown_write (); + break; + } + return res; +} + +int fhandler_socket::getsockname (struct sockaddr *addr, int *namelen) +{ + int res = -1; + + if (get_addr_family () == AF_LOCAL) + { + struct sockaddr_un *sun = (struct sockaddr_un *) addr; + memset (sun, 0, *namelen); + sun->sun_family = AF_LOCAL; + /* According to SUSv2 "If the actual length of the address is greater + than the length of the supplied sockaddr structure, the stored + address will be truncated." We play it save here so that the + path always has a trailing 0 even if it's truncated. */ + strncpy (sun->sun_path, get_sun_path (), + *namelen - sizeof *sun + sizeof sun->sun_path - 1); + *namelen = sizeof *sun - sizeof sun->sun_path + + strlen (sun->sun_path) + 1; + res = 0; + } + else + { + res = ::getsockname (get_socket (), addr, namelen); + if (res) + set_winsock_errno (); + } + return res; +} + +int fhandler_socket::getpeername (struct sockaddr *name, int *len) +{ + int res = ::getpeername (get_socket (), name, len); + if (res) + set_winsock_errno (); + return res; +} + +#endif + Index: cygwin-daemon//ipc.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/Attic/ipc.cc,v retrieving revision 1.1.2.1 diff -u -b -B -r1.1.2.1 ipc.cc --- ipc.cc 2001/09/25 06:31:04 1.1.2.1 +++ ipc.cc 2002/02/10 20:28:55 @@ -22,7 +22,7 @@ ftok(const char *path, int id) { struct stat statbuf; - if (stat(path, &statbuf)) + if (stat(path, &statbuf) < 0) { /* stat set the appropriate errno for us */ return (key_t) -1; Index: cygwin-daemon//net.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/net.cc,v retrieving revision 1.77.2.3 diff -u -b -B -r1.77.2.3 net.cc --- net.cc 2002/01/22 04:52:40 1.77.2.3 +++ net.cc 2002/02/10 20:29:01 @@ -879,6 +878,9 @@ if (!sock) res = -1; else +#ifdef NEW_NET + res = sock->connect(name,namelen); +#else { res = connect (sock->get_socket (), (sockaddr *) &sin, namelen); if (res) @@ -929,6 +931,7 @@ } } } +#endif return res; } @@ -1191,6 +1194,9 @@ fhandler_socket *sock = get (fd); if (sock) +#ifdef NEW_NET + res = sock->accept(peer,len); +#else { /* Allows NULL peer and len parameters. */ struct sockaddr_in peer_dummy; @@ -1263,6 +1269,7 @@ } } done: +#endif syscall_printf ("%d = accept (%d, %x, %x)", res, fd, peer, len); return res; } @@ -1278,6 +1285,9 @@ fhandler_socket *sock = get (fd); if (sock) +#ifdef NEW_NET + res = sock->bind(my_addr,addrlen); +#else { if (my_addr->sa_family == AF_LOCAL) { @@ -1352,6 +1362,8 @@ res = 0; } +#endif + out: syscall_printf ("%d = bind (%d, %x, %d)", res, fd, my_addr, addrlen); return res; @@ -1369,6 +1381,9 @@ fhandler_socket *sock = get (fd); if (sock) +#ifdef NEW_NET + res = sock->getsockname(addr,namelen); +#else { if (sock->get_addr_family () == AF_LOCAL) { @@ -1392,6 +1407,7 @@ set_winsock_errno (); } } +#endif syscall_printf ("%d = getsockname (%d, %x, %d)", res, fd, addr, namelen); return res; } @@ -1405,11 +1421,15 @@ fhandler_socket *sock = get (fd); if (sock) +#ifdef NEW_NET + res = sock->listen(backlog); +#else { res = listen (sock->get_socket (), backlog); if (res) set_winsock_errno (); } +#endif syscall_printf ("%d = listen (%d, %d)", res, fd, backlog); return res; } @@ -1423,6 +1443,9 @@ fhandler_socket *sock = get (fd); if (sock) +#ifdef NEW_NET + res = sock->shutdown(how); +#else { res = shutdown (sock->get_socket (), how); if (res) @@ -1442,6 +1465,7 @@ break; } } +#endif syscall_printf ("%d = shutdown (%d, %d)", res, fd, how); return res; } @@ -1507,12 +1530,15 @@ if (!h) res = -1; else +#ifdef NEW_NET + res = h->getpeername(name,len); +#else { res = getpeername (h->get_socket (), name, len); if (res) set_winsock_errno (); } - +#endif debug_printf ("%d = getpeername %d", res, h->get_socket ()); return res; } @@ -1529,6 +1555,9 @@ if (__check_null_invalid_struct_errno (buf, len) || !h) res = -1; else +#ifdef NEW_NET + res = h->recv(buf,len,flags); +#else { sigframe thisframe (mainthread); @@ -1558,7 +1587,7 @@ set_winsock_errno (); } } - +#endif syscall_printf ("%d = recv (%d, %x, %x, %x)", res, fd, buf, len, flags); return res; @@ -1576,6 +1605,9 @@ if (__check_invalid_read_ptr_errno (buf, len) || !h) res = -1; else +#ifdef NEW_NET + res = h->send(buf,len,flags); +#else { sigframe thisframe (mainthread); @@ -1606,6 +1638,7 @@ } } +#endif syscall_printf ("%d = send (%d, %x, %d, %x)", res, fd, buf, len, flags); return res;