- Ported to powerpc

- Fixed bug with accept() call
- Better error checking
This commit is contained in:
Jack Jansen 1995-01-18 13:50:42 +00:00
parent fa4fd8ef4f
commit 75b6f1c8e5
4 changed files with 146 additions and 63 deletions

View File

@ -190,8 +190,10 @@ dnrr_getattr(self, name)
if ( rv ) return rv;
err_clear();
if ( self->waiting )
if ( !dnrwait(self) )
if ( !dnrwait(self) ) {
err_setstr(ErrorObject, "Resolver busy");
return NULL;
}
tp = self->type;
return getmember((char *)&self->hinfo, dnrr_mlists[tp], name);
}
@ -293,7 +295,7 @@ dnr_StrToAddr(self, args)
if ( err == cacheFault ) {
rv->waiting++;
INCREF(rv);
} else {
} else if ( err ) {
DECREF(rv);
PyErr_Mac(ErrorObject, err);
return NULL;
@ -321,7 +323,7 @@ dnr_AddrToName(self, args)
if ( err == cacheFault ) {
rv->waiting++;
INCREF(rv);
} else {
} else if ( err ) {
DECREF(rv);
PyErr_Mac(ErrorObject, err);
return NULL;
@ -369,7 +371,7 @@ dnr_HInfo(self, args)
if ( err == cacheFault ) {
rv->waiting++;
INCREF(rv);
} else {
} else if ( err ) {
DECREF(rv);
PyErr_Mac(ErrorObject, err);
return NULL;
@ -401,17 +403,12 @@ dnr_MXInfo(self, args)
if ( err == cacheFault ) {
rv->waiting++;
INCREF(rv);
} else {
} else if ( err ) {
DECREF(rv);
PyErr_Mac(ErrorObject, err);
return NULL;
}
return (object *)rv;
if (!newgetargs(args, ""))
return NULL;
INCREF(None);
return None;
}
/* List of methods defined in the module */

View File

@ -30,8 +30,21 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <Desk.h>
/* State of a tcp stream, in the connectionState field */
#define STATE_CLOSED 0
#define STATE_LISTEN 2
#define STATE_ESTAB 8
#define STATE_CWAIT 18
static object *ErrorObject;
TCPIOCompletionUPP upp_tcp_done;
TCPNotifyUPP upp_tcp_asr;
#if 0
UDPIOCompletionUPP upp_udp_done;
#endif
UDPNotifyUPP upp_udp_asr;
/* ----------------------------------------------------- */
/* Declarations for objects of type MacTCP connection status */
@ -64,6 +77,8 @@ staticforward typeobject Tcpgstype;
typedef struct {
OB_HEAD
TCPiopb iop;
long localhost; /* Our IP address */
short localport; /* Our port number */
object *asr; /* Optional async notification routine */
int asr_ec; /* error code parameter to asr */
int asr_reason; /* detail for some errors */
@ -241,6 +256,34 @@ static typeobject Tcpgstype = {
/* End of code for MacTCP global status objects */
/* -------------------------------------------------------- */
static int
tcps_checkstate(self, state, state2)
tcpsobject *self;
int state, state2;
{
OSErr err;
TCPStatusPB *pb;
char buf[80];
if ( self->async_busy ) {
err_setstr(ErrorObject, "Operation not allowed, PassiveOpen in progress");
return -1;
}
if ( state < 0 && state2 < 0 )
return 0;
err = xTCPStatus(&self->iop, &pb);
if ( err ) {
PyErr_Mac(ErrorObject, err);
return -1;
}
if ( state == pb->connectionState ||
state2 == pb->connectionState )
return 0;
sprintf(buf, "Operation not allowed, connection state=%d", pb->connectionState);
err_setstr(ErrorObject, buf);
return -1;
}
static int
tcps_asr_safe(arg)
void *arg;
@ -276,14 +319,14 @@ tcps_asr(str, ec, self, reason, icmp)
}
static void
tcps_opendone(pb)
tcps_done(pb)
TCPiopb *pb;
{
tcpsobject *self = (tcpsobject *)pb->csParam.open.userDataPtr;
if ( pb != &self->iop || !self->async_busy ) {
/* Oops... problems */
printf("tcps_opendone: unexpected call\n");
printf("tcps_done: unexpected call\n");
return;
}
self->async_busy = 0;
@ -339,15 +382,19 @@ tcps_PassiveOpen(self, args)
if (!newgetargs(args, "h", &port))
return NULL;
if ( tcps_checkstate(self, -1, -1) < 0 )
return NULL;
self->async_busy = 1;
self->async_err = 0;
err = xTCPPassiveOpen(&self->iop, port, (TCPIOCompletionProc)tcps_opendone,
err = xTCPPassiveOpen(&self->iop, port, upp_tcp_done,
(void *)self);
if ( err ) {
self->async_busy = 0;
PyErr_Mac(ErrorObject, err);
return NULL;
}
self->localhost = self->iop.csParam.open.localHost;
self->localport = self->iop.csParam.open.localPort;
INCREF(None);
return None;
}
@ -363,11 +410,15 @@ tcps_ActiveOpen(self, args)
if (!newgetargs(args, "hlh", &lport, &rhost, &rport))
return NULL;
err = xTCPActiveOpen(&self->iop, lport, rhost, rport, (TCPIOCompletionProc)0);
if ( tcps_checkstate(self, -1, -1) < 0 )
return NULL;
err = xTCPActiveOpen(&self->iop, lport, rhost, rport, (TCPIOCompletionUPP)0);
if ( err ) {
PyErr_Mac(ErrorObject, err);
return NULL;
}
self->localhost = self->iop.csParam.open.localHost;
self->localport = self->iop.csParam.open.localPort;
INCREF(None);
return None;
}
@ -385,11 +436,13 @@ tcps_Send(self, args)
if (!newgetargs(args, "s#|ii", &buf, &bufsize, &push, &urgent))
return NULL;
if ( tcps_checkstate(self, STATE_ESTAB, STATE_CWAIT) < 0 )
return NULL;
wds.length = bufsize;
wds.ptr = buf;
wds.terminus = 0;
err = xTCPSend(&self->iop, (wdsEntry *)&wds, (Boolean)push, (Boolean)urgent,
(TCPIOCompletionProc)0);
(TCPIOCompletionUPP)0);
if ( err ) {
PyErr_Mac(ErrorObject, err);
return NULL;
@ -412,8 +465,10 @@ tcps_Rcv(self, args)
if (!newgetargs(args, "i", &timeout))
return NULL;
if ( tcps_checkstate(self, -1, -1) < 0 )
return NULL;
memset((char *)&rds, 0, sizeof(rds));
err = xTCPNoCopyRcv(&self->iop, rds, 1, timeout, (TCPIOCompletionProc)0);
err = xTCPNoCopyRcv(&self->iop, rds, 1, timeout, (TCPIOCompletionUPP)0);
if ( err ) {
PyErr_Mac(ErrorObject, err);
return NULL;
@ -421,7 +476,7 @@ tcps_Rcv(self, args)
urgent = self->iop.csParam.receive.urgentFlag;
mark = self->iop.csParam.receive.markFlag;
rv = newsizedstringobject((char *)rds[0].ptr, rds[0].length);
err = xTCPBufReturn(&self->iop, rds, (TCPIOCompletionProc)0);
err = xTCPBufReturn(&self->iop, rds, (TCPIOCompletionUPP)0);
if ( err ) {
/* Should not happen */printf("mactcp module: BufReturn failed?\n");
PyErr_Mac(ErrorObject, err);
@ -440,7 +495,7 @@ tcps_Close(self, args)
if (!newgetargs(args, ""))
return NULL;
err = xTCPClose(&self->iop, (TCPIOCompletionProc)0);
err = xTCPClose(&self->iop, (TCPIOCompletionUPP)0);
if ( err ) {
PyErr_Mac(ErrorObject, err);
return NULL;
@ -477,6 +532,8 @@ tcps_Status(self, args)
if (!newgetargs(args, ""))
return NULL;
if ( tcps_checkstate(self, -1, -1) < 0 )
return NULL;
err = xTCPStatus(&self->iop, &pb);
if ( err ) {
PyErr_Mac(ErrorObject, err);
@ -485,6 +542,21 @@ tcps_Status(self, args)
return (object *)newtcpcsobject(pb);
}
static object *
tcps_GetSockName(self, args)
tcpsobject *self;
object *args;
{
/* This routine is needed so we can get at the local port even when
** a PassiveOpen is in progress (when we can't do a Status call).
** This is needed for socket listen(); getsockname(); accept() emulation
** as used by ftp and the like.
*/
if (!newgetargs(args, ""))
return NULL;
return mkvalue("(lh)", self->localhost, self->localport);
}
static struct methodlist tcps_methods[] = {
{"isdone", (method)tcps_isdone, 1},
{"wait", (method)tcps_wait, 1},
@ -495,6 +567,7 @@ static struct methodlist tcps_methods[] = {
{"Close", (method)tcps_Close, 1},
{"Abort", (method)tcps_Abort, 1},
{"Status", (method)tcps_Status, 1},
{"GetSockName", (method)tcps_GetSockName, 1},
{NULL, NULL} /* sentinel */
};
@ -535,7 +608,7 @@ newtcpsobject(bufsize)
if (self == NULL)
return NULL;
memset((char *)&self->iop, 0, sizeof(self->iop));
err= xTCPCreate(bufsize, (TCPNotifyProc)tcps_asr, (void *)self, &self->iop);
err= xTCPCreate(bufsize, upp_tcp_asr, (void *)self, &self->iop);
if ( err ) {
DEL(self);
PyErr_Mac(ErrorObject, err);
@ -626,7 +699,7 @@ udps_Read(self, args)
if (!newgetargs(args, "i", &timeout))
return NULL;
err = xUDPRead(&self->iop, timeout, (UDPIOCompletionProc)0);
err = xUDPRead(&self->iop, timeout, (UDPIOCompletionUPP)0);
if ( err ) {
PyErr_Mac(ErrorObject, err);
return NULL;
@ -659,7 +732,7 @@ udps_Write(self, args)
wds.length = bufsize;
wds.ptr = buf;
wds.terminus = 0;
err = xUDPWrite(&self->iop, host, port, &wds, (UDPIOCompletionProc)0);
err = xUDPWrite(&self->iop, host, port, &wds, (UDPIOCompletionUPP)0);
if ( err ) {
PyErr_Mac(ErrorObject, err);
return NULL;
@ -715,7 +788,7 @@ newudpsobject(bufsize, port)
return NULL;
memset((char *)&self->iop, 0, sizeof(self->iop));
self->port = port;
err= xUDPCreate(&self->iop, bufsize, &self->port, (UDPNotifyProc)udps_asr,
err= xUDPCreate(&self->iop, bufsize, &self->port, upp_udp_asr,
(void *)self);
if ( err ) {
DEL(self);
@ -899,6 +972,13 @@ initmactcp()
d = getmoduledict(m);
ErrorObject = newstringobject("mactcp.error");
dictinsert(d, "error", ErrorObject);
upp_tcp_done = NewTCPIOCompletionProc(tcps_done);
upp_tcp_asr = NewTCPNotifyProc(tcps_asr);
#if 0
upp_udp_done = NewUDPIOCompletionProc(udps_done);
#endif
upp_udp_asr = NewUDPNotifyProc(udps_asr);
/* XXXX Add constants here */

View File

@ -15,11 +15,6 @@
#include "tcpglue.h"
#include <Devices.h>
#ifndef __MWERKS__
#define TCPIOCompletionUPP TCPIOCompletionProc
#define NewTCPIOCompletionProc(x) (x)
#endif /* __MWERKS__ */
static short driver = 0;
#ifndef __powerc
@ -56,7 +51,7 @@ OSErr xOpenDriver()
*/
OSErr xTCPCreate(buflen,notify,udp, pb)
int buflen;
TCPNotifyProc notify;
TCPNotifyUPP notify;
void *udp;
TCPiopb *pb;
{
@ -73,7 +68,7 @@ OSErr xTCPCreate(buflen,notify,udp, pb)
/*
* start listening for a TCP connection
*/
OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionProc completion,
OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionUPP completion,
void *udp)
{
if (driver == 0)
@ -101,7 +96,7 @@ OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionProc completion,
* connect to a remote TCP
*/
OSErr xTCPActiveOpen(TCPiopb *pb, short port, long rhost, short rport,
TCPIOCompletionProc completion)
TCPIOCompletionUPP completion)
{
if (driver == 0)
return(invalidStreamPtr);
@ -128,7 +123,7 @@ OSErr xTCPNoCopyRcv(pb,rds,rdslen,timeout,completion)
rdsEntry *rds;
int rdslen;
int timeout;
TCPIOCompletionProc completion;
TCPIOCompletionUPP completion;
{
if (driver == 0)
@ -142,7 +137,7 @@ OSErr xTCPNoCopyRcv(pb,rds,rdslen,timeout,completion)
return (xPBControl(pb,completion));
}
OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionProc completion)
OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionUPP completion)
{
pb->ioCRefNum = driver;
pb->csCode = TCPRcvBfrReturn;
@ -154,7 +149,7 @@ OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionProc completion)
/*
* send data
*/
OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCompletionProc completion)
OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCompletionUPP completion)
{
if (driver == 0)
return invalidStreamPtr;
@ -174,7 +169,7 @@ OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCo
/*
* close a connection
*/
OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionProc completion)
OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionUPP completion)
{
if (driver == 0)
return(invalidStreamPtr);
@ -306,7 +301,7 @@ OSErr xTCPStatus(TCPiopb *pb, TCPStatusPB **spb)
/*
* create a UDP stream, hook it to a socket.
*/
OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyProc asr, void *udp)
OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyUPP asr, void *udp)
{
OSErr io;
@ -327,7 +322,7 @@ OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyProc asr, void *
/*
* ask for incoming data
*/
OSErr xUDPRead(UDPiopb *pb, int timeout, UDPIOCompletionProc completion)
OSErr xUDPRead(UDPiopb *pb, int timeout, UDPIOCompletionUPP completion)
{
if (driver == 0)
@ -337,7 +332,7 @@ OSErr xUDPRead(UDPiopb *pb, int timeout, UDPIOCompletionProc completion)
pb->csCode = UDPRead;
pb->csParam.receive.timeOut = timeout;
pb->csParam.receive.secondTimeStamp = 0/* must be zero */;
return (xPBControl ( (TCPiopb *)pb, (TCPIOCompletionProc)completion ));
return (xPBControl ( (TCPiopb *)pb, (TCPIOCompletionUPP)completion ));
}
OSErr xUDPBfrReturn(UDPiopb *pb, char *buff)
@ -349,14 +344,14 @@ OSErr xUDPBfrReturn(UDPiopb *pb, char *buff)
pb->ioCRefNum = driver;
pb->csCode = UDPBfrReturn;
pb->csParam.receive.rcvBuff = buff;
return ( xPBControl( (TCPiopb *)pb,(TCPIOCompletionProc)-1 ) );
return ( xPBControl( (TCPiopb *)pb,(TCPIOCompletionUPP)-1 ) );
}
/*
* send data
*/
OSErr xUDPWrite(UDPiopb *pb,ip_addr host,ip_port port,miniwds *wds,
UDPIOCompletionProc completion)
UDPIOCompletionUPP completion)
{
if (driver == 0)
@ -369,7 +364,7 @@ OSErr xUDPWrite(UDPiopb *pb,ip_addr host,ip_port port,miniwds *wds,
pb->csParam.send.wdsPtr = (Ptr)wds;
pb->csParam.send.checkSum = true;
pb->csParam.send.sendLength = 0/* must be zero */;
return (xPBControl( (TCPiopb *)pb, (TCPIOCompletionProc)completion));
return (xPBControl( (TCPiopb *)pb, (TCPIOCompletionUPP)completion));
}
/*
@ -443,7 +438,7 @@ OSErr xTCPRcv(pb,buf,buflen,timeout,completion)
Ptr buf;
int buflen;
int timeout;
TCPIOCompletionProc completion;
TCPIOCompletionUPP completion;
{
if (driver == 0)
@ -457,7 +452,7 @@ OSErr xTCPRcv(pb,buf,buflen,timeout,completion)
return (xPBControl(pb,completion));
}
OSErr xPBControl(TCPiopb *pb,TCPIOCompletionProc completion)
OSErr xPBControl(TCPiopb *pb,TCPIOCompletionUPP completion)
{
#ifndef __MWERKS__
pb->ioNamePtr = ReturnA5();
@ -468,22 +463,14 @@ OSErr xPBControl(TCPiopb *pb,TCPIOCompletionProc completion)
(pb)->ioCompletion = 0L;
return(PBControl((ParmBlkPtr)(pb),false)); /* sync */
}
else if (completion == (TCPIOCompletionProc)-1L)
else if (completion == (TCPIOCompletionUPP)-1L)
{
(pb)->ioCompletion = 0L;
return(PBControl((ParmBlkPtr)(pb),true)); /* async */
}
else
{
#if 0
/* If I understand the PowerPC calling correctly this is the right
** code, but the MetroWerks headers seem to disagree. We'll see... -- Jack
*/
TCPIOCompletionUPP comp_upp = NewTCPIOCompletionProc(completion);
(pb)->ioCompletion = comp_upp;
#else
(pb)->ioCompletion = completion;
#endif
return(PBControl((ParmBlkPtr)(pb),true)); /* async */
}
}

View File

@ -14,6 +14,21 @@
#include <UDPPB.h>
#include <AddressXlation.h>
#ifndef __MWERKS__
#define TCPIOCompletionUPP TCPIOCompletionProc
#define TCPNotifyUPP TCPNotifyProc
#define UDPIOCompletionUPP UDPIOCompletionProc
#define UDPNotifyUPP UDPNotifyProc
#define NewTCPIOCompletionProc(x) (x)
#define NewTCPNotifyProc(x) (x)
#define NewUDPIOCompletionProc(x) (x)
#define NewUDPNotifyProc(x) (x)
#endif /* __MWERKS__ */
#if defined(powerc) || defined (__powerc)
#pragma options align=mac68k
#endif
typedef struct miniwds
{
unsigned short length;
@ -21,26 +36,30 @@ typedef struct miniwds
unsigned short terminus; /* must be zero'd for use */
} miniwds;
#if defined(powerc) || defined(__powerc)
#pragma options align=reset
#endif
OSErr xOpenDriver(void);
OSErr xPBControl(TCPiopb *pb, TCPIOCompletionProc completion);
OSErr xPBControl(TCPiopb *pb, TCPIOCompletionUPP completion);
OSErr xPBControlSync(TCPiopb *pb);
OSErr xTCPCreate(int buflen, TCPNotifyProc notify, void *udp, TCPiopb *pb);
OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionProc completion, void *udp);
OSErr xTCPActiveOpen(TCPiopb *pb, short port, long rhost, short rport, TCPIOCompletionProc completion);
OSErr xTCPRcv(TCPiopb *pb, char *buf, int buflen, int timeout, TCPIOCompletionProc completion);
OSErr xTCPNoCopyRcv(TCPiopb *,rdsEntry *,int,int,TCPIOCompletionProc);
OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionProc completion);
OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCompletionProc completion);
OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionProc completion);
OSErr xTCPCreate(int buflen, TCPNotifyUPP notify, void *udp, TCPiopb *pb);
OSErr xTCPPassiveOpen(TCPiopb *pb, short port, TCPIOCompletionUPP completion, void *udp);
OSErr xTCPActiveOpen(TCPiopb *pb, short port, long rhost, short rport, TCPIOCompletionUPP completion);
OSErr xTCPRcv(TCPiopb *pb, char *buf, int buflen, int timeout, TCPIOCompletionUPP completion);
OSErr xTCPNoCopyRcv(TCPiopb *,rdsEntry *,int,int,TCPIOCompletionUPP);
OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionUPP completion);
OSErr xTCPSend(TCPiopb *pb, wdsEntry *wds, Boolean push, Boolean urgent, TCPIOCompletionUPP completion);
OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionUPP completion);
OSErr xTCPAbort(TCPiopb *pb);
OSErr xTCPRelease(TCPiopb *pb);
OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyProc asr, void *udp);
OSErr xUDPRead(UDPiopb *pb,int timeout, UDPIOCompletionProc completion);
OSErr xUDPCreate(UDPiopb *pb,int buflen,ip_port *port, UDPNotifyUPP asr, void *udp);
OSErr xUDPRead(UDPiopb *pb,int timeout, UDPIOCompletionUPP completion);
OSErr xUDPBfrReturn(UDPiopb *pb, char *buff);
OSErr xUDPWrite(UDPiopb *pb,ip_addr host,ip_port port,miniwds *wds,
UDPIOCompletionProc completion);
UDPIOCompletionUPP completion);
OSErr xUDPRelease(UDPiopb *pb);
ip_addr xIPAddr(void);