@@ -1387,6 +1387,22 @@ ftp_getresp(ftpbuf_t *ftp)
13871387}
13881388/* }}} */
13891389
1390+ static ssize_t my_send_wrapper_with_restart (php_socket_t fd , const void * buf , size_t size , int flags ) {
1391+ ssize_t n ;
1392+ do {
1393+ n = send (fd , buf , size , flags );
1394+ } while (n == -1 && php_socket_errno () == EINTR );
1395+ return n ;
1396+ }
1397+
1398+ static ssize_t my_recv_wrapper_with_restart (php_socket_t fd , void * buf , size_t size , int flags ) {
1399+ ssize_t n ;
1400+ do {
1401+ n = recv (fd , buf , size , flags );
1402+ } while (n == -1 && php_socket_errno () == EINTR );
1403+ return n ;
1404+ }
1405+
13901406int single_send (ftpbuf_t * ftp , php_socket_t s , void * buf , size_t size ) {
13911407#ifdef HAVE_FTP_SSL
13921408 int err ;
@@ -1402,7 +1418,7 @@ int single_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t size) {
14021418 handle = ftp -> data -> ssl_handle ;
14031419 fd = ftp -> data -> fd ;
14041420 } else {
1405- return send (s , buf , size , 0 );
1421+ return my_send_wrapper_with_restart (s , buf , size , 0 );
14061422 }
14071423
14081424 do {
@@ -1441,8 +1457,33 @@ int single_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t size) {
14411457 } while (retry );
14421458 return sent ;
14431459#else
1444- return send (s , buf , size , 0 );
1460+ return my_send_wrapper_with_restart (s , buf , size , 0 );
1461+ #endif
1462+ }
1463+
1464+ static int my_poll (php_socket_t fd , int events , int timeout ) {
1465+ int n ;
1466+ zend_hrtime_t timeout_hr = (zend_hrtime_t ) timeout * 1000000 ;
1467+
1468+ while (true) {
1469+ zend_hrtime_t start_ns = zend_hrtime ();
1470+ n = php_pollfd_for_ms (fd , events , (int ) (timeout_hr / 1000000 ));
1471+
1472+ if (n == -1 && php_socket_errno () == EINTR ) {
1473+ zend_hrtime_t delta_ns = zend_hrtime () - start_ns ;
1474+ if (delta_ns > timeout_hr ) {
1475+ #ifndef PHP_WIN32
1476+ errno = ETIMEDOUT ;
14451477#endif
1478+ break ;
1479+ }
1480+ timeout_hr -= delta_ns ;
1481+ } else {
1482+ break ;
1483+ }
1484+ }
1485+
1486+ return n ;
14461487}
14471488
14481489/* {{{ my_send */
@@ -1454,7 +1495,7 @@ my_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len)
14541495
14551496 size = len ;
14561497 while (size ) {
1457- n = php_pollfd_for_ms (s , POLLOUT , ftp -> timeout_sec * 1000 );
1498+ n = my_poll (s , POLLOUT , ftp -> timeout_sec * 1000 );
14581499
14591500 if (n < 1 ) {
14601501 char buf [256 ];
@@ -1493,7 +1534,7 @@ my_recv(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len)
14931534 SSL * handle = NULL ;
14941535 php_socket_t fd ;
14951536#endif
1496- n = php_pollfd_for_ms (s , PHP_POLLREADABLE , ftp -> timeout_sec * 1000 );
1537+ n = my_poll (s , PHP_POLLREADABLE , ftp -> timeout_sec * 1000 );
14971538 if (n < 1 ) {
14981539 char buf [256 ];
14991540 if (n == 0 ) {
@@ -1553,7 +1594,7 @@ my_recv(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len)
15531594 } while (retry );
15541595 } else {
15551596#endif
1556- nr_bytes = recv (s , buf , len , 0 );
1597+ nr_bytes = my_recv_wrapper_with_restart (s , buf , len , 0 );
15571598#ifdef HAVE_FTP_SSL
15581599 }
15591600#endif
@@ -1567,7 +1608,7 @@ data_available(ftpbuf_t *ftp, php_socket_t s)
15671608{
15681609 int n ;
15691610
1570- n = php_pollfd_for_ms (s , PHP_POLLREADABLE , 1000 );
1611+ n = my_poll (s , PHP_POLLREADABLE , 1000 );
15711612 if (n < 1 ) {
15721613 char buf [256 ];
15731614 if (n == 0 ) {
@@ -1590,7 +1631,7 @@ data_writeable(ftpbuf_t *ftp, php_socket_t s)
15901631{
15911632 int n ;
15921633
1593- n = php_pollfd_for_ms (s , POLLOUT , 1000 );
1634+ n = my_poll (s , POLLOUT , 1000 );
15941635 if (n < 1 ) {
15951636 char buf [256 ];
15961637 if (n == 0 ) {
@@ -1614,7 +1655,7 @@ my_accept(ftpbuf_t *ftp, php_socket_t s, struct sockaddr *addr, socklen_t *addrl
16141655{
16151656 int n ;
16161657
1617- n = php_pollfd_for_ms (s , PHP_POLLREADABLE , ftp -> timeout_sec * 1000 );
1658+ n = my_poll (s , PHP_POLLREADABLE , ftp -> timeout_sec * 1000 );
16181659 if (n < 1 ) {
16191660 char buf [256 ];
16201661 if (n == 0 ) {
0 commit comments