📄 epocnet.cpp
字号:
}/* * Deal with socket errors detected in try_send(). * FIXME: This can be done in the AO CSender.RunL? */void net_pending_errors(void){ int i; Actual_Socket s; /* * This might be a fiddly business, because it's just possible * that handling a pending error on one socket might cause * others to be closed. (I can't think of any reason this might * happen in current SSH implementation, but to maintain * generality of this network layer I'll assume the worst.) * * So what we'll do is search the socket list for _one_ socket * with a pending error, and then handle it, and then search * the list again _from the beginning_. Repeat until we make a * pass with no socket errors present. That way we are * protected against the socket list changing under our feet. */ do { for (i = 0; (s = (Actual_Socket)index234(netStatics->iSocketTree, i)) != NULL; i++) { if (s->pending_error) { /* * An error has occurred on this socket. Pass it to the * plug. */ LOGF(("sk_net_pending_errors: Error %d, %s", s->pending_error, FormatError("Pending errors", s->pending_error))); plug_closing(s->plug, FormatError("Pending errors", s->pending_error), s->pending_error, 0); break; } } } while (s);}/* * Each socket abstraction contains a `void *' private field in * which the client can keep state. */static void sk_tcp_set_private_ptr(Socket sock, void *ptr){ Actual_Socket s = (Actual_Socket) sock; s->private_ptr = ptr;}static void *sk_tcp_get_private_ptr(Socket sock){ Actual_Socket s = (Actual_Socket) sock; return s->private_ptr;}/* * Special error values are returned from sk_namelookup and sk_new * if there's a problem. These functions extract an error message, * or return NULL if there's no problem. */const char *sk_addr_error(SockAddr addr){ return addr->error;}static const char *sk_tcp_socket_error(Socket sock){ Actual_Socket s = (Actual_Socket) sock; return s->error;}static void sk_tcp_set_frozen(Socket sock, int is_frozen){ Actual_Socket s = (Actual_Socket) sock; if (s->frozen == is_frozen) return; s->frozen = is_frozen; if (!is_frozen && s->frozen_readable) { s->s->r->Reissue(); } s->frozen_readable = 0;}/* * For Plink: enumerate all sockets currently active. */SOCKET first_socket(int *state){ Actual_Socket s; *state = 0; s = (Actual_Socket) index234(netStatics->iSocketTree, (*state)++); return s ? s->s : INVALID_SOCKET;}SOCKET next_socket(int *state){ Actual_Socket s = (Actual_Socket) index234(netStatics->iSocketTree, (*state)++); return s ? s->s : INVALID_SOCKET;}int net_service_lookup(char * /*service*/){ return 0;}SockAddr platform_get_x11_unix_address(int /*displaynum*/, char ** /*canonicalname*/){ SockAddr ret = snew(struct SockAddr_tag); memset(ret, 0, sizeof(struct SockAddr_tag)); ret->error = "No unix socket support"; return ret;}// Get number of active socketsint sk_num_active_sockets(void) { if ( !netStatics->iSocketTree ) { return 0; } return count234(netStatics->iSocketTree);}/* The ActiveObject approach... *//* CRecver implementation */CRecver* CRecver::NewL(Socket p){ CRecver *self=new (ELeave) CRecver; CleanupStack::PushL(self); self->ConstructL(p); CleanupStack::Pop(); return(self);}CRecver::CRecver() : CActive(CActive::EPriorityStandard),readlen(2048){}void CRecver::ConstructL(Socket p){ parent=p; CActiveScheduler::Add(this);}CRecver::~CRecver(){ Cancel();}void CRecver::StartRecver(){ Actual_Socket s=(Actual_Socket)parent; s->s->RecvOneOrMore(readbuf, 0, iStatus, readlen); SetActive();}void CRecver::Reissue(){ RunL();}void CRecver::RunL(){ TRAPD(error, DoRunL()); if ( error != KErrNone ) { _LIT(KPanic, "CRecver"); User::Panic(KPanic, error); }}void CRecver::DoRunL(){ Actual_Socket s=(Actual_Socket)parent; TInt atmark, err; err = iStatus.Int(); if ( (err == KErrEof) || (readlen() == 0) ) { // Remote end closed connection plug_closing(s->plug, NULL, 0, 0); return; } if ( err != KErrNone) { LOGF(("CRecver::DoRunL: Error %d, %s", err, FormatError("CRecver", err))); plug_closing(s->plug, FormatError("CRecver", err), err, 0); return; } if (s->killing) return; if (s->frozen) { s->frozen_readable=1; return; } /* * We have received data on the socket. For an oobinline * socket, this might be data _before_ an urgent pointer, * in which case we send it to the back end with type==1 * (data prior to urgent). */ if (s->oobinline) { err=s->s->GetOpt(KSoTcpRcvAtMark, KSolInetTcp, atmark); if (err!=KErrNone) atmark=1; if (atmark) atmark=0; else atmark=1; /* * This is just strange for me... Now how should this work??? +G * * If it does nothing, we get atmark==1, * which is equivalent to `no OOB pending', so the * effect will be to non-OOB-ify any OOB data. */ } else atmark = 1; noise_ultralight(readbuf.Size()); if (plug_receive(s->plug, atmark ? 0 : 1, (char *)readbuf.Ptr(), readbuf.Size())) StartRecver(); else {// CActiveScheduler::Stop(); }}void CRecver::DoCancel(){ Actual_Socket s=(Actual_Socket)parent; s->s->CancelAll();}/* CSender implementation */CSender* CSender::NewL(Socket p){ CSender *self=new (ELeave) CSender; CleanupStack::PushL(self); self->ConstructL(p); CleanupStack::Pop(); return(self);}CSender::CSender() : CActive(CActive::EPriorityStandard){}void CSender::ConstructL(Socket p){ parent=p; CActiveScheduler::Add(this);}CSender::~CSender(){ Cancel();}void CSender::Sendit(){ Actual_Socket s=(Actual_Socket)parent; void *data; TInt len; TUint urgentflag; if (s->sending_oob || bufchain_size(&(s->output_data)) > 0) { if (s->sending_oob) { urgentflag = KSockWriteUrgent; len = s->sending_oob; data = &(s->oobdata); } else { urgentflag = 0; bufchain_prefix(&(s->output_data), &data, &len); } writebuf.Set((TUint8 *)data, len); s->s->Send(writebuf, urgentflag, iStatus); s->writable = 0; SetActive(); }}void CSender::RunL(){ TRAPD(error, DoRunL()); if ( error != KErrNone ) { _LIT(KPanic, "CSender"); User::Panic(KPanic, error); }}void CSender::DoRunL(){ Actual_Socket s=(Actual_Socket)parent; if (iStatus == KErrBadHandle || iStatus == KErrDisconnected || iStatus == KErrEof) { LOGF(("CSender::DoRunL: Error %d, %s", iStatus.Int(), FormatError("CSender", iStatus.Int()))); s->pending_error = iStatus.Int(); return; } else if (iStatus != KErrNone) { LOGF(("CSender::DoRunL: Error %d, %s", iStatus.Int(), FormatError("CSender", iStatus.Int()))); fatalbox(FormatError("CSender", iStatus.Int())); } if (s->sending_oob) s->sending_oob = 0; else bufchain_consume(&(s->output_data), writebuf.Size()); if (!s->killing) plug_sent(s->plug, s->sending_oob + bufchain_size(&(s->output_data))); s->writable=1; if (s->sending_oob || bufchain_size(&(s->output_data)) > 0) Sendit(); else if (s->killing) sk_tcp_close((Socket)s);}void CSender::DoCancel(){ Actual_Socket s=(Actual_Socket)parent; s->s->CancelAll();}/* CAcceptor implementation */CAcceptor* CAcceptor::NewL(Socket p){ CAcceptor *self=new (ELeave) CAcceptor; CleanupStack::PushL(self); self->ConstructL(p); CleanupStack::Pop(); return(self);}CAcceptor::CAcceptor() : CActive(CActive::EPriorityStandard){}void CAcceptor::ConstructL(Socket p){ parent=p; CActiveScheduler::Add(this);}CAcceptor::~CAcceptor(){ Cancel();}void CAcceptor::StartAcceptor(){ Actual_Socket listener=(Actual_Socket)parent; TInt err; listener->accepted = new (ELeave) RSocketS; err=listener->accepted->Open(netStatics->iSocketServ); if (err!=KErrNone) { LOGF(("CAcceptor::StartAcceptor: Open failed: %d, %s", err, FormatError("Socket open for CAcceptor", err))); delete listener->accepted; listener->accepted=NULL; User::LeaveIfError(err); } listener->accepted->id=netStatics->iNextId; listener->s->Accept(*(listener->accepted), iStatus); SetActive();}void CAcceptor::RunL(){ TRAPD(error, DoRunL()); if ( error != KErrNone ) { _LIT(KPanic, "CAcceptor"); User::Panic(KPanic, error); }}void CAcceptor::DoRunL(){ Actual_Socket s=(Actual_Socket)parent; TInetAddr t; if (iStatus!=KErrNone) { LOGF(("CAcceptor::RunL: Error %d, %s", iStatus.Int(), FormatError("CAcceptor", iStatus.Int()))); delete s->accepted; s->accepted=NULL; StartAcceptor(); return; } s->accepted->RemoteName(t); if (s->localhost_only && t.Address() != KInetAddrLoop) { s->accepted->Close(); delete s->accepted; s->accepted=NULL; } else if (plug_accepting(s->plug, (void*)s->accepted)) { s->accepted->Close(); delete s->accepted; s->accepted=NULL; } StartAcceptor();}void CAcceptor::DoCancel(){ Actual_Socket s=(Actual_Socket)parent; s->s->CancelAll(); if (s->accepted!=NULL) delete s->accepted;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -