1
0
mirror of https://github.com/danog/ipc.git synced 2024-11-30 04:29:09 +01:00
ipc/lib/functions.php

96 lines
2.8 KiB
PHP
Raw Permalink Normal View History

2020-02-14 20:31:11 +01:00
<?php
namespace Amp\Ipc;
use Amp\Ipc\Sync\ChannelledSocket;
use Amp\Promise;
use function Amp\call;
2020-07-17 14:37:37 +02:00
/**
* Create IPC server.
*
* @param string $uri Local endpoint on which to listen for requests
*
* @return IpcServer
*/
function listen(string $uri): IpcServer
{
return new IpcServer($uri);
}
2020-09-24 21:00:49 +02:00
2020-02-14 20:31:11 +01:00
/**
* Connect to IPC server.
*
* @param string $uri URI
*
* @return Promise<ChannelledSocket>
*/
function connect(string $uri): Promise
{
return call(static function () use ($uri) {
2020-03-05 21:16:53 +01:00
if (!\file_exists($uri)) {
2020-03-05 21:12:35 +01:00
throw new \RuntimeException("The endpoint does not exist!");
}
2020-03-05 21:16:53 +01:00
2020-02-14 20:31:11 +01:00
$type = \filetype($uri);
2020-03-05 21:12:35 +01:00
if ($type !== 'fifo') {
if ($type === 'file') {
$uri = \file_get_contents($uri);
} else {
$uri = "unix://$uri";
2020-02-14 20:31:11 +01:00
}
2020-03-05 21:12:35 +01:00
if (!$socket = \stream_socket_client($uri, $errno, $errstr, 5, \STREAM_CLIENT_CONNECT)) {
$message = "Could not connect to IPC socket";
if ($error = \error_get_last()) {
$message .= \sprintf(" Errno: %d; %s", $error["type"], $error["message"]);
}
throw new \RuntimeException($message);
}
return new ChannelledSocket($socket, $socket);
}
2020-02-14 20:31:11 +01:00
2020-03-05 21:12:35 +01:00
$suffix = \bin2hex(\random_bytes(10));
$prefix = \sys_get_temp_dir()."/amp-".$suffix.".fifo";
if (\strlen($prefix) > 0xFFFF) {
throw new \RuntimeException('Prefix is too long!');
}
$sockets = [
2021-05-06 22:01:25 +02:00
$prefix."2",
$prefix."1",
];
2020-02-14 20:31:11 +01:00
2020-03-05 21:12:35 +01:00
foreach ($sockets as $k => &$socket) {
if (!\posix_mkfifo($socket, 0777)) {
throw new \RuntimeException('Could not create FIFO client socket!');
2020-02-14 20:31:11 +01:00
}
2020-03-05 21:12:35 +01:00
\register_shutdown_function(static function () use ($socket): void {
@\unlink($socket);
});
2020-02-14 20:31:11 +01:00
2020-03-05 21:12:35 +01:00
if (!$socket = \fopen($socket, 'r+')) { // Open in r+w mode to prevent blocking if there is no reader
throw new \RuntimeException("Could not open FIFO client socket");
2020-02-14 20:31:11 +01:00
}
}
2020-03-05 21:12:35 +01:00
if (!$tempSocket = \fopen($uri, 'r+')) { // Open in r+w mode to prevent blocking if there is no reader
throw new \RuntimeException("Could not connect to FIFO server");
2020-02-14 20:31:11 +01:00
}
2020-03-05 21:12:35 +01:00
\stream_set_blocking($tempSocket, false);
\stream_set_write_buffer($tempSocket, 0);
if (!\fwrite($tempSocket, \pack('v', \strlen($prefix)).$prefix)) {
2021-05-06 22:01:25 +02:00
\fclose($tempSocket);
$tempSocket = null;
2020-03-05 21:12:35 +01:00
throw new \RuntimeException("Failure sending request to FIFO server");
2020-02-14 20:31:11 +01:00
}
2020-03-05 21:12:35 +01:00
\fclose($tempSocket);
$tempSocket = null;
return new ChannelledSocket(...$sockets);
2020-02-14 20:31:11 +01:00
});
}