• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

sineflow / clamav / 22585077326

02 Mar 2026 04:22PM UTC coverage: 95.455% (+19.3%) from 76.106%
22585077326

Pull #14

github

pmishev
More tests
Pull Request #14: 2.0.0

69 of 75 new or added lines in 11 files covered. (92.0%)

126 of 132 relevant lines covered (95.45%)

69.75 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.78
/src/Socket/Socket.php
1
<?php
2

3
namespace Sineflow\ClamAV\Socket;
4

5
use Sineflow\ClamAV\Exception\SocketException;
6

7
class Socket
8
{
9
    public const UNIX = \AF_UNIX;
10
    public const NETWORK = \AF_INET;
11

12
    private const MAX_READ_BYTES = 8192;
13

14
    private ?\Socket $socket = null;
15

16
    public function __construct(
216✔
17
        private readonly int $socketType,
18
        private readonly array $connectionArguments,
19
        private readonly ?int $timeoutSeconds = null,
20
    ) {
21
    }
216✔
22

23
    public function sendCommand(string $dataIn, int $flagsSend = 0, int $flagsReceive = MSG_WAITALL): string
153✔
24
    {
25
        $this->connect();
153✔
26

27
        if (false === socket_send($this->socket, $dataIn, strlen($dataIn), $flagsSend)) {
153✔
NEW
28
            $this->closeAndThrow('Writing to socket failed');
×
29
        }
30
        $dataOut = '';
153✔
31

32
        do {
33
            $bytes = socket_recv($this->socket, $chunk, self::MAX_READ_BYTES, $flagsReceive);
153✔
34
            if (false === $bytes) {
153✔
35
                $this->closeAndThrow('Reading from socket failed');
9✔
36
            }
37
            $dataOut .= $chunk;
144✔
38
        } while ($bytes);
144✔
39
        socket_close($this->socket);
144✔
40
        $this->socket = null;
144✔
41

42
        return $dataOut;
144✔
43
    }
44

45
    /**
46
     * @throws SocketException
47
     */
48
    private function connect(): void
153✔
49
    {
50
        if ($this->socket instanceof \Socket) {
153✔
NEW
51
            return;
×
52
        }
53

54
        $socket = @ socket_create($this->socketType, SOCK_STREAM, 0);
153✔
55
        if ($socket === false) {
153✔
NEW
56
            $this->closeAndThrow('Creating socket failed');
×
57
        }
58
        $this->socket = $socket;
153✔
59

60
        $success = @ socket_connect($this->socket, ...$this->connectionArguments);
153✔
61
        if ($success === false) {
153✔
NEW
62
            $this->closeAndThrow('Connecting to socket failed');
×
63
        }
64

65
        if ($this->timeoutSeconds !== null) {
153✔
66
            $timeout = ['sec' => $this->timeoutSeconds, 'usec' => 0];
9✔
67
            if (false === socket_set_option($this->socket, SOL_SOCKET, SO_SNDTIMEO, $timeout)) {
9✔
NEW
68
                $this->closeAndThrow('Setting socket send timeout failed');
×
69
            }
70
            if (false === socket_set_option($this->socket, SOL_SOCKET, SO_RCVTIMEO, $timeout)) {
9✔
NEW
71
                $this->closeAndThrow('Setting socket receive timeout failed');
×
72
            }
73
        }
74
    }
75

76
    private function closeAndThrow(string $message): never
9✔
77
    {
78
        $errorCode = socket_last_error($this->socket);
9✔
79
        if (null !== $this->socket) {
9✔
80
            socket_close($this->socket);
9✔
81
            $this->socket = null;
9✔
82
        }
83
        throw new SocketException($message, $errorCode);
9✔
84
    }
85
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc