more sock options.

This commit is contained in:
Kelvin Sherlock 2012-05-07 22:41:45 -04:00
parent 5476bf616d
commit ecb8e59d6d
3 changed files with 158 additions and 107 deletions

View File

@ -33,6 +33,11 @@ typedef struct Entry {
unsigned _NONBLOCK:1; unsigned _NONBLOCK:1;
//setsockopt(2) //setsockopt(2)
unsigned _DEBUG:1;
unsigned _REUSEADDR:1;
unsigned _REUSEPORT:1;
unsigned _KEEPALIVE:1;
unsigned _OOBINLINE:1; unsigned _OOBINLINE:1;
unsigned _LINGER:1; unsigned _LINGER:1;
unsigned _NOSIGPIPE:1; unsigned _NOSIGPIPE:1;
@ -60,6 +65,8 @@ typedef struct xsockaddr_in {
#define DecBusy() asm { jsl 0xE10068 } #define DecBusy() asm { jsl 0xE10068 }
#define Resched() asm { cop 0x7f } #define Resched() asm { cop 0x7f }
#define BusyFlag ((byte *)0xE100FFl)
#define SEI() asm { sei } #define SEI() asm { sei }
#define CLI() asm { cli } #define CLI() asm { cli }
@ -95,6 +102,8 @@ int mgetsockopt(Entry *, void *p1, void *p2, void *p3, void *p4, void *p5);
int msetsockopt(Entry *, void *p1, void *p2, void *p3, void *p4, void *p5); int msetsockopt(Entry *, void *p1, void *p2, void *p3, void *p4, void *p5);
int mioctl(Entry *, void *p1, void *p2, void *p3, void *p4, void *p5); int mioctl(Entry *, void *p1, void *p2, void *p3, void *p4, void *p5);
int mgetsockname(Entry *, void *p1, void *p2, void *p3, void *p4, void *p5);
int mselect(Entry *, void *p1, void *p2, void *p3, void *p4, void *p5);

View File

@ -30,6 +30,38 @@ static void ticks_to_timeval(LongWord ticks, struct timeval *tv)
} }
static int set_flag(void *p, int size, int flag)
{
if (size == 4)
{
*(long *)p = flag;
return 0;
}
if (size == 2)
{
*(int *)p = flag;
return 0;
}
return EINVAL;
}
static int set_flag_long(void *p, int size, long flag)
{
if (size == 4)
{
*(long *)p = flag;
return 0;
}
if (size == 2)
{
*(int *)p = flag;
return 0;
}
return EINVAL;
}
int mgetsockopt(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5) int mgetsockopt(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5)
{ {
Word terr; Word terr;
@ -44,68 +76,43 @@ int mgetsockopt(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5)
if (!optval) return EINVAL; if (!optval) return EINVAL;
// todo -- should set optlen = returned size.
// todo -- linger // todo -- linger
switch (optname) switch (optname)
{ {
case SO_TYPE: case SO_TYPE:
// todo... non-stream // todo... non-stream
if (optlen == 4) return set_flag(optval, optlen, SOCK_STREAM);
{
*(LongWord *)optval = SOCK_STREAM;
return 0;
}
if (optlen == 2)
{
*(Word *)optval = SOCK_STREAM;
return 0;
}
break; break;
case SO_DEBUG:
return set_flag(optval, optlen, e->_DEBUG);
break;
case SO_REUSEADDR:
return set_flag(optval, optlen, e->_REUSEADDR);
break;
case SO_REUSEPORT:
return set_flag(optval, optlen, e->_REUSEPORT);
break;
case SO_KEEPALIVE:
return set_flag(optval, optlen, e->_KEEPALIVE);
break;
case SO_OOBINLINE: case SO_OOBINLINE:
if (optlen == 4) return set_flag(optval, optlen, 1);
{
*(LongWord *)optval = 1;
return 0;
}
if (optlen == 2)
{
*(Word *)optval = 1;
return 0;
}
if (optlen == 1)
{
*(char *)optval = 1;
return 0;
}
break; break;
case SO_SNDLOWAT: case SO_SNDLOWAT:
if (optlen == 4) return set_flag(optval, optlen, e->_SNDLOWAT);
{
*(LongWord *)optval = e->_SNDLOWAT;
return 0;
}
if (optlen == 2)
{
*(Word *)optval = e->_SNDLOWAT;
return 0;
}
break; break;
case SO_RCVLOWAT: case SO_RCVLOWAT:
if (optlen == 4) return set_flag(optval, optlen, e->_RCVLOWAT);
{
*(LongWord *)optval = e->_RCVLOWAT;
return 0;
}
if (optlen == 2)
{
*(Word *)optval = e->_RCVLOWAT;
return 0;
}
break; break;
case SO_SNDTIMEO: case SO_SNDTIMEO:
@ -135,19 +142,11 @@ int mgetsockopt(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5)
IncBusy(); IncBusy();
terr = TCPIPStatusTCP(e->ipid, &e->sr); terr = TCPIPStatusTCP(e->ipid, &e->sr);
t = _toolErr; t = _toolErr;
DecBusy();
if (t) terr = t; if (t) terr = t;
e->terr = terr;
DecBusy();
if (optlen == 4) return set_flag_long(optval, optlen, e->sr.srRcvQueued);
{
*(LongWord *)optval = e->sr.srRcvQueued;
return 0;
}
if (optlen == 2)
{
*(Word *)optval = e->sr.srRcvQueued;
return 0;
}
break; break;
#endif #endif
@ -157,20 +156,11 @@ int mgetsockopt(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5)
IncBusy(); IncBusy();
terr = TCPIPStatusTCP(e->ipid, &e->sr); terr = TCPIPStatusTCP(e->ipid, &e->sr);
t = _toolErr; t = _toolErr;
DecBusy();
if (t) terr = t; if (t) terr = t;
e->terr = terr;
DecBusy();
if (optlen == 4) return set_flag_long(optval, optlen, e->sr.srSndQueued);
{
*(LongWord *)optval = e->sr.srSndQueued;
return 0;
}
if (optlen == 2)
{
*(Word *)optval = e->sr.srSndQueued;
return 0;
}
return EINVAL;
break; break;
#endif #endif

View File

@ -30,11 +30,53 @@ static LongWord timeval_to_ticks(struct timeval tv)
return rv; return rv;
} }
static boolean get_flag(void *p, int size, Word *flag)
{
if (size == 4)
{
*flag = *(LongWord *)flag;
return true;
}
if (size == 2)
{
*flag = *(Word *)flag;
return true;
}
if (size == 1)
{
*flag = *(Byte *)flag;
return true;
}
return false;
}
static boolean get_flag_long(void *p, int size, LongWord *flag)
{
if (size == 4)
{
*flag = *(LongWord *)flag;
return true;
}
if (size == 2)
{
*flag = *(Word *)flag;
return true;
}
if (size == 1)
{
*flag = *(Byte *)flag;
return true;
}
return false;
}
int msetsockopt(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5) int msetsockopt(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5)
{ {
Word terr; Word terr;
Word t; Word t;
Word flag;
int level = *(int *)p1; int level = *(int *)p1;
int optname = *(int *)p2; int optname = *(int *)p2;
@ -49,52 +91,62 @@ int msetsockopt(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5)
switch(optname) switch(optname)
{ {
case SO_DEBUG:
if (!get_flag(optval, optlen, &flag))
return EINVAL;
e->_DEBUG = flag ? 1 : 0;
return 0;
case SO_REUSEADDR:
if (!get_flag(optval, optlen, &flag))
return EINVAL;
e->_REUSEADDR = flag ? 1 : 0;
return 0;
case SO_REUSEPORT:
if (!get_flag(optval, optlen, &flag))
return EINVAL;
e->_REUSEPORT = flag ? 1 : 0;
return 0;
case SO_DEBUG:
if (!get_flag(optval, optlen, &flag))
return EINVAL;
e->_DEBUG = flag ? 1 : 0;
return 0;
case SO_KEEPALIVE:
if (!get_flag(optval, optlen, &flag))
return EINVAL;
e->_KEEPALIVE = flag ? 1 : 0;
return 0;
case SO_OOBINLINE: case SO_OOBINLINE:
if (optlen == 4) // always 1.
{ if (!get_flag(optval, optlen, &flag))
Word flag = *(LongWord *)optval; return EINVAL;
if (!flag) return EINVAL; if (!flag)
return 0; return EINVAL;
} return 0;
if (optlen == 2)
{
Word flag = *(Word *)optval;
if (!flag) return EINVAL;
return 0;
}
if (optlen == 1)
{
Word flag = *(char *)optval;
if (!flag) return EINVAL;
return 0;
}
break; break;
case SO_SNDLOWAT: case SO_SNDLOWAT:
if (optlen == 4) // 0 is valid.
{ if (!get_flag_long(optval, optlen, &e->_SNDLOWAT))
e->_SNDLOWAT = *(LongWord *)optval; return EINVAL;
return 0; return 0;
}
if (optlen == 2)
{
e->_SNDLOWAT = *(Word *)optval;
return 0;
}
break; break;
case SO_RCVLOWAT: case SO_RCVLOWAT:
if (optlen == 4) // min size = 1.
{ if (!get_flag_long(optval, optlen, &e->_RCVLOWAT))
e->_RCVLOWAT = *(LongWord *)optval; return EINVAL;
return 0; if (e->_RCVLOWAT) return 0;
}
if (optlen == 2) e->_RCVLOWAT = 1;
{ return EINVAL;
e->_RCVLOWAT = *(Word *)optval;
return 0;
}
break; break;
case SO_SNDTIMEO: case SO_SNDTIMEO: