Warning: That file was not part of the compilation database. It may have many parsing errors.

1/****************************************************************************
2**
3** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4** Contact: http://www.qt-project.org/legal
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Digia. For licensing terms and
14** conditions see http://qt.digia.com/licensing. For further information
15** use the contact form at http://qt.digia.com/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 2.1 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 2.1 requirements
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24**
25** In addition, as a special exception, Digia gives you certain additional
26** rights. These rights are described in the Digia Qt LGPL Exception
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28**
29** GNU General Public License Usage
30** Alternatively, this file may be used under the terms of the GNU
31** General Public License version 3.0 as published by the Free Software
32** Foundation and appearing in the file LICENSE.GPL included in the
33** packaging of this file. Please review the following information to
34** ensure the GNU General Public License version 3.0 requirements will be
35** met: http://www.gnu.org/copyleft/gpl.html.
36**
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qplatformdefs.h"
43#include "qwssocket_qws.h"
44
45#ifndef QT_NO_QWS_MULTIPROCESS
46
47#include <fcntl.h>
48#include <netdb.h>
49#include <errno.h>
50#include <stdio.h>
51#include <sys/file.h>
52#include <sys/time.h>
53#include <sys/un.h>
54
55#ifdef __MIPSEL__
56# ifndef SOCK_DGRAM
57# define SOCK_DGRAM 1
58# endif
59# ifndef SOCK_STREAM
60# define SOCK_STREAM 2
61# endif
62#endif
63
64#if defined(Q_OS_SOLARIS) || defined (QT_LINUXBASE)
65// uff-da apparently Solaris doesn't have the SUN_LEN macro, here is
66// an implementation of it...
67# ifndef SUN_LEN
68# define SUN_LEN(su) \
69 sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)
70# endif
71
72// nor the POSIX names of UNIX domain sockets *sigh*
73# ifndef AF_LOCAL
74# define AF_LOCAL AF_UNIX
75# endif
76# ifndef PF_LOCAL
77# define PF_LOCAL PF_UNIX
78# endif
79#endif // Q_OS_SOLARIS || QT_LINUXBASE
80
81QT_BEGIN_NAMESPACE
82
83/***********************************************************************
84 *
85 * QWSSocket
86 *
87 **********************************************************************/
88QWSSocket::QWSSocket(QObject *parent)
89 : QWS_SOCK_BASE(parent)
90{
91#ifndef QT_NO_SXE
92 QObject::connect( this, SIGNAL(stateChanged(SocketState)),
93 this, SLOT(forwardStateChange(SocketState)));
94#endif
95}
96
97QWSSocket::~QWSSocket()
98{
99}
100
101#ifndef QT_NO_SXE
102QString QWSSocket::errorString()
103{
104 switch (QUnixSocket::error()) {
105 case NoError:
106 return QString();
107 case InvalidPath:
108 case NonexistentPath:
109 return QLatin1String("Bad path"); // NO_TR
110 default:
111 return QLatin1String("Bad socket"); // NO TR
112 }
113}
114
115void QWSSocket::forwardStateChange(QUnixSocket::SocketState st )
116{
117 switch ( st )
118 {
119 case ConnectedState:
120 emit connected();
121 break;
122 case ClosingState:
123 break;
124 case UnconnectedState:
125 emit disconnected();
126 break;
127 default:
128 // nothing
129 break;
130 }
131 if ( QUnixSocket::error() != NoError )
132 emit error((QAbstractSocket::SocketError)0);
133}
134#endif
135
136bool QWSSocket::connectToLocalFile(const QString &file)
137{
138#ifndef QT_NO_SXE
139 bool result = QUnixSocket::connect( file.toLocal8Bit() );
140 if ( !result )
141 {
142 perror( "QWSSocketAuth::connectToLocalFile could not connect:" );
143 emit error(QAbstractSocket::ConnectionRefusedError);
144 return false;
145 }
146 return true;
147#else
148 // create socket
149 int s = ::socket(PF_LOCAL, SOCK_STREAM, 0);
150
151 // connect to socket
152 struct sockaddr_un a;
153 memset(&a, 0, sizeof(a));
154 a.sun_family = PF_LOCAL;
155 strncpy(a.sun_path, file.toLocal8Bit().constData(), sizeof(a.sun_path) - 1);
156 int r = ::connect(s, (struct sockaddr*)&a, SUN_LEN(&a));
157 if (r == 0) {
158 setSocketDescriptor(s);
159 } else {
160 perror("QWSSocket::connectToLocalFile could not connect:");
161 ::close(s);
162 emit error(ConnectionRefusedError);
163 return false;
164 }
165#endif
166 return true;
167}
168
169
170/***********************************************************************
171 *
172 * QWSServerSocket
173 *
174 **********************************************************************/
175QWSServerSocket::QWSServerSocket(const QString& file, QObject *parent)
176#ifndef QT_NO_SXE
177 : QUnixSocketServer(parent)
178#else
179 : QTcpServer(parent)
180#endif
181{
182 init(file);
183}
184
185void QWSServerSocket::init(const QString &file)
186{
187#ifndef QT_NO_SXE
188 QByteArray fn = file.toLocal8Bit();
189 bool result = QUnixSocketServer::listen( fn );
190 if ( !result )
191 {
192 QUnixSocketServer::ServerError err = serverError();
193 switch ( err )
194 {
195 case InvalidPath:
196 qWarning("QWSServerSocket:: invalid path %s", qPrintable(file));
197 break;
198 case ResourceError:
199 case BindError:
200 case ListenError:
201 qWarning("QWSServerSocket:: could not listen on path %s", qPrintable(file));
202 break;
203 default:
204 break;
205 }
206 }
207#else
208 int backlog = 16; //#####
209
210// create socket
211 int s = ::socket(PF_LOCAL, SOCK_STREAM, 0);
212 if (s == -1) {
213 perror("QWSServerSocket::init");
214 qWarning("QWSServerSocket: unable to create socket.");
215 return;
216 }
217
218 QByteArray fn = file.toLocal8Bit();
219 unlink(fn.constData()); // doesn't have to succeed
220
221 // bind socket
222 struct sockaddr_un a;
223 memset(&a, 0, sizeof(a));
224 a.sun_family = PF_LOCAL;
225 strncpy(a.sun_path, fn.constData(), sizeof(a.sun_path) - 1);
226 int r = ::bind(s, (struct sockaddr*)&a, SUN_LEN(&a));
227 if (r < 0) {
228 perror("QWSServerSocket::init");
229 qWarning("QWSServerSocket: could not bind to file %s", fn.constData());
230 ::close(s);
231 return;
232 }
233
234 if (chmod(fn.constData(), 0600) < 0) {
235 perror("QWSServerSocket::init");
236 qWarning("Could not set permissions of %s", fn.constData());
237 ::close(s);
238 return;
239 }
240
241 // listen
242 if (::listen(s, backlog) == 0) {
243 if (!setSocketDescriptor(s))
244 qWarning( "QWSServerSocket could not set descriptor %d : %s", s, errorString().toLatin1().constData());
245 } else {
246 perror("QWSServerSocket::init");
247 qWarning("QWSServerSocket: could not listen to file %s", fn.constData());
248 ::close(s);
249 }
250#endif
251}
252
253QWSServerSocket::~QWSServerSocket()
254{
255}
256
257#ifndef QT_NO_SXE
258
259void QWSServerSocket::incomingConnection(int socketDescriptor)
260{
261 inboundConnections.append( socketDescriptor );
262 emit newConnection();
263}
264
265
266QWSSocket *QWSServerSocket::nextPendingConnection()
267{
268 QMutexLocker locker( &ssmx );
269 if ( inboundConnections.count() == 0 )
270 return 0;
271 QWSSocket *s = new QWSSocket();
272 s->setSocketDescriptor( inboundConnections.takeFirst() );
273 return s;
274}
275
276#endif // QT_NO_SXE
277
278QT_END_NAMESPACE
279
280#endif //QT_NO_QWS_MULTIPROCESS
281

Warning: That file was not part of the compilation database. It may have many parsing errors.