File indexing completed on 2024-06-02 05:05:38

0001 /*
0002     SPDX-FileCopyrightText: 2009 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "pipe.h"
0008 
0009 #include "net/socket.h"
0010 #include <fcntl.h>
0011 #include <sys/socket.h>
0012 #include <sys/types.h>
0013 #include <unistd.h>
0014 #include <util/functions.h>
0015 #include <util/log.h>
0016 
0017 namespace bt
0018 {
0019 #ifdef Q_WS_WIN
0020 int socketpair(int sockets[2])
0021 {
0022     sockets[0] = sockets[1] = -1;
0023 
0024     net::Socket sock(true, 4);
0025     if (!sock.bind("127.0.0.1", 0, true))
0026         return -1;
0027 
0028     net::Address local_addr = sock.getSockName();
0029     net::Socket writer(true, 4);
0030     writer.setBlocking(false);
0031     writer.connectTo(local_addr);
0032 
0033     net::Address dummy;
0034     sockets[1] = sock.accept(dummy);
0035     if (sockets[1] < 0)
0036         return -1;
0037 
0038     if (!writer.connectSuccesFull()) {
0039         closesocket(sockets[1]);
0040         return -1;
0041     }
0042 
0043     sockets[0] = writer.take();
0044     Out(SYS_GEN | LOG_DEBUG) << "Created wakeup pipe" << endl;
0045     return 0;
0046 }
0047 #endif
0048 
0049 Pipe::Pipe()
0050     : reader(-1)
0051     , writer(-1)
0052 {
0053     int sockets[2];
0054 #ifndef Q_WS_WIN
0055     if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == 0) {
0056         reader = sockets[1];
0057         writer = sockets[0];
0058         fcntl(writer, F_SETFL, O_NONBLOCK);
0059         fcntl(reader, F_SETFL, O_NONBLOCK);
0060     }
0061 #else
0062     if (socketpair(sockets) == 0) {
0063         reader = sockets[1];
0064         writer = sockets[0];
0065     }
0066 #endif
0067     else {
0068         Out(SYS_GEN | LOG_DEBUG) << "Cannot create wakeup pipe" << endl;
0069     }
0070 }
0071 
0072 Pipe::~Pipe()
0073 {
0074 #ifndef Q_WS_WIN
0075     ::close(reader);
0076     ::close(writer);
0077 #else
0078     ::closesocket(reader);
0079     ::closesocket(writer);
0080 #endif
0081 }
0082 
0083 int Pipe::read(Uint8 *buffer, int max_len)
0084 {
0085 #ifndef Q_WS_WIN
0086     return ::read(reader, buffer, max_len);
0087 #else
0088     return ::recv(reader, (char *)buffer, max_len, 0);
0089 #endif
0090 }
0091 
0092 int Pipe::write(const bt::Uint8 *data, int len)
0093 {
0094 #ifndef Q_WS_WIN
0095     return ::write(writer, data, len);
0096 #else
0097     return ::send(writer, (char *)data, len, 0);
0098 #endif
0099 }
0100 
0101 }