]> git.saurik.com Git - wxWidgets.git/blame - src/unix/sockunix.cpp
remove tabs added by error in previous commit
[wxWidgets.git] / src / unix / sockunix.cpp
CommitLineData
51fe4b60 1/////////////////////////////////////////////////////////////////////////////
60913641 2// Name: src/unix/sockunix.cpp
51fe4b60
VZ
3// Purpose: wxSocketImpl implementation for Unix systems
4// Authors: Guilhem Lavaux, Guillermo Rodriguez Garcia, David Elliott,
5// Vadim Zeitlin
6// Created: April 1997
7// RCS-ID: $Id$
8// Copyright: (c) 1997 Guilhem Lavaux
9// (c) 2008 Vadim Zeitlin
10// Licence: wxWindows licence
11/////////////////////////////////////////////////////////////////////////////
12
97e6ee04 13
7e1e6965 14#include "wx/wxprec.h"
7e1e6965 15
ebf94940
VZ
16#if wxUSE_SOCKETS
17
ebf94940
VZ
18#include "wx/private/fd.h"
19#include "wx/private/socket.h"
60913641 20#include "wx/unix/private/sockunix.h"
97e6ee04 21
c9bccf23 22#include <errno.h>
97e6ee04 23
ebf94940 24#if defined(__WATCOMC__)
c9bccf23 25 #include <nerrno.h>
ebf94940 26#endif
02564412 27
97e6ee04 28#include <sys/types.h>
97e6ee04 29
bc023abb
MW
30#ifdef HAVE_SYS_SELECT_H
31# include <sys/select.h>
32#endif
33
ebdab982 34#ifdef __EMX__
c9bccf23 35 #include <sys/select.h>
d1f8e97b 36#endif
97e6ee04 37
9e03e02d 38#ifndef WX_SOCKLEN_T
97e6ee04
DE
39
40#ifdef VMS
9e03e02d 41# define WX_SOCKLEN_T unsigned int
97e6ee04
DE
42#else
43# ifdef __GLIBC__
44# if __GLIBC__ == 2
9e03e02d 45# define WX_SOCKLEN_T socklen_t
97e6ee04 46# endif
fcbd7e5a 47# elif defined(__WXMAC__)
9e03e02d 48# define WX_SOCKLEN_T socklen_t
97e6ee04 49# else
9e03e02d 50# define WX_SOCKLEN_T int
97e6ee04
DE
51# endif
52#endif
53
54#endif /* SOCKLEN_T */
55
ddc1a35f 56#ifndef SOCKOPTLEN_T
c9bccf23 57 #define SOCKOPTLEN_T WX_SOCKLEN_T
ddc1a35f
DE
58#endif
59
c9bccf23 60// UnixWare reportedly needs this for FIONBIO definition
97e6ee04 61#ifdef __UNIXWARE__
c9bccf23 62 #include <sys/filio.h>
2887cb4e 63#endif
71b4a9b8 64
62088a3c
VZ
65// ============================================================================
66// wxSocketImpl implementation
67// ============================================================================
68
54cb21d6
VZ
69/* static */
70wxSocketImpl *wxSocketImpl::Create(wxSocketBase& wxsocket)
71{
72 return new wxSocketImplUnix(wxsocket);
73}
74
97e6ee04 75
2b036c4b 76wxSocketError wxSocketImplUnix::GetLastError() const
97e6ee04 77{
2b036c4b
VZ
78 switch ( errno )
79 {
80 case 0:
81 return wxSOCKET_NOERROR;
97e6ee04 82
2b036c4b
VZ
83 case ENOTSOCK:
84 return wxSOCKET_INVSOCK;
97e6ee04 85
42dfe2b2
VZ
86 // unfortunately EAGAIN only has the "would block" meaning for read(),
87 // not for connect() for which it means something rather different but
88 // we can't distinguish between these two situations currently...
14372de8
VZ
89 //
90 // also notice that EWOULDBLOCK can be different from EAGAIN on some
91 // systems (HP-UX being the only known example) while it's defined as
92 // EAGAIN on most others (e.g. Linux)
42dfe2b2 93 case EAGAIN:
14372de8
VZ
94#ifdef EWOULDBLOCK
95 #if EWOULDBLOCK != EAGAIN
96 case EWOULDBLOCK:
97 #endif
98#endif // EWOULDBLOCK
2b036c4b
VZ
99 case EINPROGRESS:
100 return wxSOCKET_WOULDBLOCK;
97e6ee04 101
2b036c4b
VZ
102 default:
103 return wxSOCKET_IOERR;
104 }
97e6ee04
DE
105}
106
51fe4b60 107void wxSocketImplUnix::DoEnableEvents(bool flag)
2804f77d 108{
51fe4b60 109 wxSocketManager * const manager = wxSocketManager::Get();
f0fbbe23
VZ
110 if ( flag )
111 {
51fe4b60
VZ
112 manager->Install_Callback(this, wxSOCKET_INPUT);
113 manager->Install_Callback(this, wxSOCKET_OUTPUT);
f0fbbe23
VZ
114 }
115 else // off
116 {
51fe4b60
VZ
117 manager->Uninstall_Callback(this, wxSOCKET_INPUT);
118 manager->Uninstall_Callback(this, wxSOCKET_OUTPUT);
60edcf45 119 }
60edcf45
VZ
120}
121
97e6ee04 122
51fe4b60 123void wxSocketImplUnix::OnStateChange(wxSocketNotify event)
53a161e1 124{
53a161e1
VZ
125 NotifyOnStateChange(event);
126
51fe4b60 127 if ( event == wxSOCKET_LOST )
53a161e1
VZ
128 Shutdown();
129}
130
a9d859df 131void wxSocketImplUnix::OnReadWaiting()
97e6ee04
DE
132{
133 char c;
134
bb154f79
KH
135 if (m_fd == INVALID_SOCKET)
136 {
137 return;
138 }
139
14372de8 140 int num = recv(m_fd, &c, 1, MSG_PEEK);
bb154f79
KH
141
142 if (num > 0)
97e6ee04 143 {
51fe4b60 144 OnStateChange(wxSOCKET_INPUT);
97e6ee04
DE
145 }
146 else
147 {
09e6e5ec 148 if (m_server && m_stream)
97e6ee04 149 {
51fe4b60 150 OnStateChange(wxSOCKET_CONNECTION);
97e6ee04 151 }
e37e082e
VZ
152 else if (num == 0)
153 {
01c03554
VZ
154 if (m_stream)
155 {
156 /* graceful shutdown */
51fe4b60 157 OnStateChange(wxSOCKET_LOST);
01c03554
VZ
158 }
159 else
160 {
161 /* Empty datagram received */
51fe4b60 162 OnStateChange(wxSOCKET_INPUT);
01c03554 163 }
e37e082e 164 }
97e6ee04
DE
165 else
166 {
e400d27d 167 /* Do not throw a lost event in cases where the socket isn't really lost */
7e1e6965 168 if ((errno == EWOULDBLOCK) || (errno == EAGAIN) || (errno == EINTR))
bb154f79 169 {
51fe4b60 170 OnStateChange(wxSOCKET_INPUT);
bb154f79 171 }
7e1e6965 172 else
bb154f79 173 {
51fe4b60 174 OnStateChange(wxSOCKET_LOST);
7e1e6965 175 }
97e6ee04
DE
176 }
177 }
178}
179
a9d859df 180void wxSocketImplUnix::OnWriteWaiting()
97e6ee04 181{
09e6e5ec 182 if (m_establishing && !m_server)
97e6ee04
DE
183 {
184 int error;
ddc1a35f 185 SOCKOPTLEN_T len = sizeof(error);
97e6ee04 186
948c96ef 187 m_establishing = false;
97e6ee04 188
f71bb8ef 189 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
97e6ee04
DE
190
191 if (error)
192 {
51fe4b60 193 OnStateChange(wxSOCKET_LOST);
97e6ee04
DE
194 }
195 else
196 {
51fe4b60 197 OnStateChange(wxSOCKET_CONNECTION);
97e6ee04
DE
198 /* We have to fire this event by hand because CONNECTION (for clients)
199 * and OUTPUT are internally the same and we just disabled CONNECTION
200 * events with the above macro.
201 */
51fe4b60 202 OnStateChange(wxSOCKET_OUTPUT);
97e6ee04
DE
203 }
204 }
205 else
206 {
51fe4b60 207 OnStateChange(wxSOCKET_OUTPUT);
97e6ee04
DE
208 }
209}
210
a9d859df
VZ
211void wxSocketImplUnix::OnExceptionWaiting()
212{
213 wxFAIL_MSG( "not supposed to be called" );
214}
215
ebf94940 216#endif /* wxUSE_SOCKETS */