@@ -54,7 +54,7 @@ public function __construct($uri, array $context = array(), LoopInterface $loop
5454 if (preg_match ('#^(?:\w+://)?\d+$# ' , $ uri )) {
5555 throw new \InvalidArgumentException (
5656 'Invalid URI given (EINVAL) ' ,
57- \defined ('SOCKET_EINVAL ' ) ? \SOCKET_EINVAL : 22
57+ \defined ('SOCKET_EINVAL ' ) ? \SOCKET_EINVAL : ( \defined ( ' PCNTL_EINVAL ' ) ? \ PCNTL_EINVAL : 22 )
5858 );
5959 }
6060
@@ -135,25 +135,42 @@ public static function accept($socket)
135135 * The errno and errstr values describes the type of error that has been
136136 * encountered. This method tries to look up the given errstr and find a
137137 * matching errno value which can be useful to provide more context to error
138- * messages. It goes through the list of known errno constants when
139- * ext-sockets is available to find an errno matching the given errstr.
138+ * messages. It goes through the list of known errno constants when either
139+ * `ext-sockets`, `ext-posix` or `ext-pcntl` is available to find an errno
140+ * matching the given errstr.
140141 *
141142 * @param string $errstr
142143 * @return int errno value (e.g. value of `SOCKET_ECONNREFUSED`) or 0 if not found
143144 * @internal
144- * @copyright Copyright (c) 2018 Christian Lück, taken from https://github.com/clue/errno with permission
145+ * @copyright Copyright (c) 2023 Christian Lück, taken from https://github.com/clue/errno with permission
145146 * @codeCoverageIgnore
146147 */
147148 public static function errno ($ errstr )
148149 {
149- if (\function_exists ('socket_strerror ' )) {
150+ // PHP defines the required `strerror()` function through either `ext-sockets`, `ext-posix` or `ext-pcntl`
151+ $ strerror = \function_exists ('socket_strerror ' ) ? 'socket_strerror ' : (\function_exists ('posix_strerror ' ) ? 'posix_strerror ' : (\function_exists ('pcntl_strerror ' ) ? 'pcntl_strerror ' : null ));
152+ if ($ strerror !== null ) {
153+ assert (\is_string ($ strerror ) && \is_callable ($ strerror ));
154+
155+ // PHP defines most useful errno constants like `ECONNREFUSED` through constants in `ext-sockets` like `SOCKET_ECONNREFUSED`
156+ // PHP also defines a hand full of errno constants like `EMFILE` through constants in `ext-pcntl` like `PCNTL_EMFILE`
157+ // go through list of all defined constants like `SOCKET_E*` and `PCNTL_E*` and see if they match the given `$errstr`
150158 foreach (\get_defined_constants (false ) as $ name => $ value ) {
151- if (\strpos ($ name , 'SOCKET_E ' ) === 0 && \socket_strerror ($ value ) === $ errstr ) {
159+ if (\is_int ( $ value ) && ( \ strpos ($ name , 'SOCKET_E ' ) === 0 || \strpos ( $ name , ' PCNTL_E ' ) === 0 ) && $ strerror ($ value ) === $ errstr ) {
152160 return $ value ;
153161 }
154162 }
163+
164+ // if we reach this, no matching errno constant could be found (unlikely when `ext-sockets` is available)
165+ // go through list of all possible errno values from 1 to `MAX_ERRNO` and see if they match the given `$errstr`
166+ for ($ errno = 1 , $ max = \defined ('MAX_ERRNO ' ) ? \MAX_ERRNO : 4095 ; $ errno <= $ max ; ++$ errno ) {
167+ if ($ strerror ($ errno ) === $ errstr ) {
168+ return $ errno ;
169+ }
170+ }
155171 }
156172
173+ // if we reach this, no matching errno value could be found (unlikely when either `ext-sockets`, `ext-posix` or `ext-pcntl` is available)
157174 return 0 ;
158175 }
159176
@@ -164,8 +181,8 @@ public static function errno($errstr)
164181 * This method tries to look up the given errno value and find a matching
165182 * errno constant name which can be useful to provide more context and more
166183 * descriptive error messages. It goes through the list of known errno
167- * constants when ext-sockets is available to find the matching errno
168- * constant name.
184+ * constants when either ` ext-sockets` or `ext-pcntl` is available to find
185+ * the matching errno constant name.
169186 *
170187 * Because this method is used to append more context to error messages, the
171188 * constant name will be prefixed with a space and put between parenthesis
@@ -174,19 +191,21 @@ public static function errno($errstr)
174191 * @param int $errno
175192 * @return string e.g. ` (ECONNREFUSED)` or empty string if no matching const for the given errno could be found
176193 * @internal
177- * @copyright Copyright (c) 2018 Christian Lück, taken from https://github.com/clue/errno with permission
194+ * @copyright Copyright (c) 2023 Christian Lück, taken from https://github.com/clue/errno with permission
178195 * @codeCoverageIgnore
179196 */
180197 public static function errconst ($ errno )
181198 {
182- if (\function_exists ('socket_strerror ' )) {
183- foreach (\get_defined_constants (false ) as $ name => $ value ) {
184- if ($ value === $ errno && \strpos ($ name , 'SOCKET_E ' ) === 0 ) {
185- return ' ( ' . \substr ($ name , 7 ) . ') ' ;
186- }
199+ // PHP defines most useful errno constants like `ECONNREFUSED` through constants in `ext-sockets` like `SOCKET_ECONNREFUSED`
200+ // PHP also defines a hand full of errno constants like `EMFILE` through constants in `ext-pcntl` like `PCNTL_EMFILE`
201+ // go through list of all defined constants like `SOCKET_E*` and `PCNTL_E*` and see if they match the given `$errno`
202+ foreach (\get_defined_constants (false ) as $ name => $ value ) {
203+ if ($ value === $ errno && (\strpos ($ name , 'SOCKET_E ' ) === 0 || \strpos ($ name , 'PCNTL_E ' ) === 0 )) {
204+ return ' ( ' . \substr ($ name , \strpos ($ name , '_ ' ) + 1 ) . ') ' ;
187205 }
188206 }
189207
208+ // if we reach this, no matching errno constant could be found (unlikely when `ext-sockets` is available)
190209 return '' ;
191210 }
192211}
0 commit comments