* fhandler_socket.cc: New file.
* Makefile.in: Add fhandler_socket.o to dependencies. * fhandler.h: Change comment. * net.cc Move all fhandler_socket methods to fhandler_socket.cc. * winsup.h: Add declaration for `ws2_32_handle'.
This commit is contained in:
parent
dd4f0b2343
commit
afd5033d83
|
@ -1,3 +1,11 @@
|
||||||
|
Fri Oct 27 11:48:00 2000 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* fhandler_socket.cc: New file.
|
||||||
|
* Makefile.in: Add fhandler_socket.o to dependencies.
|
||||||
|
* fhandler.h: Change comment.
|
||||||
|
* net.cc Move all fhandler_socket methods to fhandler_socket.cc.
|
||||||
|
* winsup.h: Add declaration for `ws2_32_handle'.
|
||||||
|
|
||||||
Thu Oct 26 11:51:59 2000 Corinna Vinschen <corinna@vinschen.de>
|
Thu Oct 26 11:51:59 2000 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* dtable.cc (dtable::release): Check for socket. Change
|
* dtable.cc (dtable::release): Check for socket. Change
|
||||||
|
|
|
@ -115,8 +115,8 @@ DLL_IMPORTS:=$(w32api_lib)/libkernel32.a
|
||||||
DLL_OFILES:=assert.o cygheap.o dcrt0.o debug.o delqueue.o dir.o dlfcn.o \
|
DLL_OFILES:=assert.o cygheap.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 \
|
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 \
|
fcntl.o fhandler.o fhandler_clipboard.o fhandler_console.o \
|
||||||
fhandler_floppy.o fhandler_mem.o \
|
fhandler_floppy.o fhandler_mem.o fhandler_random.o fhandler_raw.o \
|
||||||
fhandler_random.o fhandler_raw.o fhandler_serial.o fhandler_tape.o \
|
fhandler_serial.o fhandler_socket.o fhandler_tape.o \
|
||||||
fhandler_termios.o fhandler_tty.o fhandler_windows.o fhandler_zero.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 init.o ioctl.o localtime.o malloc.o \
|
||||||
miscfuncs.o mmap.o \
|
miscfuncs.o mmap.o \
|
||||||
|
|
|
@ -29,7 +29,7 @@ details. */
|
||||||
fhandler_dev_tape (fhandler_tape.cc)
|
fhandler_dev_tape (fhandler_tape.cc)
|
||||||
|
|
||||||
fhandler_pipe
|
fhandler_pipe
|
||||||
fhandler_socket (net.cc)
|
fhandler_socket (fhandler_socket.cc)
|
||||||
|
|
||||||
fhandler_tty_slave (tty.cc)
|
fhandler_tty_slave (tty.cc)
|
||||||
fhandler_pty_master (tty.cc)
|
fhandler_pty_master (tty.cc)
|
||||||
|
|
|
@ -0,0 +1,310 @@
|
||||||
|
/* fhandler_socket.cc. See fhandler.h for a description of the fhandler classes.
|
||||||
|
|
||||||
|
Copyright 2000 Cygnus Solutions.
|
||||||
|
|
||||||
|
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. */
|
||||||
|
|
||||||
|
/* #define DEBUG_NEST_ON 1 */
|
||||||
|
|
||||||
|
#define __INSIDE_CYGWIN_NET__
|
||||||
|
|
||||||
|
#define Win32_Winsock
|
||||||
|
#include "winsup.h"
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include "cygheap.h"
|
||||||
|
#include "cygerrno.h"
|
||||||
|
#include "fhandler.h"
|
||||||
|
#include "dtable.h"
|
||||||
|
#include "sigproc.h"
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* fhandler_socket */
|
||||||
|
|
||||||
|
fhandler_socket::fhandler_socket (const char *name) :
|
||||||
|
fhandler_base (FH_SOCKET, name)
|
||||||
|
{
|
||||||
|
set_cb (sizeof *this);
|
||||||
|
set_need_fork_fixup ();
|
||||||
|
prot_info_ptr = (LPWSAPROTOCOL_INFOA) cmalloc (HEAP_BUF,
|
||||||
|
sizeof (WSAPROTOCOL_INFOA));
|
||||||
|
}
|
||||||
|
|
||||||
|
fhandler_socket::~fhandler_socket ()
|
||||||
|
{
|
||||||
|
if (prot_info_ptr)
|
||||||
|
cfree (prot_info_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_socket::fixup_before_fork_exec (DWORD win_proc_id)
|
||||||
|
{
|
||||||
|
int ret = 1;
|
||||||
|
|
||||||
|
if (prot_info_ptr &&
|
||||||
|
(ret = WSADuplicateSocketA (get_socket (), win_proc_id, prot_info_ptr)))
|
||||||
|
{
|
||||||
|
debug_printf ("WSADuplicateSocket error");
|
||||||
|
set_winsock_errno ();
|
||||||
|
}
|
||||||
|
if (!ret && ws2_32_handle)
|
||||||
|
{
|
||||||
|
debug_printf ("WSADuplicateSocket went fine, dwServiceFlags1=%d",
|
||||||
|
prot_info_ptr->dwServiceFlags1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fhandler_base::fixup_before_fork_exec (win_proc_id);
|
||||||
|
debug_printf ("Without Winsock 2.0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_socket::fixup_after_fork (HANDLE parent)
|
||||||
|
{
|
||||||
|
SOCKET new_sock = INVALID_SOCKET;
|
||||||
|
|
||||||
|
debug_printf ("WSASocket begin, dwServiceFlags1=%d",
|
||||||
|
prot_info_ptr->dwServiceFlags1);
|
||||||
|
if (prot_info_ptr &&
|
||||||
|
(new_sock = WSASocketA (FROM_PROTOCOL_INFO,
|
||||||
|
FROM_PROTOCOL_INFO,
|
||||||
|
FROM_PROTOCOL_INFO,
|
||||||
|
prot_info_ptr, 0, 0)) == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
debug_printf ("WSASocket error");
|
||||||
|
set_winsock_errno ();
|
||||||
|
}
|
||||||
|
if (new_sock != INVALID_SOCKET && ws2_32_handle)
|
||||||
|
{
|
||||||
|
debug_printf ("WSASocket went fine");
|
||||||
|
set_io_handle ((HANDLE) new_sock);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fhandler_base::fixup_after_fork (parent);
|
||||||
|
debug_printf ("Without Winsock 2.0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_socket::dup (fhandler_base *child)
|
||||||
|
{
|
||||||
|
fhandler_socket *fhs = (fhandler_socket *) child;
|
||||||
|
fhs->set_io_handle (get_io_handle ());
|
||||||
|
fhs->fixup_before_fork_exec (GetCurrentProcessId ());
|
||||||
|
if (ws2_32_handle)
|
||||||
|
{
|
||||||
|
fhs->fixup_after_fork (hMainProc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return fhandler_base::dup (child);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_socket::read (void *ptr, size_t len)
|
||||||
|
{
|
||||||
|
sigframe thisframe (mainthread);
|
||||||
|
int res = recv (get_socket (), (char *) ptr, len, 0);
|
||||||
|
if (res == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
set_winsock_errno ();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_socket::write (const void *ptr, size_t len)
|
||||||
|
{
|
||||||
|
sigframe thisframe (mainthread);
|
||||||
|
int res = send (get_socket (), (const char *) ptr, len, 0);
|
||||||
|
if (res == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
set_winsock_errno ();
|
||||||
|
if (get_errno () == ECONNABORTED || get_errno () == ECONNRESET)
|
||||||
|
_raise (SIGPIPE);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cygwin internal */
|
||||||
|
int
|
||||||
|
fhandler_socket::close ()
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
sigframe thisframe (mainthread);
|
||||||
|
|
||||||
|
if (closesocket (get_socket ()))
|
||||||
|
{
|
||||||
|
set_winsock_errno ();
|
||||||
|
res = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ASYNC_MASK (FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT)
|
||||||
|
|
||||||
|
/* Cygwin internal */
|
||||||
|
int
|
||||||
|
fhandler_socket::ioctl (unsigned int cmd, void *p)
|
||||||
|
{
|
||||||
|
extern int get_ifconf (struct ifconf *ifc, int what); /* net.cc */
|
||||||
|
int res;
|
||||||
|
struct ifconf *ifc;
|
||||||
|
struct ifreq *ifr;
|
||||||
|
sigframe thisframe (mainthread);
|
||||||
|
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case SIOCGIFCONF:
|
||||||
|
ifc = (struct ifconf *) p;
|
||||||
|
if (ifc == 0)
|
||||||
|
{
|
||||||
|
set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
res = get_ifconf (ifc, cmd);
|
||||||
|
if (res)
|
||||||
|
debug_printf ("error in get_ifconf\n");
|
||||||
|
break;
|
||||||
|
case SIOCGIFFLAGS:
|
||||||
|
ifr = (struct ifreq *) p;
|
||||||
|
if (ifr == 0)
|
||||||
|
{
|
||||||
|
set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ifr->ifr_flags = IFF_NOTRAILERS | IFF_UP | IFF_RUNNING;
|
||||||
|
if (((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr
|
||||||
|
== INADDR_LOOPBACK)
|
||||||
|
ifr->ifr_flags |= IFF_LOOPBACK;
|
||||||
|
else
|
||||||
|
ifr->ifr_flags |= IFF_BROADCAST;
|
||||||
|
res = 0;
|
||||||
|
break;
|
||||||
|
case SIOCGIFBRDADDR:
|
||||||
|
case SIOCGIFNETMASK:
|
||||||
|
case SIOCGIFADDR:
|
||||||
|
{
|
||||||
|
char buf[2048];
|
||||||
|
struct ifconf ifc;
|
||||||
|
ifc.ifc_len = sizeof (buf);
|
||||||
|
ifc.ifc_buf = buf;
|
||||||
|
struct ifreq *ifrp;
|
||||||
|
|
||||||
|
struct ifreq *ifr = (struct ifreq *) p;
|
||||||
|
if (ifr == 0)
|
||||||
|
{
|
||||||
|
debug_printf ("ifr == NULL\n");
|
||||||
|
set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = get_ifconf (&ifc, cmd);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
debug_printf ("error in get_ifconf\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_printf (" name: %s\n", ifr->ifr_name);
|
||||||
|
for (ifrp = ifc.ifc_req;
|
||||||
|
(caddr_t) ifrp < ifc.ifc_buf + ifc.ifc_len;
|
||||||
|
++ifrp)
|
||||||
|
{
|
||||||
|
debug_printf ("testname: %s\n", ifrp->ifr_name);
|
||||||
|
if (! strcmp (ifrp->ifr_name, ifr->ifr_name))
|
||||||
|
{
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case SIOCGIFADDR:
|
||||||
|
ifr->ifr_addr = ifrp->ifr_addr;
|
||||||
|
break;
|
||||||
|
case SIOCGIFBRDADDR:
|
||||||
|
ifr->ifr_broadaddr = ifrp->ifr_broadaddr;
|
||||||
|
break;
|
||||||
|
case SIOCGIFNETMASK:
|
||||||
|
ifr->ifr_netmask = ifrp->ifr_netmask;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((caddr_t) ifrp >= ifc.ifc_buf + ifc.ifc_len)
|
||||||
|
{
|
||||||
|
set_errno (EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FIOASYNC:
|
||||||
|
res = WSAAsyncSelect (get_socket (), gethwnd (), WM_ASYNCIO,
|
||||||
|
*(int *) p ? ASYNC_MASK : 0);
|
||||||
|
syscall_printf ("Async I/O on socket %s",
|
||||||
|
*(int *) p ? "started" : "cancelled");
|
||||||
|
set_async (*(int *) p);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* We must cancel WSAAsyncSelect (if any) before setting socket to
|
||||||
|
* blocking mode
|
||||||
|
*/
|
||||||
|
if (cmd == FIONBIO && *(int *) p == 0)
|
||||||
|
WSAAsyncSelect (get_socket (), gethwnd (), 0, 0);
|
||||||
|
res = ioctlsocket (get_socket (), cmd, (unsigned long *) p);
|
||||||
|
if (res == SOCKET_ERROR)
|
||||||
|
set_winsock_errno ();
|
||||||
|
if (cmd == FIONBIO)
|
||||||
|
{
|
||||||
|
syscall_printf ("socket is now %sblocking",
|
||||||
|
*(int *) p ? "un" : "");
|
||||||
|
/* Start AsyncSelect if async socket unblocked */
|
||||||
|
if (*(int *) p && get_async ())
|
||||||
|
WSAAsyncSelect (get_socket (), gethwnd (), WM_ASYNCIO, ASYNC_MASK);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
syscall_printf ("%d = ioctl_socket (%x, %x)", res, cmd, p);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_socket::fcntl (int cmd, void *arg)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
int request, current;
|
||||||
|
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case F_SETFL:
|
||||||
|
{
|
||||||
|
/* Care for the old O_NDELAY flag. If one of the flags is set,
|
||||||
|
both flags are set. */
|
||||||
|
int new_flags = (int) arg;
|
||||||
|
if (new_flags & (O_NONBLOCK | OLD_O_NDELAY))
|
||||||
|
new_flags |= O_NONBLOCK | OLD_O_NDELAY;
|
||||||
|
request = (new_flags & O_NONBLOCK) ? 1 : 0;
|
||||||
|
current = (get_flags () & O_NONBLOCK) ? 1 : 0;
|
||||||
|
if (request != current && (res = ioctl (FIONBIO, &request)))
|
||||||
|
break;
|
||||||
|
if (request)
|
||||||
|
set_flags (get_flags () | O_NONBLOCK | OLD_O_NDELAY);
|
||||||
|
else
|
||||||
|
set_flags (get_flags () & ~(O_NONBLOCK | OLD_O_NDELAY));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
res = fhandler_base::fcntl (cmd, arg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
|
@ -44,8 +44,7 @@ int __stdcall rresvport (int *);
|
||||||
int sscanf (const char *, const char *, ...);
|
int sscanf (const char *, const char *, ...);
|
||||||
} /* End of "C" section */
|
} /* End of "C" section */
|
||||||
|
|
||||||
extern HANDLE ws2_32_handle;
|
static WSADATA wsadata;
|
||||||
WSADATA wsadata;
|
|
||||||
|
|
||||||
/* Cygwin internal */
|
/* Cygwin internal */
|
||||||
static SOCKET __stdcall
|
static SOCKET __stdcall
|
||||||
|
@ -1514,7 +1513,7 @@ out:
|
||||||
ifc->ifc_len = cnt * sizeof (struct ifreq);
|
ifc->ifc_len = cnt * sizeof (struct ifreq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
get_ifconf (struct ifconf *ifc, int what)
|
get_ifconf (struct ifconf *ifc, int what)
|
||||||
{
|
{
|
||||||
unsigned long lip, lnp;
|
unsigned long lip, lnp;
|
||||||
|
@ -1783,300 +1782,6 @@ endhostent (void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************/
|
|
||||||
/* fhandler_socket */
|
|
||||||
|
|
||||||
fhandler_socket::fhandler_socket (const char *name) :
|
|
||||||
fhandler_base (FH_SOCKET, name)
|
|
||||||
{
|
|
||||||
set_cb (sizeof *this);
|
|
||||||
set_need_fork_fixup ();
|
|
||||||
prot_info_ptr = (LPWSAPROTOCOL_INFOA) cmalloc (HEAP_BUF,
|
|
||||||
sizeof (WSAPROTOCOL_INFOA));
|
|
||||||
}
|
|
||||||
|
|
||||||
fhandler_socket::~fhandler_socket ()
|
|
||||||
{
|
|
||||||
if (prot_info_ptr)
|
|
||||||
cfree (prot_info_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
fhandler_socket::fixup_before_fork_exec (DWORD win_proc_id)
|
|
||||||
{
|
|
||||||
int ret = 1;
|
|
||||||
|
|
||||||
if (prot_info_ptr &&
|
|
||||||
(ret = WSADuplicateSocketA (get_socket (), win_proc_id, prot_info_ptr)))
|
|
||||||
{
|
|
||||||
debug_printf ("WSADuplicateSocket error");
|
|
||||||
set_winsock_errno ();
|
|
||||||
}
|
|
||||||
if (!ret && ws2_32_handle)
|
|
||||||
{
|
|
||||||
debug_printf ("WSADuplicateSocket went fine, dwServiceFlags1=%d",
|
|
||||||
prot_info_ptr->dwServiceFlags1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fhandler_base::fixup_before_fork_exec (win_proc_id);
|
|
||||||
debug_printf ("Without Winsock 2.0");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
fhandler_socket::fixup_after_fork (HANDLE parent)
|
|
||||||
{
|
|
||||||
SOCKET new_sock = INVALID_SOCKET;
|
|
||||||
|
|
||||||
debug_printf ("WSASocket begin, dwServiceFlags1=%d",
|
|
||||||
prot_info_ptr->dwServiceFlags1);
|
|
||||||
if (prot_info_ptr &&
|
|
||||||
(new_sock = WSASocketA (FROM_PROTOCOL_INFO,
|
|
||||||
FROM_PROTOCOL_INFO,
|
|
||||||
FROM_PROTOCOL_INFO,
|
|
||||||
prot_info_ptr, 0, 0)) == INVALID_SOCKET)
|
|
||||||
{
|
|
||||||
debug_printf ("WSASocket error");
|
|
||||||
set_winsock_errno ();
|
|
||||||
}
|
|
||||||
if (new_sock != INVALID_SOCKET && ws2_32_handle)
|
|
||||||
{
|
|
||||||
debug_printf ("WSASocket went fine");
|
|
||||||
set_io_handle ((HANDLE) new_sock);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fhandler_base::fixup_after_fork (parent);
|
|
||||||
debug_printf ("Without Winsock 2.0");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
fhandler_socket::dup (fhandler_base *child)
|
|
||||||
{
|
|
||||||
fhandler_socket *fhs = (fhandler_socket *) child;
|
|
||||||
fhs->set_io_handle (get_io_handle ());
|
|
||||||
fhs->fixup_before_fork_exec (GetCurrentProcessId ());
|
|
||||||
if (ws2_32_handle)
|
|
||||||
{
|
|
||||||
fhs->fixup_after_fork (hMainProc);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return fhandler_base::dup (child);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
fhandler_socket::read (void *ptr, size_t len)
|
|
||||||
{
|
|
||||||
sigframe thisframe (mainthread);
|
|
||||||
int res = recv (get_socket (), (char *) ptr, len, 0);
|
|
||||||
if (res == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
set_winsock_errno ();
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
fhandler_socket::write (const void *ptr, size_t len)
|
|
||||||
{
|
|
||||||
sigframe thisframe (mainthread);
|
|
||||||
int res = send (get_socket (), (const char *) ptr, len, 0);
|
|
||||||
if (res == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
set_winsock_errno ();
|
|
||||||
if (get_errno () == ECONNABORTED || get_errno () == ECONNRESET)
|
|
||||||
_raise (SIGPIPE);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cygwin internal */
|
|
||||||
int
|
|
||||||
fhandler_socket::close ()
|
|
||||||
{
|
|
||||||
int res = 0;
|
|
||||||
sigframe thisframe (mainthread);
|
|
||||||
|
|
||||||
if (closesocket (get_socket ()))
|
|
||||||
{
|
|
||||||
set_winsock_errno ();
|
|
||||||
res = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cygwin internal */
|
|
||||||
/*
|
|
||||||
* Return the flags settings for an interface.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
get_if_flags (struct ifreq *ifr)
|
|
||||||
{
|
|
||||||
struct sockaddr_in *sa = (struct sockaddr_in *) &ifr->ifr_addr;
|
|
||||||
|
|
||||||
short flags = IFF_NOTRAILERS | IFF_UP | IFF_RUNNING;
|
|
||||||
if (sa->sin_addr.s_addr == INADDR_LOOPBACK)
|
|
||||||
flags |= IFF_LOOPBACK;
|
|
||||||
else
|
|
||||||
flags |= IFF_BROADCAST;
|
|
||||||
|
|
||||||
ifr->ifr_flags = flags;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ASYNC_MASK (FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT)
|
|
||||||
|
|
||||||
/* Cygwin internal */
|
|
||||||
int
|
|
||||||
fhandler_socket::ioctl (unsigned int cmd, void *p)
|
|
||||||
{
|
|
||||||
int res;
|
|
||||||
struct ifconf *ifc;
|
|
||||||
struct ifreq *ifr;
|
|
||||||
sigframe thisframe (mainthread);
|
|
||||||
|
|
||||||
switch (cmd)
|
|
||||||
{
|
|
||||||
case SIOCGIFCONF:
|
|
||||||
ifc = (struct ifconf *) p;
|
|
||||||
if (ifc == 0)
|
|
||||||
{
|
|
||||||
set_errno (EINVAL);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
res = get_ifconf (ifc, cmd);
|
|
||||||
if (res)
|
|
||||||
debug_printf ("error in get_ifconf\n");
|
|
||||||
break;
|
|
||||||
case SIOCGIFFLAGS:
|
|
||||||
ifr = (struct ifreq *) p;
|
|
||||||
if (ifr == 0)
|
|
||||||
{
|
|
||||||
set_errno (EINVAL);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
res = get_if_flags (ifr);
|
|
||||||
break;
|
|
||||||
case SIOCGIFBRDADDR:
|
|
||||||
case SIOCGIFNETMASK:
|
|
||||||
case SIOCGIFADDR:
|
|
||||||
{
|
|
||||||
char buf[2048];
|
|
||||||
struct ifconf ifc;
|
|
||||||
ifc.ifc_len = sizeof (buf);
|
|
||||||
ifc.ifc_buf = buf;
|
|
||||||
struct ifreq *ifrp;
|
|
||||||
|
|
||||||
struct ifreq *ifr = (struct ifreq *) p;
|
|
||||||
if (ifr == 0)
|
|
||||||
{
|
|
||||||
debug_printf ("ifr == NULL\n");
|
|
||||||
set_errno (EINVAL);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = get_ifconf (&ifc, cmd);
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
debug_printf ("error in get_ifconf\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
debug_printf (" name: %s\n", ifr->ifr_name);
|
|
||||||
for (ifrp = ifc.ifc_req;
|
|
||||||
(caddr_t) ifrp < ifc.ifc_buf + ifc.ifc_len;
|
|
||||||
++ifrp)
|
|
||||||
{
|
|
||||||
debug_printf ("testname: %s\n", ifrp->ifr_name);
|
|
||||||
if (! strcmp (ifrp->ifr_name, ifr->ifr_name))
|
|
||||||
{
|
|
||||||
switch (cmd)
|
|
||||||
{
|
|
||||||
case SIOCGIFADDR:
|
|
||||||
ifr->ifr_addr = ifrp->ifr_addr;
|
|
||||||
break;
|
|
||||||
case SIOCGIFBRDADDR:
|
|
||||||
ifr->ifr_broadaddr = ifrp->ifr_broadaddr;
|
|
||||||
break;
|
|
||||||
case SIOCGIFNETMASK:
|
|
||||||
ifr->ifr_netmask = ifrp->ifr_netmask;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((caddr_t) ifrp >= ifc.ifc_buf + ifc.ifc_len)
|
|
||||||
{
|
|
||||||
set_errno (EINVAL);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FIOASYNC:
|
|
||||||
res = WSAAsyncSelect (get_socket (), gethwnd (), WM_ASYNCIO,
|
|
||||||
*(int *) p ? ASYNC_MASK : 0);
|
|
||||||
syscall_printf ("Async I/O on socket %s",
|
|
||||||
*(int *) p ? "started" : "cancelled");
|
|
||||||
set_async (*(int *) p);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* We must cancel WSAAsyncSelect (if any) before setting socket to
|
|
||||||
* blocking mode
|
|
||||||
*/
|
|
||||||
if (cmd == FIONBIO && *(int *) p == 0)
|
|
||||||
WSAAsyncSelect (get_socket (), gethwnd (), 0, 0);
|
|
||||||
res = ioctlsocket (get_socket (), cmd, (unsigned long *) p);
|
|
||||||
if (res == SOCKET_ERROR)
|
|
||||||
set_winsock_errno ();
|
|
||||||
if (cmd == FIONBIO)
|
|
||||||
{
|
|
||||||
syscall_printf ("socket is now %sblocking",
|
|
||||||
*(int *) p ? "un" : "");
|
|
||||||
/* Start AsyncSelect if async socket unblocked */
|
|
||||||
if (*(int *) p && get_async ())
|
|
||||||
WSAAsyncSelect (get_socket (), gethwnd (), WM_ASYNCIO, ASYNC_MASK);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
syscall_printf ("%d = ioctl_socket (%x, %x)", res, cmd, p);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
fhandler_socket::fcntl (int cmd, void *arg)
|
|
||||||
{
|
|
||||||
int res = 0;
|
|
||||||
int request, current;
|
|
||||||
|
|
||||||
switch (cmd)
|
|
||||||
{
|
|
||||||
case F_SETFL:
|
|
||||||
{
|
|
||||||
/* Care for the old O_NDELAY flag. If one of the flags is set,
|
|
||||||
both flags are set. */
|
|
||||||
int new_flags = (int) arg;
|
|
||||||
if (new_flags & (O_NONBLOCK | OLD_O_NDELAY))
|
|
||||||
new_flags |= O_NONBLOCK | OLD_O_NDELAY;
|
|
||||||
request = (new_flags & O_NONBLOCK) ? 1 : 0;
|
|
||||||
current = (get_flags () & O_NONBLOCK) ? 1 : 0;
|
|
||||||
if (request != current && (res = ioctl (FIONBIO, &request)))
|
|
||||||
break;
|
|
||||||
if (request)
|
|
||||||
set_flags (get_flags () | O_NONBLOCK | OLD_O_NDELAY);
|
|
||||||
else
|
|
||||||
set_flags (get_flags () & ~(O_NONBLOCK | OLD_O_NDELAY));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
res = fhandler_base::fcntl (cmd, arg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wsock_init ()
|
wsock_init ()
|
||||||
{
|
{
|
||||||
|
|
|
@ -173,6 +173,7 @@ void __stdcall window_terminate (void);
|
||||||
|
|
||||||
/* Globals that handle initialization of winsock in a child process. */
|
/* Globals that handle initialization of winsock in a child process. */
|
||||||
extern HANDLE wsock32_handle;
|
extern HANDLE wsock32_handle;
|
||||||
|
extern HANDLE ws2_32_handle;
|
||||||
|
|
||||||
/* Globals that handle initialization of netapi in a child process. */
|
/* Globals that handle initialization of netapi in a child process. */
|
||||||
extern HANDLE netapi32_handle;
|
extern HANDLE netapi32_handle;
|
||||||
|
|
Loading…
Reference in New Issue