/[svn]/liblscp/trunk/src/socket.c
ViewVC logotype

Annotation of /liblscp/trunk/src/socket.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3866 - (hide annotations) (download)
Sat Mar 27 12:17:51 2021 UTC (3 years ago) by capela
File MIME type: text/plain
File size: 8081 byte(s)
* Switching to CMake build system as for packaging default.
1 capela 78 // socket.c
2     //
3     /****************************************************************************
4     liblscp - LinuxSampler Control Protocol API
5 capela 3866 Copyright (C) 2004-2021, rncbc aka Rui Nuno Capela. All rights reserved.
6 capela 78
7     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Lesser General Public
9     License as published by the Free Software Foundation; either
10     version 2.1 of the License, or (at your option) any later version.
11    
12     This library is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15     Lesser General Public License for more details.
16    
17 capela 921 You should have received a copy of the GNU General Public License along
18     with this program; if not, write to the Free Software Foundation, Inc.,
19     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 capela 78
21     *****************************************************************************/
22    
23     #include "lscp/socket.h"
24    
25    
26     //-------------------------------------------------------------------------
27     // Socket info debugging.
28    
29     #if defined(WIN32)
30    
31     static struct {
32    
33 capela 952 int iError;
34     const char *pszError;
35    
36 capela 78 } _wsaErrorCodes[] = {
37    
38 capela 952 { 0, "No error" },
39     { WSAEINTR, "Interrupted system call" },
40     { WSAEBADF, "Bad file number" },
41     { WSAEACCES, "Permission denied" },
42     { WSAEFAULT, "Bad address" },
43     { WSAEINVAL, "Invalid argument" },
44     { WSAEMFILE, "Too many open sockets" },
45     { WSAEWOULDBLOCK, "Operation would block" },
46     { WSAEINPROGRESS, "Operation now in progress" },
47     { WSAEALREADY, "Operation already in progress" },
48     { WSAENOTSOCK, "Socket operation on non-socket" },
49     { WSAEDESTADDRREQ, "Destination address required" },
50     { WSAEMSGSIZE, "Message too long" },
51     { WSAEPROTOTYPE, "Protocol wrong type for socket" },
52     { WSAENOPROTOOPT, "Bad protocol option" },
53     { WSAEPROTONOSUPPORT, "Protocol not supported" },
54     { WSAESOCKTNOSUPPORT, "Socket type not supported" },
55     { WSAEOPNOTSUPP, "Operation not supported on socket" },
56     { WSAEPFNOSUPPORT, "Protocol family not supported" },
57     { WSAEAFNOSUPPORT, "Address family not supported" },
58     { WSAEADDRINUSE, "Address already in use" },
59     { WSAEADDRNOTAVAIL, "Can't assign requested address" },
60     { WSAENETDOWN, "Network is down" },
61     { WSAENETUNREACH, "Network is unreachable" },
62     { WSAENETRESET, "Net connection reset" },
63     { WSAECONNABORTED, "Software caused connection abort" },
64     { WSAECONNRESET, "Connection reset by peer" },
65     { WSAENOBUFS, "No buffer space available" },
66     { WSAEISCONN, "Socket is already connected" },
67     { WSAENOTCONN, "Socket is not connected" },
68     { WSAESHUTDOWN, "Can't send after socket shutdown" },
69     { WSAETOOMANYREFS, "Too many references, can't splice" },
70     { WSAETIMEDOUT, "Connection timed out" },
71     { WSAECONNREFUSED, "Connection refused" },
72     { WSAELOOP, "Too many levels of symbolic links" },
73     { WSAENAMETOOLONG, "File name too long" },
74     { WSAEHOSTDOWN, "Host is down" },
75     { WSAEHOSTUNREACH, "No route to host" },
76     { WSAENOTEMPTY, "Directory not empty" },
77     { WSAEPROCLIM, "Too many processes" },
78     { WSAEUSERS, "Too many users" },
79     { WSAEDQUOT, "Disc quota exceeded" },
80     { WSAESTALE, "Stale NFS file handle" },
81     { WSAEREMOTE, "Too many levels of remote in path" },
82     { WSASYSNOTREADY, "Network system is unavailable" },
83     { WSAVERNOTSUPPORTED, "Winsock version out of range" },
84     { WSANOTINITIALISED, "WSAStartup not yet called" },
85     { WSAEDISCON, "Graceful shutdown in progress" },
86     { WSAHOST_NOT_FOUND, "Host not found" },
87     { WSANO_DATA, "No host data of that type was found" },
88     { 0, NULL }
89 capela 78 };
90    
91     void lscp_socket_perror ( const char *pszPrefix )
92     {
93 capela 952 int iError = WSAGetLastError();
94     const char *pszError = "Unknown error code";
95     int i;
96 capela 78
97 capela 952 for (i = 0; _wsaErrorCodes[i].pszError; i++) {
98     if (_wsaErrorCodes[i].iError == iError) {
99     pszError = _wsaErrorCodes[i].pszError;
100     break;
101     }
102     }
103    
104     fprintf(stderr, "%s: %s (%d)\n", pszPrefix, pszError, iError);
105 capela 78 }
106    
107 capela 114 void lscp_socket_herror ( const char *pszPrefix )
108     {
109 capela 952 lscp_socket_perror(pszPrefix);
110 capela 114 }
111    
112 capela 78 #else
113    
114     void lscp_socket_perror ( const char *pszPrefix )
115     {
116 capela 952 perror(pszPrefix);
117 capela 78 }
118    
119 capela 114 void lscp_socket_herror ( const char *pszPrefix )
120     {
121 capela 952 herror(pszPrefix);
122 capela 114 }
123    
124 capela 78 #endif
125    
126    
127     static void _lscp_socket_getopt_bool ( lscp_socket_t sock, const char *pszOptName, int iOptName )
128     {
129 capela 952 int iSockOpt;
130     socklen_t cSockLen = sizeof(int);
131     char szPrefix[33];
132 capela 78
133 capela 952 sprintf(szPrefix, " %s\t", pszOptName);
134     if (getsockopt(sock, SOL_SOCKET, iOptName, (char *) &iSockOpt, &cSockLen) == SOCKET_ERROR)
135     lscp_socket_perror(szPrefix);
136     else
137     fprintf(stderr, "%s: %s\n", szPrefix, (iSockOpt ? "ON" : "OFF"));
138 capela 78 }
139    
140     static void _lscp_socket_getopt_int ( lscp_socket_t sock, const char *pszOptName, int iOptName )
141     {
142 capela 952 int iSockOpt;
143     socklen_t cSockLen = sizeof(int);
144     char szPrefix[33];
145 capela 78
146 capela 952 sprintf(szPrefix, " %s\t", pszOptName);
147     if (getsockopt(sock, SOL_SOCKET, iOptName, (char *) &iSockOpt, &cSockLen) == SOCKET_ERROR)
148     lscp_socket_perror(szPrefix);
149     else
150     fprintf(stderr, "%s: %d\n", szPrefix, iSockOpt);
151 capela 78 }
152    
153     void lscp_socket_getopts ( const char *pszPrefix, lscp_socket_t sock )
154     {
155 capela 952 fprintf(stderr, "%s: sock=%d:\n", pszPrefix, sock);
156    
157     _lscp_socket_getopt_bool(sock, "SO_BROADCAST", SO_BROADCAST);
158     _lscp_socket_getopt_bool(sock, "SO_DEBUG", SO_DEBUG);
159 capela 78 #if defined(WIN32)
160 capela 952 _lscp_socket_getopt_bool(sock, "SO_DONTLINGER", SO_DONTLINGER);
161 capela 78 #endif
162 capela 952 _lscp_socket_getopt_bool(sock, "SO_DONTROUTE", SO_DONTROUTE);
163     _lscp_socket_getopt_bool(sock, "SO_KEEPALIVE", SO_KEEPALIVE);
164     _lscp_socket_getopt_bool(sock, "SO_OOBINLINE", SO_OOBINLINE);
165     _lscp_socket_getopt_int (sock, "SO_RCVBUF", SO_RCVBUF);
166     _lscp_socket_getopt_bool(sock, "SO_REUSEADDR", SO_REUSEADDR);
167     _lscp_socket_getopt_int (sock, "SO_SNDBUF", SO_SNDBUF);
168 capela 78 }
169    
170     void lscp_socket_trace ( const char *pszPrefix, struct sockaddr_in *pAddr, const char *pchBuffer, int cchBuffer )
171     {
172 capela 952 char *pszBuffer;
173 capela 78
174 capela 952 fprintf(stderr, "%s: addr=%s port=%d:\n",
175     pszPrefix,
176     inet_ntoa(pAddr->sin_addr),
177     htons(pAddr->sin_port)
178     );
179    
180     if (pchBuffer && cchBuffer > 0) {
181     pszBuffer = (char *) malloc(cchBuffer + 1);
182     if (pszBuffer) {
183     memcpy(pszBuffer, pchBuffer, cchBuffer);
184     while (cchBuffer > 0 && (pszBuffer[cchBuffer - 1] == '\n' || pszBuffer[cchBuffer- 1] == '\r'))
185     cchBuffer--;
186     pszBuffer[cchBuffer] = (char) 0;
187     fprintf(stderr, "< %s\n", pszBuffer);
188     free(pszBuffer);
189     }
190     }
191     else fprintf(stderr, "< (null)\n");
192 capela 78 }
193    
194    
195     //-------------------------------------------------------------------------
196     // Threaded socket agent struct helpers.
197    
198     void lscp_socket_agent_init ( lscp_socket_agent_t *pAgent, lscp_socket_t sock, struct sockaddr_in *pAddr, int cAddr )
199     {
200 capela 952 memset(pAgent, 0, sizeof(lscp_socket_agent_t));
201 capela 78
202 capela 952 pAgent->sock = sock;
203     pAgent->pThread = NULL;
204     pAgent->iState = 0;
205 capela 144
206 capela 952 if (pAddr)
207     memmove((char *) &(pAgent->addr), pAddr, cAddr);
208 capela 78 }
209    
210    
211     lscp_status_t lscp_socket_agent_start ( lscp_socket_agent_t *pAgent, lscp_thread_proc_t pfnProc, void *pvData, int iDetach )
212     {
213 capela 952 if (pAgent->iState)
214     pAgent->iState = 0;
215     if (pAgent->pThread)
216     lscp_thread_destroy(pAgent->pThread);
217 capela 78
218 capela 952 pAgent->iState = 1;
219     pAgent->pThread = lscp_thread_create(pfnProc, pvData, iDetach);
220 capela 78
221 capela 952 return (pAgent->pThread == NULL ? LSCP_FAILED : LSCP_OK);
222 capela 78 }
223    
224    
225     lscp_status_t lscp_socket_agent_join ( lscp_socket_agent_t *pAgent )
226     {
227 capela 952 lscp_status_t ret = LSCP_FAILED;
228 capela 78
229 capela 952 if (pAgent->pThread)
230     ret = lscp_thread_join(pAgent->pThread);
231 capela 78
232 capela 952 return ret;
233 capela 78 }
234    
235    
236     lscp_status_t lscp_socket_agent_free ( lscp_socket_agent_t *pAgent )
237     {
238 capela 952 lscp_status_t ret = LSCP_FAILED;
239 capela 78
240 capela 952 if (pAgent->iState)
241     pAgent->iState = 0;
242 capela 178
243 capela 952 if (pAgent->sock != INVALID_SOCKET)
244     closesocket(pAgent->sock);
245     pAgent->sock = INVALID_SOCKET;
246 capela 78
247 capela 952 if (pAgent->pThread)
248     ret = lscp_thread_destroy(pAgent->pThread);
249     pAgent->pThread = NULL;
250 capela 78
251 capela 952 return ret;
252 capela 78 }
253    
254    
255     // end of socket.c

  ViewVC Help
Powered by ViewVC