misc updates
This commit is contained in:
parent
050fd731df
commit
f14c62511b
334
marignotti.c
334
marignotti.c
|
@ -36,9 +36,28 @@ int semID;
|
||||||
// this will be used to hold extra info (sockopts, etc)
|
// this will be used to hold extra info (sockopts, etc)
|
||||||
// as well as to keep a list of ipids waiting to close.
|
// as well as to keep a list of ipids waiting to close.
|
||||||
|
|
||||||
|
struct flags {
|
||||||
|
// shutdown(2)
|
||||||
|
Word _SHUT_RD:1;
|
||||||
|
Word _SHUT_WR:1;
|
||||||
|
|
||||||
|
// fcntl(2)
|
||||||
|
Word _NONBLOCK:1;
|
||||||
|
|
||||||
|
// setsockopt()
|
||||||
|
Word _OOBINLINE:1;
|
||||||
|
Word _LINGER:1;
|
||||||
|
Word _NOSIGPIPE:1;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct ipidHash {
|
typedef struct ipidHash {
|
||||||
Word ipid;
|
Word ipid;
|
||||||
Word flags;
|
struct flags flags;
|
||||||
|
|
||||||
|
Word _SNDLOWAT;
|
||||||
|
Word _RCVLOWAT;
|
||||||
|
|
||||||
struct ipidHash *next;
|
struct ipidHash *next;
|
||||||
} ipidHash;
|
} ipidHash;
|
||||||
|
|
||||||
|
@ -47,6 +66,20 @@ ipidHash *htable[64] = { };
|
||||||
ipidHash *dlist = NULL;
|
ipidHash *dlist = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
ipidHash *findIpidHash(Word ipid)
|
||||||
|
{
|
||||||
|
ipidHash *e;
|
||||||
|
|
||||||
|
e = htable[ipid & (64 - 1)];
|
||||||
|
|
||||||
|
while (e)
|
||||||
|
{
|
||||||
|
if (e->ipid == ipid) return e;
|
||||||
|
e = e->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// not yet sure what this is for...
|
// not yet sure what this is for...
|
||||||
typedef void (*selwakeup)(int col_flag, int pid);
|
typedef void (*selwakeup)(int col_flag, int pid);
|
||||||
|
@ -177,9 +210,14 @@ int do_attach(
|
||||||
// semaphore ...
|
// semaphore ...
|
||||||
swait(semID);
|
swait(semID);
|
||||||
|
|
||||||
e = (ipidHash *)malloc(sizeof(ipidHash));
|
e = (ipidHash *)calloc(sizeof(ipidHash), 1);
|
||||||
e->ipid = ipid;
|
e->ipid = ipid;
|
||||||
e->flags = 0;
|
|
||||||
|
e->_RCVLOWAT = 1;
|
||||||
|
e->_SNDLOWAT = 1024;
|
||||||
|
e->flags._OOBINLINE = 1;
|
||||||
|
|
||||||
|
|
||||||
e->next = htable[ipid & (64-1)];
|
e->next = htable[ipid & (64-1)];
|
||||||
htable[ipid & (64 - 1)] = e;
|
htable[ipid & (64 - 1)] = e;
|
||||||
|
|
||||||
|
@ -201,6 +239,40 @@ struct xsockaddr_in {
|
||||||
char sin_zero[8];
|
char sin_zero[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int do_bind(
|
||||||
|
int socknum,
|
||||||
|
void *m, size_t *m_len,
|
||||||
|
struct sockaddr *addr, int *addrlen,
|
||||||
|
void *rights)
|
||||||
|
{
|
||||||
|
// freebsd 2.0 whois does a bind before
|
||||||
|
// the connect.
|
||||||
|
// this was removed in freebsd 3.0
|
||||||
|
|
||||||
|
Word ipid = (Word)socknum;
|
||||||
|
struct xsockaddr_in *sin = (struct xsockaddr_in *)addr;
|
||||||
|
|
||||||
|
port = sin->sin_port;
|
||||||
|
asm {
|
||||||
|
lda <port
|
||||||
|
xba
|
||||||
|
sta <port
|
||||||
|
}
|
||||||
|
|
||||||
|
// ?
|
||||||
|
// bind is usually called for the server side.
|
||||||
|
|
||||||
|
TCPIPSetNewDestination(ipid,
|
||||||
|
sin->sin_addr,
|
||||||
|
port);
|
||||||
|
|
||||||
|
if (_toolErr) return EPFNOSUPPORT;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int do_connect(
|
int do_connect(
|
||||||
int socknum,
|
int socknum,
|
||||||
void *m, size_t *m_len,
|
void *m, size_t *m_len,
|
||||||
|
@ -284,6 +356,10 @@ int do_disconnect(
|
||||||
debug_str("do_disconnect");
|
debug_str("do_disconnect");
|
||||||
//WriteLine("\pdo_disconnect");
|
//WriteLine("\pdo_disconnect");
|
||||||
|
|
||||||
|
// TODO -- SO_LINGER / SO_LINGER_SEC
|
||||||
|
// monitor the out queue and don't return until all
|
||||||
|
// data is sent (or it times out).
|
||||||
|
|
||||||
// return value ignored.
|
// return value ignored.
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -374,7 +450,7 @@ int do_send(
|
||||||
if (terr == tcperrConClosing)
|
if (terr == tcperrConClosing)
|
||||||
{
|
{
|
||||||
*len = 0;
|
*len = 0;
|
||||||
return ECONNRESET;
|
return ECONNRESET; // ? EPIPE?
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -389,15 +465,33 @@ int do_rcvd(
|
||||||
{
|
{
|
||||||
// called from GS/OS, busy flag is set.
|
// called from GS/OS, busy flag is set.
|
||||||
|
|
||||||
// todo -- EWOULDBLOCK?
|
// todo -- EWOULDBLOCK / EAGAIN
|
||||||
|
|
||||||
|
// Marinetti will not read less than the requested
|
||||||
|
// size unless there is a push or the connection is closing.
|
||||||
|
|
||||||
|
// TODO -- SO_RCVLOWAT (default is 1?)
|
||||||
|
// if SO_RCVLOWAT < queued data < requested length,
|
||||||
|
// read SO_RCVLOWAT bytes
|
||||||
|
|
||||||
Word terr;
|
Word terr;
|
||||||
Word ipid = (Word)socknum;
|
Word ipid = (Word)socknum;
|
||||||
void *data = (void *)m;
|
void *data = (void *)m;
|
||||||
size_t *len = (size_t *)m_len;
|
size_t *len = (size_t *)m_len;
|
||||||
|
|
||||||
|
ipidHash *e;
|
||||||
rrBuff rr;
|
rrBuff rr;
|
||||||
|
|
||||||
|
Word readCount;
|
||||||
|
Word minCount;
|
||||||
|
|
||||||
|
if (!len || !data) return EFAULT;
|
||||||
|
|
||||||
|
e = findIpidHash(ipid);
|
||||||
|
|
||||||
|
readCount = *len;
|
||||||
|
minCount = e ? e->_RCVLOWAT;
|
||||||
|
|
||||||
//WriteLine("\pdo_rcvd");
|
//WriteLine("\pdo_rcvd");
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -409,18 +503,35 @@ int do_rcvd(
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo -- should block unless O_NONBLOCK set.
|
// todo -- should block unless O_NONBLOCK set.
|
||||||
|
|
||||||
|
|
||||||
|
// todo -- could the read return 0 if there was a push at byte 0
|
||||||
|
// but data afterwards?
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
|
||||||
srBuff sr;
|
srBuff sr;
|
||||||
|
|
||||||
terr = TCPIPStatusTCP(ipid, &sr);
|
terr = TCPIPStatusTCP(ipid, &sr);
|
||||||
|
|
||||||
dump_srbuff(&sr);
|
dump_srbuff(&sr);
|
||||||
|
|
||||||
|
|
||||||
|
if (!sr.srRcvQueued && e && e->flags._NONBLOCK)
|
||||||
|
{
|
||||||
|
*len = 0;
|
||||||
|
return EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (sr.srRcvQueued < readCount && sr.srRcvQueued >= minCount)
|
||||||
|
{
|
||||||
|
readCount = minCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
terr = TCPIPReadTCP(ipid, 0, (Ref)data, *len, &rr);
|
|
||||||
|
terr = TCPIPReadTCP(ipid, 0, (Ref)data, readCount, &rr);
|
||||||
|
|
||||||
if (rr.rrBuffCount)
|
if (rr.rrBuffCount)
|
||||||
{
|
{
|
||||||
|
@ -448,22 +559,195 @@ int do_rcvd(
|
||||||
// no data, no more data, then closing.
|
// no data, no more data, then closing.
|
||||||
if (terr == tcperrConClosing && !rr.rrMoreFlag)
|
if (terr == tcperrConClosing && !rr.rrMoreFlag)
|
||||||
return ECONNRESET;
|
return ECONNRESET;
|
||||||
|
|
||||||
|
|
||||||
// if NON_BLOCKING, return EWOULDBLOCK.
|
|
||||||
|
|
||||||
//asm {
|
//asm {
|
||||||
// cop 0x7f
|
// cop 0x7f
|
||||||
//}
|
//}
|
||||||
// poll in main loop not called, apparently.
|
// poll in main loop not called, apparently.
|
||||||
|
|
||||||
//TCPIPPoll(); //
|
//TCPIPPoll(); //
|
||||||
sleep(1); // cop 0x7f?
|
sleep(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int do_select(
|
||||||
|
int socknum,
|
||||||
|
void *m, size_t *m_len,
|
||||||
|
struct sockaddr *addr, int *addrlen,
|
||||||
|
void *rights)
|
||||||
|
{
|
||||||
|
|
||||||
|
ipidHash *e;
|
||||||
|
srBuff sr;
|
||||||
|
Word terr;
|
||||||
|
|
||||||
|
Word ipid = (Word)sock;
|
||||||
|
int *pid = (int *)m_len;
|
||||||
|
int *flag = (int *)(addr);
|
||||||
|
|
||||||
|
// *flag is return value as well as input value
|
||||||
|
// (which select type)
|
||||||
|
// SEL_READ = 0
|
||||||
|
// SEL_WRITE = 1
|
||||||
|
// SEL_EXCEPT = 2
|
||||||
|
|
||||||
|
if (*flag == 0)
|
||||||
|
{
|
||||||
|
// sel read.
|
||||||
|
terr = TCPIPStatusTCP(ipid, &sr);
|
||||||
|
|
||||||
|
if (sr.srRcvQueued)
|
||||||
|
*flag = 1;
|
||||||
|
else
|
||||||
|
*flag = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*flag == 1)
|
||||||
|
{
|
||||||
|
// sel write.
|
||||||
|
// check the high water mark.
|
||||||
|
terr = TCPIPStatusTCP(ipid, &sr);
|
||||||
|
|
||||||
|
e = findIpidHash(ipid);
|
||||||
|
|
||||||
|
if (e && sr.srSndQueued >= e->_SNDLOWAT)
|
||||||
|
*flag = 0;
|
||||||
|
else
|
||||||
|
*flag = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*flag == 2)
|
||||||
|
{
|
||||||
|
// exceptions??
|
||||||
|
*flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int do_getsockopt(
|
||||||
|
Word ipid,
|
||||||
|
void *p1, void *p2,
|
||||||
|
void *p3, void *p4,
|
||||||
|
void *p5)
|
||||||
|
{
|
||||||
|
|
||||||
|
ipidHash *e;
|
||||||
|
int level = *(int *)p1;
|
||||||
|
int optname = *(int *)p2;
|
||||||
|
void *optval = (void *)p3;
|
||||||
|
int *optlen = (int *)p4;
|
||||||
|
|
||||||
|
if (!optval) return EINVAL;
|
||||||
|
|
||||||
|
e = findIpidHash(ipid);
|
||||||
|
|
||||||
|
switch (optname)
|
||||||
|
{
|
||||||
|
case SO_NREAD:
|
||||||
|
// return the amount of data available to read.
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SO_NWRITE:
|
||||||
|
// return the amount of data queued for writing.
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SO_TYPE:
|
||||||
|
*(Word *)optval = SOCK_STREAM;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case SO_NOSIGPIPE:
|
||||||
|
if (e) *(Word *)optval = e->flags._NOSIGPIPE;
|
||||||
|
else *(Word *)optval = 0;
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SO_RCVLOWAT:
|
||||||
|
if (e) *(Word)optval = e->_RCVLOWAT;
|
||||||
|
else *(Word)optval = 1;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case SO_SNDLOWAT:
|
||||||
|
if (e) *(Word)optval = e->_SNDLOWAT;
|
||||||
|
else *(Word)optval = 1024;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case SO_LINGER:
|
||||||
|
if (e) *(Word *)optval = e->flags._LINGER;
|
||||||
|
else *(Word *)optval = 0;
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SO_OOBINLINE:
|
||||||
|
if (e) *(Word *)optval = e->flags._OOBINLINE;
|
||||||
|
else *(Word *)optval = 1;
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// unsupported ish.
|
||||||
|
case SO_SNDBUF:
|
||||||
|
case SO_RCVBUF:
|
||||||
|
// input/output buffer size
|
||||||
|
|
||||||
|
case SO_RCVTIMEO:
|
||||||
|
case SO_SNDTIMEO:
|
||||||
|
// read/send timeout.
|
||||||
|
|
||||||
|
case SO_ERROR:
|
||||||
|
// return any pending error and clear the error status.
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
return ENOPROTOOPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ENOPROTOOPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int do_shutdown(
|
||||||
|
Word ipid,
|
||||||
|
void *p1, void *p2,
|
||||||
|
void *p3, void *p4,
|
||||||
|
void *p5)
|
||||||
|
{
|
||||||
|
ipidHash *e = findIpidHash(ipid);
|
||||||
|
|
||||||
|
int how = *(int *)p1;
|
||||||
|
|
||||||
|
// mark the read/write op disabled
|
||||||
|
// TODO -- main thread should read & ignore any
|
||||||
|
// incoming data if SHUT_RD?
|
||||||
|
|
||||||
|
if (!e) return EINVAL;
|
||||||
|
|
||||||
|
switch(how)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
e->flags._SHUT_RD = 1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
e->flags._SHUT_WR = 1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
e->flags._SHUT_RD = 1;
|
||||||
|
e->flags._SHUT_WR = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma databank 1
|
#pragma databank 1
|
||||||
static int driver(
|
static int driver(
|
||||||
int socknum, int req,
|
int socknum, int req,
|
||||||
|
@ -493,9 +777,8 @@ static int driver(
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PRU_BIND:
|
case PRU_BIND:
|
||||||
//WriteLine("\pbind!");
|
// KERNbind(int fd, struct sockaddr *my_addr, int addrlen, int *ERRNO)
|
||||||
// todo
|
return do_bind(socknum, m, m_len, addr, addrlen, rights);
|
||||||
return 0;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PRU_CONNECT:
|
case PRU_CONNECT:
|
||||||
|
@ -571,6 +854,9 @@ static int driver(
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PRU_SELECT:
|
case PRU_SELECT:
|
||||||
|
// int SOCKselect(int pid, int fl, int sock)
|
||||||
|
return do_select(socknum, m, m_len, addr, addrlen, rights);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,10 +902,11 @@ Word StartUp(displayPtr fx)
|
||||||
flags |= kLoaded;
|
flags |= kLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
// require 3.0b3
|
// require 3.0b3
|
||||||
if (TCPIPLongVersion() < 0x03006003)
|
if (TCPIPLongVersion() < 0x03006003)
|
||||||
{
|
{
|
||||||
|
if (fx) fx("Marinetti 3.0b3 is required.");
|
||||||
if (flags & kLoaded)
|
if (flags & kLoaded)
|
||||||
UnloadOneTool(54);
|
UnloadOneTool(54);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -671,6 +958,8 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
flags = StartUp(DisplayMessage);
|
flags = StartUp(DisplayMessage);
|
||||||
|
|
||||||
|
if (flags == -1) exit(1);
|
||||||
|
|
||||||
semID = screate(1);
|
semID = screate(1);
|
||||||
|
|
||||||
InstallNetDriver(driver, 0);
|
InstallNetDriver(driver, 0);
|
||||||
|
@ -687,6 +976,14 @@ int main(int argc, char **argv)
|
||||||
ipidHash *prev;
|
ipidHash *prev;
|
||||||
|
|
||||||
debug_str("TCPIPPoll() begin");
|
debug_str("TCPIPPoll() begin");
|
||||||
|
if (dlist)
|
||||||
|
{
|
||||||
|
// suspend so we can be fg.
|
||||||
|
kill(getpid(),SIGSTOP);
|
||||||
|
asm {
|
||||||
|
brk 0xea
|
||||||
|
}
|
||||||
|
}
|
||||||
TCPIPPoll();
|
TCPIPPoll();
|
||||||
debug_str("TCPIPPoll() end");
|
debug_str("TCPIPPoll() end");
|
||||||
|
|
||||||
|
@ -715,6 +1012,7 @@ int main(int argc, char **argv)
|
||||||
if (sr.srState == TCPSCLOSED)
|
if (sr.srState == TCPSCLOSED)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
debug_str("TCPLogout");
|
||||||
TCPIPLogout(e->ipid);
|
TCPIPLogout(e->ipid);
|
||||||
free(e);
|
free(e);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue