]> git.saurik.com Git - wxWidgets.git/blob - src/common/socket.cpp
IRIX compile fixes
[wxWidgets.git] / src / common / socket.cpp
1 ////////////////////////////////////////////////////////////////////////////////
2 // Name: socket.cpp
3 // Purpose: Socket handler classes
4 // Authors: Guilhem Lavaux (completely rewritten from a basic API of Andrew
5 // Davidson(1995) in wxWeb)
6 // Created: April 1997
7 // Updated: April 1999
8 // Copyright: (C) 1999 1998, 1997, Guilhem Lavaux
9 // RCS_ID: $Id$
10 // License: see wxWindows license
11 ////////////////////////////////////////////////////////////////////////////////
12 #ifdef __GNUG__
13 #pragma implementation "socket.h"
14 #endif
15
16 #ifdef __MWERKS__
17 typedef int socklen_t ;
18 #endif
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #if wxUSE_SOCKETS
28
29 /////////////////////////////////////////////////////////////////////////////
30 // wxWindows headers
31 /////////////////////////////////////////////////////////////////////////////
32 #include <wx/defs.h>
33 #include <wx/object.h>
34 #include <wx/string.h>
35 #include <wx/timer.h>
36 #include <wx/utils.h>
37
38 // IRIX requires bstring.h be included to use select()
39 #ifdef sgi
40 #include <bstring.h>
41 #endif // IRIX
42
43 // Not enough OS behaviour defined for wxStubs
44 #ifndef __WXSTUBS__
45
46 #include <stdlib.h>
47 #include <string.h>
48 #include <ctype.h>
49
50 /////////////////////////////////////////////////////////////////////////////
51 // System specific headers
52 /////////////////////////////////////////////////////////////////////////////
53 #ifdef __WXMAC__
54 // in order to avoid problems with our c library and double definitions
55 #define close closesocket
56 #define ioctl ioctlsocket
57
58 #include <wx/mac/macsock.h>
59
60 #endif
61
62 #if defined(__WINDOWS__)
63 #include <winsock.h>
64 #endif // __WINDOWS__
65
66 #if defined(__UNIX__)
67
68 #ifdef VMS
69 #include <socket.h>
70 #else
71 #include <sys/socket.h>
72 #endif
73 #include <sys/ioctl.h>
74
75 #include <sys/time.h>
76 #include <unistd.h>
77
78 #ifdef sun
79 #include <sys/filio.h>
80 #endif
81
82 #endif // __UNIX__
83
84 #include <signal.h>
85 #include <errno.h>
86
87 #ifdef __VISUALC__
88 #include <io.h>
89 #endif
90
91 /////////////////////////////////////////////////////////////////////////////
92 // wxSocket headers
93 /////////////////////////////////////////////////////////////////////////////
94 #include <wx/module.h>
95 #define WXSOCK_INTERNAL
96 #include <wx/sckaddr.h>
97 #include <wx/socket.h>
98 #include <wx/sckint.h>
99
100 // ----------------------
101 // Some patch ----- BEGIN
102 // ----------------------
103 #ifdef __WINDOWS__
104 #define close closesocket
105 #define ioctl ioctlsocket
106 #ifdef errno
107 #undef errno
108 #endif
109 #define errno WSAGetLastError()
110 #ifdef EWOULDBLOCK
111 #undef EWOULDBLOCK
112 #endif
113 #define EWOULDBLOCK WSAEWOULDBLOCK
114 #define ETIMEDOUT WSAETIMEDOUT
115 #undef EINTR
116 #define EINTR WSAEINTR
117 #endif
118
119 #ifndef __WINDOWS__
120 #define INVALID_SOCKET -1
121 #endif
122
123 #ifdef __WINDOWS__
124 // This is an MS TCP/IP routine and is not needed here. Some WinSock
125 // implementations (such as PC-NFS) will require you to include this
126 // or a similar routine (see appendix in WinSock doc or help file).
127
128 #if defined( NEED_WSAFDIsSet ) || defined( __VISUALC__ )
129 int PASCAL FAR __WSAFDIsSet(SOCKET fd, fd_set FAR *set)
130 {
131 int i = set->fd_count;
132
133 while (i--)
134 {
135 if (set->fd_array[i] == fd)
136 return 1;
137 }
138
139 return 0;
140 }
141 #endif
142 #endif
143
144 // -------------------
145 // Some patch ---- END
146 // -------------------
147
148 #ifdef GetClassInfo
149 #undef GetClassInfo
150 #endif
151
152 // --------------------------------------------------------------
153 // Module
154 // --------------------------------------------------------------
155 class wxSocketModule: public wxModule
156 {
157 DECLARE_DYNAMIC_CLASS(wxSocketModule)
158 public:
159 wxSocketModule() {}
160 bool OnInit();
161 void OnExit();
162 };
163
164 // --------------------------------------------------------------
165 // ClassInfos
166 // --------------------------------------------------------------
167 #if !USE_SHARED_LIBRARY
168 IMPLEMENT_CLASS(wxSocketBase, wxObject)
169 IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
170 IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
171 IMPLEMENT_CLASS(wxSocketHandler, wxObject)
172 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
173 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
174 #endif
175
176 // --------------------------------------------------------------
177 // --------- wxSocketBase CONSTRUCTOR ---------------------------
178 // --------------------------------------------------------------
179 wxSocketBase::wxSocketBase(wxSocketBase::wxSockFlags _flags,
180 wxSocketBase::wxSockType _type) :
181 wxEvtHandler(),
182 m_flags(_flags), m_type(_type), m_connected(FALSE), m_connecting(FALSE),
183 m_fd(INVALID_SOCKET), m_id(-1),
184 m_handler(0),
185 m_neededreq((wxRequestNotify)(REQ_READ | REQ_LOST)),
186 m_timeout(3600),
187 m_unread(NULL), m_unrd_size(0),
188 m_cbk(NULL), m_cdata(NULL),
189 m_notify_state(FALSE)
190 {
191 m_internal = new wxSocketInternal(this);
192 }
193
194 wxSocketBase::wxSocketBase() :
195 wxEvtHandler(),
196 m_flags(WAITALL), m_type(SOCK_UNINIT), m_connected(FALSE),
197 m_connecting(FALSE), m_fd(INVALID_SOCKET),
198 m_id(-1), m_handler(0),
199 m_neededreq((wxRequestNotify)(REQ_READ | REQ_LOST)),
200 m_timeout(3600),
201 m_unread(NULL), m_unrd_size(0),
202 m_cbk(NULL), m_cdata(NULL),
203 m_notify_state(FALSE)
204 {
205 m_internal = new wxSocketInternal(this);
206 }
207
208 // --------------------------------------------------------------
209 // wxSocketBase
210 // --------------------------------------------------------------
211
212 wxSocketBase::~wxSocketBase()
213 {
214 // First, close the file descriptor.
215 Close();
216
217 if (m_unread)
218 free(m_unread);
219 // Unregister from the handler database.
220 if (m_handler)
221 m_handler->UnRegister(this);
222
223 // Destroy all saved states.
224 m_states.DeleteContents(TRUE);
225
226 // Destroy the socket manager.
227 delete m_internal;
228 }
229
230 bool wxSocketBase::Close()
231 {
232 if (m_fd != INVALID_SOCKET)
233 {
234 if (m_notify_state == TRUE)
235 Notify(FALSE);
236
237 // Shutdown the connection.
238 shutdown(m_fd, 2);
239 close(m_fd);
240 m_fd = INVALID_SOCKET;
241 m_connected = FALSE;
242 }
243
244 return TRUE;
245 }
246
247 // --------------------------------------------------------------
248 // wxSocketBase base IO function
249 // --------------------------------------------------------------
250
251 wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes)
252 {
253 m_lcount = GetPushback(buffer, nbytes, FALSE);
254 nbytes -= m_lcount;
255 buffer += m_lcount;
256
257 // If we have got the whole needed buffer or if we don't want to
258 // wait then it returns immediately.
259 if (!nbytes || (m_lcount && !(m_flags & WAITALL)) ) {
260 return *this;
261 }
262
263 WantBuffer(buffer, nbytes, EVT_READ);
264
265 return *this;
266 }
267
268 wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes)
269 {
270 unsigned long len, len2, sig;
271 struct {
272 char sig[4];
273 char len[4];
274 } msg;
275
276 // sig should be an explicit 32-bit unsigned integer; I've seen
277 // compilers in which size_t was actually a 16-bit unsigned integer
278
279 Read((char *)&msg, sizeof(msg));
280 if (m_lcount != sizeof(msg))
281 return *this;
282
283 sig = msg.sig[0] & 0xff;
284 sig |= (size_t)(msg.sig[1] & 0xff) << 8;
285 sig |= (size_t)(msg.sig[2] & 0xff) << 16;
286 sig |= (size_t)(msg.sig[3] & 0xff) << 24;
287
288 if (sig != 0xfeeddead)
289 return *this;
290 len = msg.len[0] & 0xff;
291 len |= (size_t)(msg.len[1] & 0xff) << 8;
292 len |= (size_t)(msg.len[2] & 0xff) << 16;
293 len |= (size_t)(msg.len[3] & 0xff) << 24;
294
295 // len2 is incorrectly computed in the original; this sequence is
296 // the fix
297 if (len > nbytes) {
298 len2 = len - nbytes;
299 len = nbytes;
300 }
301 else
302 len2 = 0;
303
304 // the "len &&" in the following statement is necessary so that
305 // we don't attempt to read (and possibly hang the system)
306 // if the message was zero bytes long
307 if (len && Read(buffer, len).LastCount() != len)
308 return *this;
309 if (len2 && (Read(NULL, len2).LastCount() != len2))
310 return *this;
311 if (Read((char *)&msg, sizeof(msg)).LastCount() != sizeof(msg))
312 return *this;
313
314 sig = msg.sig[0] & 0xff;
315 sig |= (size_t)(msg.sig[1] & 0xff) << 8;
316 sig |= (size_t)(msg.sig[2] & 0xff) << 16;
317 sig |= (size_t)(msg.sig[3] & 0xff) << 24;
318 // ERROR
319 // we return *this either way, so a smart optimizer will
320 // optimize the following sequence out; I'm leaving it in anyway
321 if (sig != 0xdeadfeed)
322 return *this;
323
324 return *this;
325 }
326
327 wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes)
328 {
329 m_lcount = GetPushback(buffer, nbytes, TRUE);
330 if (nbytes-m_lcount == 0)
331 {
332 return *this;
333 }
334 buffer += m_lcount;
335 nbytes -= m_lcount;
336
337 WantBuffer(buffer, nbytes, EVT_PEEK);
338
339 return *this;
340 }
341
342 wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes)
343 {
344 m_lcount = 0;
345 WantBuffer((char *)buffer, nbytes, EVT_WRITE);
346 return *this;
347 }
348
349 wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes)
350 {
351 struct {
352 char sig[4];
353 char len[4];
354 } msg;
355
356 // warning about 'cast truncates constant value'
357 #ifdef __VISUALC__
358 #pragma warning(disable: 4310)
359 #endif // __VISUALC__
360
361 msg.sig[0] = (char) 0xad;
362 msg.sig[1] = (char) 0xde;
363 msg.sig[2] = (char) 0xed;
364 msg.sig[3] = (char) 0xfe;
365
366 msg.len[0] = (char) nbytes & 0xff;
367 msg.len[1] = (char) (nbytes >> 8) & 0xff;
368 msg.len[2] = (char) (nbytes >> 16) & 0xff;
369 msg.len[3] = (char) (nbytes >> 24) & 0xff;
370
371 if (Write((char *)&msg, sizeof(msg)).LastCount() < sizeof(msg))
372 return *this;
373 if (Write(buffer, nbytes).LastCount() < nbytes)
374 return *this;
375
376 msg.sig[0] = (char) 0xed;
377 msg.sig[1] = (char) 0xfe;
378 msg.sig[2] = (char) 0xad;
379 msg.sig[3] = (char) 0xde;
380 msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = (char) 0;
381 Write((char *)&msg, sizeof(msg));
382
383 return *this;
384
385 #ifdef __VISUALC__
386 #pragma warning(default: 4310)
387 #endif // __VISUALC__
388 }
389
390 wxSocketBase& wxSocketBase::Unread(const char *buffer, size_t nbytes)
391 {
392 m_lcount = 0;
393 if (nbytes != 0) {
394 CreatePushbackAfter(buffer, nbytes);
395 m_lcount = nbytes;
396 }
397 return *this;
398 }
399
400 bool wxSocketBase::IsData() const
401 {
402 struct timeval tv;
403 fd_set sock_set;
404
405 if (m_fd < 0)
406 return FALSE;
407 if (m_unrd_size > 0)
408 return TRUE;
409
410 m_internal->AcquireFD();
411
412 tv.tv_sec = 0;
413 tv.tv_usec = 0;
414 FD_ZERO(&sock_set);
415 FD_SET(m_fd, &sock_set);
416 select(m_fd+1, &sock_set, NULL, NULL, &tv);
417
418 m_internal->ReleaseFD();
419
420 return (FD_ISSET(m_fd, &sock_set) != 0);
421 }
422
423 // ---------------------------------------------------------------------
424 // --------- wxSocketBase Discard(): deletes all byte in the input queue
425 // ---------------------------------------------------------------------
426 void wxSocketBase::Discard()
427 {
428 #define MAX_BUFSIZE (10*1024)
429 char *my_data = new char[MAX_BUFSIZE];
430 size_t recv_size = MAX_BUFSIZE;
431
432 SaveState();
433 SetFlags((wxSockFlags)(NOWAIT | SPEED));
434
435 while (recv_size == MAX_BUFSIZE)
436 {
437 recv_size = Read(my_data, MAX_BUFSIZE).LastCount();
438 }
439
440 RestoreState();
441 delete [] my_data;
442
443 #undef MAX_BUFSIZE
444 }
445
446 // If what? Who seems to need unsigned int?
447 // BTW uint isn't even defined on wxMSW for VC++ for some reason. Even if it
448 // were, getpeername/getsockname don't take unsigned int*, they take int*.
449 //
450 // Under glibc 2.0.7, socketbits.h declares socklen_t to be unsigned int
451 // and it uses *socklen_t as the 3rd parameter. Robert.
452
453 // JACS - How can we detect this?
454 // Meanwhile, if your compiler complains about socklen_t,
455 // switch lines below.
456
457 #if wxHAVE_GLIBC2
458 # define wxSOCKET_INT socklen_t
459 #else
460 # define wxSOCKET_INT int
461 #endif
462
463 // --------------------------------------------------------------
464 // wxSocketBase socket info functions
465 // --------------------------------------------------------------
466
467 bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
468 {
469 struct sockaddr my_addr;
470 wxSOCKET_INT len_addr = sizeof(my_addr);
471
472 if (m_fd < 0)
473 return FALSE;
474
475 m_internal->AcquireFD();
476
477 if (getpeername(m_fd, (struct sockaddr *)&my_addr, &len_addr) < 0) {
478 m_internal->ReleaseFD();
479 return FALSE;
480 }
481
482 m_internal->ReleaseFD();
483 addr_man.Disassemble(&my_addr, len_addr);
484 return TRUE;
485 }
486
487 bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
488 {
489 struct sockaddr my_addr;
490 wxSOCKET_INT len_addr = sizeof(my_addr);
491
492 if (m_fd < 0)
493 return FALSE;
494
495 m_internal->AcquireFD();
496
497 if (getsockname(m_fd, (struct sockaddr *)&my_addr, &len_addr) < 0) {
498 m_internal->ReleaseFD();
499 return FALSE;
500 }
501 m_internal->ReleaseFD();
502
503 addr_man.Disassemble(&my_addr, len_addr);
504 return TRUE;
505 }
506
507 // --------------------------------------------------------------
508 // wxSocketBase wait functions
509 // --------------------------------------------------------------
510
511 void wxSocketBase::SaveState()
512 {
513 SocketState *state = new SocketState;
514
515 state->notify_state = m_notify_state;
516 state->evt_notify_state = m_neededreq;
517 state->socket_flags = m_flags;
518 state->c_callback = m_cbk;
519 state->c_callback_data = m_cdata;
520
521 m_states.Append((wxObject *)state);
522 }
523
524 void wxSocketBase::RestoreState()
525 {
526 wxNode *node;
527 SocketState *state;
528
529 node = m_states.Last();
530 if (!node)
531 return;
532
533 state = (SocketState *)node->Data();
534
535 SetFlags(state->socket_flags);
536 m_internal->AcquireData();
537 m_neededreq = state->evt_notify_state;
538 m_internal->ReleaseData();
539 m_cbk = state->c_callback;
540 m_cdata = state->c_callback_data;
541 Notify(state->notify_state);
542
543 delete node;
544 delete state;
545 }
546
547 // --------------------------------------------------------------
548 // --------- wxSocketBase callback functions --------------------
549 // --------------------------------------------------------------
550
551 wxSocketBase::wxSockCbk wxSocketBase::Callback(wxSockCbk cbk_)
552 {
553 wxSockCbk old_cbk = cbk_;
554
555 m_cbk = cbk_;
556 return old_cbk;
557 }
558
559 char *wxSocketBase::CallbackData(char *data)
560 {
561 char *old_data = m_cdata;
562
563 m_cdata = data;
564 return old_data;
565 }
566
567 // --------------------------------------------------------------
568 // --------- wxSocketBase wait functions ------------------------
569 // --------------------------------------------------------------
570
571 bool wxSocketBase::_Wait(long seconds, long milliseconds, int type)
572 {
573 SockRequest *req;
574
575 if ((!m_connected && !m_connecting) || m_fd < 0)
576 return FALSE;
577
578 req = new SockRequest;
579
580 req->type = REQ_WAIT | type;
581 req->timeout = seconds * 1000 + milliseconds;
582 req->done = FALSE;
583 req->buffer = NULL;
584 req->size = 0;
585 req->error = 0;
586 req->wait = TRUE;
587 m_internal->QueueRequest(req, TRUE);
588
589 return (req->io_nbytes != 0);
590 }
591
592 bool wxSocketBase::Wait(long seconds, long milliseconds)
593 {
594 return _Wait(seconds, milliseconds, REQ_ACCEPT | REQ_CONNECT |
595 REQ_READ | REQ_WRITE | REQ_LOST);
596 }
597
598 bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
599 {
600 return _Wait(seconds, milliseconds, REQ_READ | REQ_LOST);
601 }
602
603 bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
604 {
605 return _Wait(seconds, milliseconds, REQ_WRITE);
606 }
607
608 bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
609 {
610 return _Wait(seconds, milliseconds, REQ_LOST);
611 }
612
613 // --------------------------------------------------------------
614 // --------- wxSocketBase callback management -------------------
615 // --------------------------------------------------------------
616
617 wxSocketBase::wxRequestNotify wxSocketBase::EventToNotify(wxRequestEvent evt)
618 {
619 switch (evt)
620 {
621 case EVT_READ:
622 return REQ_READ;
623 case EVT_PEEK:
624 return REQ_PEEK;
625 case EVT_WRITE:
626 return REQ_WRITE;
627 case EVT_LOST:
628 return REQ_LOST;
629 case EVT_ACCEPT:
630 return REQ_ACCEPT;
631 case EVT_CONNECT:
632 return REQ_CONNECT;
633 }
634 return 0;
635 }
636
637 void wxSocketBase::SetFlags(wxSockFlags _flags)
638 {
639 m_flags = _flags;
640 if (_flags & SPEED) {
641 // SPEED and WAITALL are antagonists.
642 m_flags = (wxSockFlags)(m_flags & ~WAITALL);
643 }
644 }
645
646 wxSocketBase::wxSockFlags wxSocketBase::GetFlags() const
647 {
648 return m_flags;
649 }
650
651 void wxSocketBase::SetNotify(wxRequestNotify flags)
652 {
653 /* Check if server */
654 if (m_type != SOCK_SERVER)
655 flags &= ~REQ_ACCEPT;
656
657 m_internal->AcquireData();
658 m_neededreq = flags;
659 m_internal->ReleaseData();
660 if (m_neededreq == 0)
661 m_internal->StopWaiter();
662 else
663 Notify(m_notify_state);
664 }
665
666 void wxSocketBase::Notify(bool notify)
667 {
668 m_notify_state = notify;
669 if (m_fd == INVALID_SOCKET)
670 return;
671
672 if (notify)
673 m_internal->ResumeWaiter();
674 else
675 m_internal->StopWaiter();
676 }
677
678 void wxSocketBase::OnRequest(wxRequestEvent req_evt)
679 {
680 wxSocketEvent event(m_id);
681 wxRequestNotify notify = EventToNotify(req_evt);
682
683 if ((m_neededreq & notify) == notify) {
684 event.m_socket = this;
685 event.m_skevt = req_evt;
686 ProcessEvent(event);
687 // TODOTODO
688 // OldOnNotify(req_evt);
689
690 // We disable the event reporting.
691 m_neededreq &= ~notify;
692 }
693 }
694
695 wxSocketEvent::wxSocketEvent(int id)
696 : wxEvent(id)
697 {
698 wxEventType type = (wxEventType)wxEVT_SOCKET;
699
700 SetEventType(type);
701 }
702
703 void wxSocketEvent::CopyObject(wxObject& obj_d) const
704 {
705 wxSocketEvent *event = (wxSocketEvent *)&obj_d;
706
707 wxEvent::CopyObject(obj_d);
708
709 event->m_skevt = m_skevt;
710 event->m_socket = m_socket;
711 }
712
713 void wxSocketBase::OldOnNotify(wxRequestEvent evt)
714 {
715 }
716
717 // --------------------------------------------------------------
718 // --------- wxSocketBase functions [Callback, CallbackData] ----
719 // --------------------------------------------------------------
720
721 void wxSocketBase::SetEventHandler(wxEvtHandler& h_evt, int id)
722 {
723 SetNextHandler(&h_evt);
724 m_id = id;
725 }
726
727 // --------------------------------------------------------------
728 // --------- wxSocketBase pushback library ----------------------
729 // --------------------------------------------------------------
730
731 void wxSocketBase::CreatePushbackAfter(const char *buffer, size_t size)
732 {
733 char *curr_pos;
734
735 if (m_unread != NULL)
736 m_unread = (char *) realloc(m_unread, m_unrd_size+size);
737 else
738 m_unread = (char *) malloc(size);
739 curr_pos = m_unread + m_unrd_size;
740
741 memcpy(curr_pos, buffer, size);
742 m_unrd_size += size;
743 }
744
745 void wxSocketBase::CreatePushbackBefore(const char *buffer, size_t size)
746 {
747 char *curr_pos, *new_buf;
748
749 new_buf = (char *) malloc(m_unrd_size+size);
750 curr_pos = new_buf + size;
751
752 memcpy(new_buf, buffer, size);
753 if (m_unrd_size != 0) {
754 memcpy(curr_pos, m_unread, m_unrd_size);
755 free(m_unread);
756 }
757 m_unread = new_buf;
758 m_unrd_size += size;
759 }
760
761 size_t wxSocketBase::GetPushback(char *buffer, size_t size, bool peek)
762 {
763 if (!m_unrd_size)
764 return 0;
765
766 if (size > m_unrd_size)
767 size = m_unrd_size;
768 memcpy(buffer, m_unread, size);
769
770 if (!peek) {
771 m_unrd_size -= size;
772 if (m_unrd_size == 0) {
773 free(m_unread);
774 m_unread = NULL;
775 }
776 }
777
778 return size;
779 }
780
781 // --------------------------------------------------------------
782 // --------- wxSocketBase buffer core requester -----------------
783 // --------------------------------------------------------------
784
785 void wxSocketBase::WantBuffer(char *buffer, size_t nbytes,
786 wxRequestEvent evt)
787 {
788 bool buf_timed_out;
789
790 if (m_fd == INVALID_SOCKET || !m_handler || !m_connected)
791 return;
792
793 SockRequest *buf = new SockRequest;
794
795 SaveState();
796 buf->buffer = buffer;
797 buf->size = nbytes;
798 buf->done = FALSE;
799 buf->type = EventToNotify(evt);
800 buf->io_nbytes = 0;
801 buf->error = 0;
802 buf->wait = TRUE;
803 buf->timeout = 1000;
804 buf_timed_out = FALSE;
805
806 if ((m_flags & SPEED) != 0)
807 m_internal->QueueRequest(buf, FALSE);
808 else
809 if ((m_flags & NOWAIT) != 0)
810 m_internal->QueueRequest(buf, TRUE);
811 else
812 m_internal->QueueRequest(buf, TRUE);
813 m_lcount += buf->io_nbytes;
814 if (buf_timed_out)
815 m_error = ETIMEDOUT;
816 else
817 m_error = buf->error;
818
819 delete buf;
820 RestoreState();
821 }
822
823 // --------------------------------------------------------------
824 // wxSocketServer
825 // --------------------------------------------------------------
826
827 wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
828 wxSockFlags flags) :
829 wxSocketBase(flags, SOCK_SERVER)
830 {
831 m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0);
832
833 if (m_fd == INVALID_SOCKET)
834 return;
835
836 int flag = 1;
837 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(int));
838
839 struct sockaddr *myaddr;
840 size_t len;
841
842 addr_man.Build(myaddr, len);
843 if (bind(m_fd, myaddr, addr_man.SockAddrLen()) < 0)
844 return;
845
846 if (listen(m_fd, 5) < 0) {
847 m_fd = INVALID_SOCKET;
848 return;
849 }
850
851 m_internal->SetFD(m_fd);
852
853 Notify(TRUE);
854 }
855
856 // --------------------------------------------------------------
857 // wxSocketServer Accept
858 // --------------------------------------------------------------
859
860 bool wxSocketServer::AcceptWith(wxSocketBase& sock)
861 {
862 int fd2;
863
864 m_internal->AcquireFD();
865 if ((fd2 = accept(m_fd, 0, 0)) < 0) {
866 m_internal->ReleaseFD();
867 return FALSE;
868 }
869 m_internal->ReleaseFD();
870
871 struct linger linger;
872 linger.l_onoff = 0;
873 linger.l_linger = 1;
874
875 setsockopt(fd2, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger));
876
877 int flag = 0;
878 setsockopt(fd2, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(int));
879
880 sock.m_type = SOCK_INTERNAL;
881 sock.m_fd = fd2;
882 sock.m_connected = TRUE;
883
884 sock.m_internal->SetFD(fd2);
885
886 sock.m_internal->ResumeWaiter();
887
888 return TRUE;
889 }
890
891 wxSocketBase *wxSocketServer::Accept()
892 {
893 wxSocketBase* sock = new wxSocketBase();
894
895 sock->SetFlags((wxSockFlags)m_flags);
896
897 if (!AcceptWith(*sock))
898 return NULL;
899
900 if (m_handler)
901 m_handler->Register(sock);
902
903 return sock;
904 }
905
906 // --------------------------------------------------------------
907 // wxSocketClient
908 // --------------------------------------------------------------
909
910 // --------- wxSocketClient CONSTRUCTOR -------------------------
911 // --------------------------------------------------------------
912 wxSocketClient::wxSocketClient(wxSockFlags _flags) :
913 wxSocketBase(_flags, SOCK_CLIENT)
914 {
915 }
916
917 // --------------------------------------------------------------
918 // --------- wxSocketClient DESTRUCTOR --------------------------
919 // --------------------------------------------------------------
920 wxSocketClient::~wxSocketClient()
921 {
922 }
923
924 // --------------------------------------------------------------
925 // --------- wxSocketClient Connect functions -------------------
926 // --------------------------------------------------------------
927 bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) )
928 {
929 struct linger linger;
930
931 if (IsConnected())
932 Close();
933
934 // Initializes all socket stuff ...
935 // --------------------------------
936 m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0);
937
938 if (m_fd < 0)
939 return FALSE;
940
941 m_connected = FALSE;
942
943 linger.l_onoff = 1;
944 linger.l_linger = 5;
945 setsockopt(m_fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger));
946
947 // Stay in touch with the state of things...
948
949 unsigned long flag = 1;
950 setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(int));
951
952 // Disable the nagle algorithm, which delays sends till the
953 // buffer is full (or a certain time period has passed?)...
954
955 #if defined(__WINDOWS__) || (defined(IPPROTO_TCP) && defined(TCP_NODELAY))
956 flag = 1;
957 setsockopt(m_fd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int));
958 #endif
959
960 struct sockaddr *remote;
961 size_t len;
962
963 addr_man.Build(remote, len);
964
965 if (connect(m_fd, remote, len) != 0)
966 return FALSE;
967
968 m_internal->SetFD(m_fd);
969
970 // Enables bg events.
971 // ------------------
972 Notify(TRUE);
973
974 m_connected = TRUE;
975 return TRUE;
976 }
977
978 bool wxSocketClient::WaitOnConnect(long seconds, long microseconds)
979 {
980 int ret = _Wait(seconds, microseconds, REQ_CONNECT | REQ_LOST);
981
982 if (ret)
983 m_connected = TRUE;
984
985 return m_connected;
986 }
987
988 void wxSocketClient::OnRequest(wxRequestEvent evt)
989 {
990 if (evt == EVT_CONNECT)
991 {
992 if (m_connected)
993 {
994 m_neededreq &= ~REQ_CONNECT;
995 return;
996 }
997 m_connected = TRUE;
998 return;
999 }
1000 wxSocketBase::OnRequest(evt);
1001 }
1002
1003 /////////////////////////////////////////////////////////////////
1004 // wxSocketHandler ///////////////////////////////////////////////
1005 /////////////////////////////////////////////////////////////////
1006
1007 wxSocketHandler *wxSocketHandler::master = NULL;
1008 #if defined(__WINDOWS__)
1009 static int win_initialized = 0;
1010 #endif
1011
1012 // --------------------------------------------------------------
1013 // --------- wxSocketHandler CONSTRUCTOR ------------------------
1014 // --------------------------------------------------------------
1015 wxSocketHandler::wxSocketHandler()
1016 {
1017 #if defined(__WINDOWS__)
1018 if (!win_initialized)
1019 {
1020 WSADATA wsaData;
1021
1022 WSAStartup((1 << 8) | 1, &wsaData);
1023 win_initialized = 1;
1024 }
1025 #endif
1026
1027 socks = new wxList;
1028
1029 #ifndef __WINDOWS__
1030 signal(SIGPIPE, SIG_IGN);
1031 #endif
1032 }
1033
1034 // --------------------------------------------------------------
1035 // --------- wxSocketHandler DESTRUCTOR -------------------------
1036 // --------------------------------------------------------------
1037 wxSocketHandler::~wxSocketHandler()
1038 {
1039 wxNode *next_node, *node = socks->First();
1040
1041 while (node)
1042 {
1043 wxSocketBase* sock = (wxSocketBase*)node->Data();
1044
1045 delete sock;
1046 next_node = node->Next();
1047 delete node;
1048 node = next_node;
1049 }
1050
1051 delete socks;
1052
1053 #ifdef __WINDOWS__
1054 WSACleanup();
1055 win_initialized = 0;
1056 #endif
1057 }
1058
1059 // --------------------------------------------------------------
1060 // --------- wxSocketHandler registering functions --------------
1061 // --------------------------------------------------------------
1062
1063 void wxSocketHandler::Register(wxSocketBase* sock)
1064 {
1065 wxNode *node;
1066
1067 for (node = socks->First(); node != NULL; node = node->Next())
1068 {
1069 wxSocketBase* s = (wxSocketBase*)node->Data();
1070
1071 if (s == sock)
1072 return;
1073 }
1074
1075 if (sock)
1076 {
1077 socks->Append(sock);
1078 sock->SetHandler(this);
1079 }
1080 }
1081
1082 void wxSocketHandler::UnRegister(wxSocketBase* sock)
1083 {
1084 wxNode *node;
1085
1086 for (node = socks->First(); node; node = node->Next())
1087 {
1088 wxSocketBase* s = (wxSocketBase*)node->Data();
1089
1090 if (s == sock)
1091 {
1092 delete node;
1093 sock->SetHandler(NULL);
1094 return;
1095 }
1096 }
1097 }
1098
1099 unsigned long wxSocketHandler::Count() const
1100 {
1101 return socks->Number();
1102 }
1103
1104 // --------------------------------------------------------------
1105 // --------- wxSocketHandler "big" wait functions ---------------
1106 // --------------------------------------------------------------
1107
1108 int wxSocketHandler::Wait(long seconds, long microseconds)
1109 {
1110 // TODO Needs the completely asynchronous notifier.
1111
1112 /*
1113 int i;
1114 int on_wait;
1115 wxNode *node;
1116 for (node = socks->First(), i=0; node; node = node->Next(), i++)
1117 {
1118 wxSocketBase *sock = (wxSocketBase *)node->Data();
1119
1120 sock->SaveState();
1121
1122 sock->SetupCallbacks();
1123
1124 sock->Callback(handler_cbk);
1125 sock->CallbackData((char *)&on_wait);
1126 }
1127 on_wait = 0;
1128 if (seconds != -1)
1129 s_wake.Start((seconds*1000) + (microseconds/1000), TRUE);
1130
1131 while (!on_wait)
1132 PROCESS_EVENTS();
1133
1134 for (node = socks->First(), i=0; node; node = node->Next(), i++)
1135 {
1136 wxSocketBase *sock = (wxSocketBase *)node->Data();
1137
1138 sock->RestoreState();
1139 }
1140
1141 if (on_wait == -2)
1142 return 0;
1143
1144 return on_wait;
1145 */
1146 return 0;
1147 }
1148
1149 void wxSocketHandler::YieldSock()
1150 {
1151 wxNode *node;
1152
1153 // Nothing to do anymore here except waiting for the queue emptying.
1154 for (node = socks->First(); node; node=node->Next()) {
1155 wxSocketBase *sock = (wxSocketBase *)node->Data();
1156
1157 sock->m_internal->WaitForEnd(NULL);
1158 }
1159 }
1160
1161 // --------------------------------------------------------------
1162 // --------- wxSocketHandler: create and register the socket ----
1163 // --------------------------------------------------------------
1164 wxSocketServer *wxSocketHandler::CreateServer(wxSockAddress& addr,
1165 wxSocketBase::wxSockFlags flags)
1166 {
1167 wxSocketServer *serv = new wxSocketServer(addr, flags);
1168
1169 Register(serv);
1170 return serv;
1171 }
1172
1173 wxSocketClient *wxSocketHandler::CreateClient(wxSocketBase::wxSockFlags flags)
1174 {
1175 wxSocketClient *client = new wxSocketClient(flags);
1176
1177 Register(client);
1178 return client;
1179 }
1180
1181 bool wxSocketModule::OnInit()
1182 {
1183 wxSocketHandler::master = new wxSocketHandler();
1184 return TRUE;
1185 }
1186
1187 void wxSocketModule::OnExit()
1188 {
1189 delete wxSocketHandler::master;
1190 wxSocketHandler::master = NULL;
1191 }
1192
1193 #endif
1194 // __WXSTUBS__
1195
1196 #endif
1197 // wxUSE_SOCKETS