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