<commit_before>/** Original implementation supporting both UNIX and TCP sockets.
 *
 * The UNIX socket implementation is based on the behaviour defined in the FastCGI specification, and also
 * includes optional support for logging via syslog, as defined in the specification.
 *
 * This implementation is *NOT* portable.
 */
#include "SocketServer.h"

#include "fastcgi.h"

#include <QtEndian>
#include <QFileSystemWatcher>
#include <QHostAddress>
#include <QSocketNotifier>
#include <QTextStream>
#include <QTimer>

#include <errno.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/ip.h>
#include <unistd.h>

namespace FastCgiQt
{
	class SocketServer::Private
	{
		public:
			/// Lock the socket with the specified socket id.
			void lockSocket(int socket);
			/// Unlock the socket with the specified socket id.
			void releaseSocket(int socket);

			/// Socket handle
			int m_socket;

			/// Type of socket
			SocketServer::SocketType m_socketType;

			/** Notifier used to watch for new connections to the
			 * FastCGI socket.
			 */
			QSocketNotifier* m_socketNotifier;
	};

	SocketServer::SocketTypes SocketServer::activeSocketTypes()
	{
		// Check we're running as a FastCGI application
		sockaddr_un sa;
		socklen_t len = sizeof(sa);
		::memset(&sa, 0, len);

		// The recommended way of telling if we're running as fastcgi or not.
		const int error = ::getpeername(FCGI_LISTENSOCK_FILENO, reinterpret_cast<sockaddr*>(&sa), &len);
		if(error == -1 && errno != ENOTCONN)
		{
			// Nope, not FastCGI over unix socket
			return SocketTypes();
		}
		return UnixSocket;
	}

	bool SocketServer::isFinished() const
	{
		return !(d->m_socketNotifier && d->m_socketNotifier->isEnabled());
	}

	void SocketServer::Private::lockSocket(int socket)
	{
		::flock(socket, LOCK_EX);
	}

	void SocketServer::Private::releaseSocket(int socket)
	{
		::flock(socket, LOCK_UN);
	}

	bool SocketServer::listen(SocketType type, quint16 parameter)
	{
		d->m_socketType = type;
		if(type == UnixSocket)
		{
			if(! (activeSocketTypes() & UnixSocket))
			{
				qWarning("Asked to run FastCGI on a UNIX socket, but not being run correctly");
				return false;
			}
			d->m_socket = FCGI_LISTENSOCK_FILENO;

			// Wait for the event loop to start up before running
			QTimer::singleShot(0, this, SIGNAL(newConnection()));
		}
		else
		{
			Q_ASSERT(type == TcpSocket);
			// SOCK_STREAM specifies TCP instead of UDP
			d->m_socket = ::socket(AF_INET, SOCK_STREAM, 0);
			const in_port_t port = static_cast<in_port_t>(parameter);
			if(port == 0)
			{
					qWarning("Configured to listen on TCP, but there isn't a valid Port Number configured. Try --configure-fastcgi");
					return false;<commit_msg>Don't trigger a redundant newConnection signal - harmless but unneccessary on Linux, breaks Solaris<commit_after>/** Original implementation supporting both UNIX and TCP sockets.
 *
 * The UNIX socket implementation is based on the behaviour defined in the FastCGI specification, and also
 * includes optional support for logging via syslog, as defined in the specification.
 *
 * This implementation is *NOT* portable.
 */
#include "SocketServer.h"

#include "fastcgi.h"

#include <QtEndian>
#include <QFileSystemWatcher>
#include <QHostAddress>
#include <QSocketNotifier>
#include <QTextStream>

#include <errno.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/ip.h>
#include <unistd.h>

namespace FastCgiQt
{
	class SocketServer::Private
	{
		public:
			/// Lock the socket with the specified socket id.
			void lockSocket(int socket);
			/// Unlock the socket with the specified socket id.
			void releaseSocket(int socket);

			/// Socket handle
			int m_socket;

			/// Type of socket
			SocketServer::SocketType m_socketType;

			/** Notifier used to watch for new connections to the
			 * FastCGI socket.
			 */
			QSocketNotifier* m_socketNotifier;
	};

	SocketServer::SocketTypes SocketServer::activeSocketTypes()
	{
		// Check we're running as a FastCGI application
		sockaddr_un sa;
		socklen_t len = sizeof(sa);
		::memset(&sa, 0, len);

		// The recommended way of telling if we're running as fastcgi or not.
		const int error = ::getpeername(FCGI_LISTENSOCK_FILENO, reinterpret_cast<sockaddr*>(&sa), &len);
		if(error == -1 && errno != ENOTCONN)
		{
			// Nope, not FastCGI over unix socket
			return SocketTypes();
		}
		return UnixSocket;
	}

	bool SocketServer::isFinished() const
	{
		return !(d->m_socketNotifier && d->m_socketNotifier->isEnabled());
	}

	void SocketServer::Private::lockSocket(int socket)
	{
		::flock(socket, LOCK_EX);
	}

	void SocketServer::Private::releaseSocket(int socket)
	{
		::flock(socket, LOCK_UN);
	}

	bool SocketServer::listen(SocketType type, quint16 parameter)
	{
		d->m_socketType = type;
		if(type == UnixSocket)
		{
			if(! (activeSocketTypes() & UnixSocket))
			{
				qWarning("Asked to run FastCGI on a UNIX socket, but not being run correctly");
				return false;
			}
			d->m_socket = FCGI_LISTENSOCK_FILENO;
		}
		else
		{
			Q_ASSERT(type == TcpSocket);
			// SOCK_STREAM specifies TCP instead of UDP
			d->m_socket = ::socket(AF_INET, SOCK_STREAM, 0);
			const in_port_t port = static_cast<in_port_t>(parameter);
			if(port == 0)
			{
					qWarning("Configured to listen on TCP, but there isn't a valid Port Number configured. Try --configure-fastcgi");
					return false;
{'fraction_non_alphanumeric': 0.11399443929564411, 'fraction_numerical': 0.0024096385542168677, 'mean_word_length': 4.00556586270872, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 42, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '365882', 'n_tokens_mistral': 1984, 'n_tokens_neox': 1744, 'n_words': 520}