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) |
117 { |
118 { |
118 break; |
119 break; |
119 } |
120 } |
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 { |
395 int errno_local=0; |
404 |
396 TInt returnEvents = 0; |
405 TInt returnEvents = 0; |
397 if( errval >= KErrNone ) |
406 if( errval >= KErrNone ) |
398 { |
407 { |
399 // This file descriptor is socket-like |
408 // This file descriptor is socket-like |
400 // SelectEvents will also signal ioctlLock. |
409 // SelectEvents will also signal ioctlLock. |
413 // 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 |
414 // 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 |
415 // waitforNrequest only after a event |
424 // waitforNrequest only after a event |
416 if(GetConnectionProgress()) |
425 if(GetConnectionProgress()) |
417 { |
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 |
418 returnEvents |= EReadyForReading; |
434 returnEvents |= EReadyForReading; |
419 returnEvents |= EReadyForWriting; |
435 returnEvents |= EReadyForWriting; |
|
436 returnEvents |= EAnyException; |
420 } |
437 } |
421 else |
438 else |
422 { |
439 { |
423 returnEvents |= EAnyException; |
440 returnEvents |= EAnyException; |
424 } |
441 } |
427 else |
444 else |
428 { |
445 { |
429 if( GetConnectionProgress() ) |
446 if( GetConnectionProgress() ) |
430 { |
447 { |
431 // Dummy call to retrieve select events also unlocks the socket |
448 // Dummy call to retrieve select events also unlocks the socket |
432 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); |
433 // set all the events that has been requested for |
455 // set all the events that has been requested for |
434 // This handles a scenario where connect fails( in loopback ) |
456 // This handles a scenario where connect fails( in loopback ) |
435 // here all the events requested should be ready ready |
457 // here all the events requested should be ready ready |
436 // Since PrepareOutputEvents is not aware of the events requested, all are |
458 // Since PrepareOutputEvents is not aware of the events requested, all are |
437 // set as ready and it will be filteret in select |
459 // set as ready and it will be filteret in select |
447 return returnEvents; |
469 return returnEvents; |
448 } |
470 } |
449 |
471 |
450 void CSockDescBase::CancelNotify() |
472 void CSockDescBase::CancelNotify() |
451 { |
473 { |
452 iSocket.CancelIoctl(); |
474 ATOMICSOCKETOP(iSocket.CancelIoctl(),NOP) |
453 iIoctlLock.Signal(); |
475 iIoctlLock.Signal(); |
454 } |
476 } |
455 |
477 |
456 TInt CSockDescBase::Listen(TUint qSize) |
478 TInt CSockDescBase::Listen(TUint qSize) |
457 { |
479 { |
458 return iSocket.Listen(qSize); |
480 TInt ret = KErrNone; |
|
481 ATOMICSOCKETOP(ret = iSocket.Listen(qSize), return KErrBadHandle) |
|
482 return ret; |
459 } |
483 } |
460 |
484 |
461 void CSockDescBase::ReadCancel() |
485 void CSockDescBase::ReadCancel() |
462 { |
486 { |
463 iSocket.CancelRecv(); |
487 ATOMICSOCKETOP(iSocket.CancelRecv(),NOP) |
464 } |
488 } |
465 |
489 |
466 TInt CSockDescBase::ReadCompletion(TDes8& /*aBuf*/, TInt aStatus) |
490 TInt CSockDescBase::ReadCompletion(TDes8& /*aBuf*/, TInt aStatus) |
467 { |
491 { |
468 if(KErrNone == aStatus) |
492 if(KErrNone == aStatus) |
472 return aStatus; |
496 return aStatus; |
473 } |
497 } |
474 |
498 |
475 void CSockDescBase::RecvFromCancel() |
499 void CSockDescBase::RecvFromCancel() |
476 { |
500 { |
477 iSocket.CancelRecv(); |
501 ATOMICSOCKETOP(iSocket.CancelRecv(),NOP) |
478 } |
502 } |
479 |
503 |
480 void CSockDescBase::SendToCancel() |
504 void CSockDescBase::SendToCancel() |
481 { |
505 { |
482 iSocket.CancelSend(); |
506 ATOMICSOCKETOP(iSocket.CancelSend(),NOP) |
483 } |
507 } |
484 |
508 |
485 void CSockDescBase::WriteCancel() |
509 void CSockDescBase::WriteCancel() |
486 { |
510 { |
487 iSocket.CancelWrite(); |
511 ATOMICSOCKETOP(iSocket.CancelWrite(),NOP) |
488 } |
512 } |
489 |
513 |
490 TInt CSockDescBase::SockName(int anEnd, TSockAddr& anAddr) |
514 TInt CSockDescBase::SockName(int anEnd, TSockAddr& anAddr) |
491 { |
515 { |
492 const TUint KBadFamily = 0xFF000000; |
516 const TUint KBadFamily = 0xFF000000; |
499 return addr->iError; |
523 return addr->iError; |
500 } |
524 } |
501 |
525 |
502 anAddr.SetFamily(KBadFamily); |
526 anAddr.SetFamily(KBadFamily); |
503 if (anEnd==0) |
527 if (anEnd==0) |
504 iSocket.LocalName(anAddr); |
528 ATOMICSOCKETOP(iSocket.LocalName(anAddr),NOP) |
505 else |
529 else |
506 iSocket.RemoteName(anAddr); |
530 ATOMICSOCKETOP(iSocket.RemoteName(anAddr),NOP) |
507 if (anAddr.Family()==KBadFamily) |
531 if (anAddr.Family()==KBadFamily) |
508 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 |
509 return KErrNone; |
533 return KErrNone; |
510 } |
534 } |
511 |
535 |