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 |