genericopenlibs/openenvcore/backend/src/corebackend/usocketbase.cpp
branchRCL_3
changeset 56 acd3cd4aaceb
parent 54 4332f0f7be53
child 57 2efc27d87e1c
equal deleted inserted replaced
54:4332f0f7be53 56:acd3cd4aaceb
    35 
    35 
    36 			//Send the equivalent Flags of Symbian to RSocket
    36 			//Send the equivalent Flags of Symbian to RSocket
    37 			TUint flags = iFcntlFlag;
    37 			TUint flags = iFcntlFlag;
    38 			if( anArg & O_NONBLOCK )
    38 			if( anArg & O_NONBLOCK )
    39 				{
    39 				{
    40 				ATOMICSOCKETOP(retVal = iSocket.SetOpt(KSONonBlockingIO, KSOLSocket),retVal = EBADF;)
    40 				retVal = iSocket.SetOpt(KSONonBlockingIO, KSOLSocket);
    41 				flags |= O_NONBLOCK;
    41 				flags |= O_NONBLOCK;
    42 				}
    42 				}
    43 			else
    43 			else
    44 				{
    44 				{
    45 				ATOMICSOCKETOP(retVal = iSocket.SetOpt(KSOBlockingIO, KSOLSocket),retVal = EBADF;)				
    45 				retVal = iSocket.SetOpt(KSOBlockingIO, KSOLSocket);
    46 				flags &= ~O_NONBLOCK;
    46 				flags &= ~O_NONBLOCK;
    47 				}
    47 				}
    48 			if (retVal == KErrNone)
    48 			if (retVal == KErrNone)
    49 				{
    49 				{
    50 				retVal = iFcntlFlag = flags; 
    50 				retVal = iFcntlFlag = flags; 
    89 void CSockDescBase::Read(TDes8& aBuf, TRequestStatus& aStatus)
    89 void CSockDescBase::Read(TDes8& aBuf, TRequestStatus& aStatus)
    90 	{
    90 	{
    91 	TSockXfrLength len;
    91 	TSockXfrLength len;
    92 	TRequestStatus tempStatus;
    92 	TRequestStatus tempStatus;
    93 
    93 
    94 	ATOMICSOCKETOP(iSocket.RecvOneOrMore(aBuf, 0, tempStatus, len),Complete(tempStatus,KErrBadHandle))
    94 	iSocket.RecvOneOrMore(aBuf, 0, tempStatus, len);	// needs a completion which returns the length
    95 		// needs a completion which returns the length
       
    96 	User::WaitForRequest(tempStatus);
    95 	User::WaitForRequest(tempStatus);
    97 	if (tempStatus.Int() != KErrNone)
    96 	if (tempStatus.Int() != KErrNone)
    98 		{
    97 		{
    99 		Complete(aStatus, tempStatus.Int());
    98 		Complete(aStatus, tempStatus.Int());
   100 		}
    99 		}
   107 void CSockDescBase::Write(TDes8& aBuf, TRequestStatus& aStatus)
   106 void CSockDescBase::Write(TDes8& aBuf, TRequestStatus& aStatus)
   108 	{
   107 	{
   109 	TRequestStatus tempStatus;
   108 	TRequestStatus tempStatus;
   110 	TInt bytesWritten = 0;
   109 	TInt bytesWritten = 0;
   111 	TInt bufLength = aBuf.Length();
   110 	TInt bufLength = aBuf.Length();
   112 	TSockXfrLength len = 0;
   111 	TSockXfrLength len;
   113 	do
   112 	do
   114 		{
   113 		{
   115 		ATOMICSOCKETOP(iSocket.Send(aBuf.Mid(bytesWritten), 0, tempStatus, len),Complete(tempStatus,KErrBadHandle))		
   114 		iSocket.Send(aBuf.Mid(bytesWritten), 0, tempStatus, len);
   116 		User::WaitForRequest(tempStatus);			
   115 		User::WaitForRequest(tempStatus);			
   117 		if (len() == 0)
   116 		if (len() == 0)
   118 			{
   117 			{
   119 			break;
   118 			break;
   120 			}
   119 			}
   154 		{
   153 		{
   155 		case SOCK_STREAM:
   154 		case SOCK_STREAM:
   156 			// recvfrom on a stream ignores the from address - get the peername
   155 			// recvfrom on a stream ignores the from address - get the peername
   157 			if (from.Length())
   156 			if (from.Length())
   158 				SockName(1,from);
   157 				SockName(1,from);
   159 			
   158 
   160 			ATOMICSOCKETOP(iSocket.RecvOneOrMore(aDesc,rSockFlags,tempStatus,len),Complete(tempStatus,KErrBadHandle))			            
   159 			iSocket.RecvOneOrMore(aDesc,rSockFlags,tempStatus,len);            
   161 			break;
   160 			break;
   162 
   161 
   163 		case SOCK_SEQPACKET:
   162 		case SOCK_SEQPACKET:
   164 			// get the peername (as above)
   163 			// get the peername (as above)
   165 			if (from.Length())
   164 			if (from.Length())
   166 				SockName(1,from);
   165 				SockName(1,from);
   167 			ATOMICSOCKETOP(iSocket.Recv(aDesc, rSockFlags, tempStatus),Complete(tempStatus,KErrBadHandle))
   166 			iSocket.Recv(aDesc, rSockFlags, tempStatus);
   168 			
       
   169 			break;
   167 			break;
   170 
   168 
   171 		default: // including SOCK_RAW, SOCK_DGRAM
   169 		default: // including SOCK_RAW, SOCK_DGRAM
   172 			// assume datagram, as per behavior of original stdlib code:
   170 			// assume datagram, as per behavior of original stdlib code:
   173 		    ATOMICSOCKETOP(iSocket.RecvFrom(aDesc,from,rSockFlags,tempStatus,len),Complete(tempStatus,KErrBadHandle))
   171 			iSocket.RecvFrom(aDesc,from,rSockFlags,tempStatus,len);
   174 		}
   172 		}
   175 
   173 
   176 	User::WaitForRequest(tempStatus);
   174 	User::WaitForRequest(tempStatus);
   177 	len = aDesc.Length();
   175 	len = aDesc.Length();
   178 	if (tempStatus.Int() != KErrNone)
   176 	if (tempStatus.Int() != KErrNone)
   196 	TSockXfrLength len;
   194 	TSockXfrLength len;
   197 	TBool sendflg = EFalse;
   195 	TBool sendflg = EFalse;
   198 
   196 
   199 	if (to.Length()==0)
   197 	if (to.Length()==0)
   200 		{
   198 		{
   201         ATOMICSOCKETOP(iSocket.Send(aDesc,flags,tempStatus,len),Complete(tempStatus,KErrBadHandle))
   199 		iSocket.Send(aDesc,flags,tempStatus,len);
   202         sendflg = ETrue;
   200 		sendflg = ETrue;
   203 		}	
   201 		}	
   204 	else
   202 	else
   205 		{
   203 		{
   206 		if (isStream())
   204 		if (isStream())
   207 			Complete(aStatus,KErrNotSupported);	// can't sendto a stream
   205 			Complete(aStatus,KErrNotSupported);	// can't sendto a stream
   208 		else 
   206 		else 
   209 			{
   207 			{
   210 			ATOMICSOCKETOP(iSocket.SendTo(aDesc,to,flags,tempStatus,len),Complete(tempStatus,KErrBadHandle))			
   208 			iSocket.SendTo(aDesc,to,flags,tempStatus,len);
   211 			sendflg = ETrue;
   209 			sendflg = ETrue;
   212 			}
   210 			}
   213 		}
   211 		}
   214 
   212 
   215 	if(sendflg)
   213 	if(sendflg)
   242 	}
   240 	}
   243 
   241 
   244 TInt CSockDescBase::Poll(TUint aEvents)
   242 TInt CSockDescBase::Poll(TUint aEvents)
   245 	{
   243 	{
   246 	TInt status = 0;
   244 	TInt status = 0;
       
   245 	TInt err = 0;
   247 	TInt readyEvents = 0;
   246 	TInt readyEvents = 0;
   248 	TInt err = KErrNone;
   247 	err = iSocket.GetOpt(KSOSelectPoll, KSOLSocket, status);
   249 	ATOMICSOCKETOP(err = iSocket.GetOpt(KSOSelectPoll, KSOLSocket, status),err = KErrBadHandle)
       
   250 	
   248 	
   251 	if (err != KErrNone)
   249 	if (err != KErrNone)
   252 		{
   250 		{
   253 		// Poll should return any of the requested events.
   251 		// Poll should return any of the requested events.
   254 		// In case of any error, the error will be set, and can be later checked by the descriptor.
   252 		// In case of any error, the error will be set, and can be later checked by the descriptor.
   255 
   253 		
   256 
   254 		iPollErr = err;		
   257 		// For non-blocking socket, ensure to reset "iConnectInProgress" flag for a non-connected 
   255 		// For non-blocking socket, ensure to reset "iConnectInProgress" flag for a non-connected 
   258 		// socket on which a connection is pending.
   256 		// socket on which a connection is pending.
   259 		if(GetConnectionProgress())
   257 		if(GetConnectionProgress())
   260 			{
   258 			{
   261             iPollErr = err;
   259 			SetConnectionProgress(EFalse);
   262 
       
   263             SetConnectionProgress(EFalse);
       
   264 			}
   260 			}
   265 			
   261 			
   266 		// set all the events that has been requested for
   262 		// set all the events that has been requested for
   267 		// This handles a scenario where connect fails( in loopback )
   263 		// This handles a scenario where connect fails( in loopback )
   268 		// here poll should return all the events requested as ready
   264 		// here poll should return all the events requested as ready
   294 		readyEvents |= EReadyForWriting;
   290 		readyEvents |= EReadyForWriting;
   295 		}
   291 		}
   296 		
   292 		
   297 	if (status & KSockSelectExcept)
   293 	if (status & KSockSelectExcept)
   298 		{
   294 		{
   299 
   295 		if(GetConnectionProgress())
   300 		if (GetConnectionProgress())
   296 			{				
   301 			{		
       
   302 			TInt val = -1;
       
   303 			TInt ret = KErrNone;
       
   304 			ATOMICSOCKETOP(ret = iSocket.GetOpt(KSOSelectLastError, KSOLSocket, val),ret = KErrBadHandle)
       
   305 
       
   306 			(iPollErr = ret) || (iPollErr = val);
       
   307 			TBool setExceptFd = ETrue;
   297 			TBool setExceptFd = ETrue;
   308 			// Some special checks for non-blocking sockets.
   298 			// Some special checks for non-blocking sockets.
   309 			if(aEvents & EReadyForWriting)
   299 			if(aEvents & EReadyForWriting)
   310 				{
   300 				{
   311 				readyEvents |= EReadyForWriting;
   301 				readyEvents |= EReadyForWriting;
   368 		}
   358 		}
   369 	if (aEvents & EAnyException)
   359 	if (aEvents & EAnyException)
   370 		{
   360 		{
   371 		iSelectEvents() |= KSockSelectExcept;
   361 		iSelectEvents() |= KSockSelectExcept;
   372 		}
   362 		}
   373 	ATOMICSOCKETOP(iSocket.Ioctl(KIOctlSelect, aRequest, &iSelectEvents, KSOLSocket),Complete(aRequest,KErrBadHandle))	
   363 
       
   364 	iSocket.Ioctl(KIOctlSelect, aRequest, &iSelectEvents, KSOLSocket);
   374 	return KErrNone;	
   365 	return KErrNone;	
   375 	}
   366 	}
   376 
   367 
   377 // -----------------------------------------------------------------------------
   368 // -----------------------------------------------------------------------------
   378 // CSockDescBase::TweakWatchedEvents
   369 // CSockDescBase::TweakWatchedEvents
   399 // Prepares the socket behaviours specific output events
   390 // Prepares the socket behaviours specific output events
   400 // -----------------------------------------------------------------------------
   391 // -----------------------------------------------------------------------------
   401 //
   392 //
   402 TInt CSockDescBase::TweakReadyEvents(TInt errval)
   393 TInt CSockDescBase::TweakReadyEvents(TInt errval)
   403     {
   394     {
   404 
       
   405     TInt returnEvents = 0;
   395     TInt returnEvents = 0;
   406     if( errval >= KErrNone )
   396     if( errval >= KErrNone )
   407         {
   397         {
   408         // This file descriptor is socket-like
   398         // This file descriptor is socket-like
   409         // SelectEvents will also signal ioctlLock.
   399         // SelectEvents will also signal ioctlLock.
   422             // if it is a case of non blocking connect check for the flag 
   412             // if it is a case of non blocking connect check for the flag 
   423             // though the flag indicates connection is in progress, we come out of
   413             // though the flag indicates connection is in progress, we come out of
   424             // waitforNrequest only after a event
   414             // waitforNrequest only after a event
   425             if(GetConnectionProgress())
   415             if(GetConnectionProgress())
   426                 {
   416                 {
   427 
       
   428                 TInt val = -1;
       
   429                 TInt ret = KErrNone;
       
   430                 ATOMICSOCKETOP(ret = iSocket.GetOpt(KSOSelectLastError, KSOLSocket, val),ret = KErrBadHandle)
       
   431                 (iPollErr = ret) || (iPollErr = val);
       
   432 
       
   433             
       
   434                 returnEvents |= EReadyForReading;
   417                 returnEvents |= EReadyForReading;
   435                 returnEvents |= EReadyForWriting;
   418                 returnEvents |= EReadyForWriting;      
   436                 returnEvents |= EAnyException;
       
   437                 }
   419                 }
   438             else
   420             else
   439                 {
   421                 {
   440                 returnEvents |= EAnyException;
   422                 returnEvents |= EAnyException;
   441                 }
   423                 }
   444     else
   426     else
   445         {
   427         {
   446         if( GetConnectionProgress() )
   428         if( GetConnectionProgress() )
   447             {
   429             {
   448             // Dummy call to retrieve select events also unlocks the socket
   430             // Dummy call to retrieve select events also unlocks the socket
   449             const TUint events = GetSelectEvents();
   431             const TUint events = GetSelectEvents();                    
   450             
       
   451             TInt val = -1;
       
   452             TInt ret = KErrNone;
       
   453             ATOMICSOCKETOP(ret = iSocket.GetOpt(KSOSelectLastError, KSOLSocket, val),ret = KErrBadHandle)
       
   454             (iPollErr = ret) || (iPollErr = val);
       
   455             // set all the events that has been requested for
   432             // set all the events that has been requested for
   456             // This handles a scenario where connect fails( in loopback )
   433             // This handles a scenario where connect fails( in loopback )
   457             // here all the events requested should be ready ready
   434             // here all the events requested should be ready ready
   458             // Since PrepareOutputEvents is not aware of the events requested, all are
   435             // Since PrepareOutputEvents is not aware of the events requested, all are
   459             // set as ready and it will be filteret in select
   436             // set as ready and it will be filteret in select
   469     return returnEvents;
   446     return returnEvents;
   470     }
   447     }
   471 
   448 
   472 void CSockDescBase::CancelNotify()
   449 void CSockDescBase::CancelNotify()
   473 	{
   450 	{
   474 	ATOMICSOCKETOP(iSocket.CancelIoctl(),NOP)	
   451 	iSocket.CancelIoctl();
   475 	iIoctlLock.Signal();
   452 	iIoctlLock.Signal();
   476 	}
   453 	}
   477 
   454 
   478 TInt CSockDescBase::Listen(TUint qSize)
   455 TInt CSockDescBase::Listen(TUint qSize)
   479 	{	
   456 	{
   480 	TInt ret = KErrNone;
   457 	return iSocket.Listen(qSize);
   481 	ATOMICSOCKETOP(ret = iSocket.Listen(qSize), return KErrBadHandle)
       
   482 	return ret;
       
   483 	}
   458 	}
   484 
   459 
   485 void CSockDescBase::ReadCancel()
   460 void CSockDescBase::ReadCancel()
   486 	{
   461 	{
   487 	ATOMICSOCKETOP(iSocket.CancelRecv(),NOP)	
   462 	iSocket.CancelRecv();
   488 	}
   463 	}
   489 
   464 
   490 TInt CSockDescBase::ReadCompletion(TDes8& /*aBuf*/, TInt aStatus)
   465 TInt CSockDescBase::ReadCompletion(TDes8& /*aBuf*/, TInt aStatus)
   491 	{
   466 	{
   492 	if(KErrNone == aStatus)
   467 	if(KErrNone == aStatus)
   496 	return aStatus;
   471 	return aStatus;
   497 	}
   472 	}
   498 
   473 
   499 void CSockDescBase::RecvFromCancel()
   474 void CSockDescBase::RecvFromCancel()
   500 	{
   475 	{
   501 	ATOMICSOCKETOP(iSocket.CancelRecv(),NOP)	
   476 	iSocket.CancelRecv();
   502 	}
   477 	}
   503 
   478 
   504 void CSockDescBase::SendToCancel()
   479 void CSockDescBase::SendToCancel()
   505 	{
   480 	{
   506 	ATOMICSOCKETOP(iSocket.CancelSend(),NOP)
   481 	iSocket.CancelSend();
   507 	}
   482 	}
   508 
   483 
   509 void CSockDescBase::WriteCancel()
   484 void CSockDescBase::WriteCancel()
   510 	{
   485 	{
   511 	ATOMICSOCKETOP(iSocket.CancelWrite(),NOP)	
   486 	iSocket.CancelWrite();
   512 	}
   487 	}
   513 
   488 
   514 TInt CSockDescBase::SockName(int anEnd, TSockAddr& anAddr)
   489 TInt CSockDescBase::SockName(int anEnd, TSockAddr& anAddr)
   515 	{
   490 	{
   516 	const TUint KBadFamily = 0xFF000000;
   491 	const TUint KBadFamily = 0xFF000000;
   523 		return addr->iError;
   498 		return addr->iError;
   524 		}
   499 		}
   525 
   500 
   526 	anAddr.SetFamily(KBadFamily);
   501 	anAddr.SetFamily(KBadFamily);
   527 	if (anEnd==0)
   502 	if (anEnd==0)
   528 	    ATOMICSOCKETOP(iSocket.LocalName(anAddr),NOP)		
   503 		iSocket.LocalName(anAddr);
   529 	else
   504 	else
   530 	    ATOMICSOCKETOP(iSocket.RemoteName(anAddr),NOP)		
   505 		iSocket.RemoteName(anAddr);
   531 	if (anAddr.Family()==KBadFamily)
   506 	if (anAddr.Family()==KBadFamily)
   532 		return ENOTCONN; // assume that the call failed, but there is no way to find out why
   507 		return ENOTCONN; // assume that the call failed, but there is no way to find out why
   533 	return KErrNone;
   508 	return KErrNone;
   534 	}
   509 	}
   535 
   510 
   550 			break;		
   525 			break;		
   551 		default:
   526 		default:
   552 			Complete(aStatus,KErrArgument); // Invalid argument
   527 			Complete(aStatus,KErrArgument); // Invalid argument
   553 			return;
   528 			return;
   554 		}
   529 		}
   555 	ATOMICSOCKETOP(iSocket.Shutdown(how,aStatus),Complete(aStatus,KErrBadHandle))	
   530 	iSocket.Shutdown(how,aStatus);
   556 	return;
   531 	return;
   557 	}
   532 	}