@@ -1407,6 +1407,22 @@ ftp_getresp(ftpbuf_t *ftp)
14071407}
14081408/* }}} */
14091409
1410+ static ssize_t my_send_wrapper_with_restart (php_socket_t fd , const void * buf , size_t size , int flags ) {
1411+ ssize_t n ;
1412+ do {
1413+ n = send (fd , buf , size , flags );
1414+ } while (n == -1 && php_socket_errno () == EINTR );
1415+ return n ;
1416+ }
1417+
1418+ static ssize_t my_recv_wrapper_with_restart (php_socket_t fd , void * buf , size_t size , int flags ) {
1419+ ssize_t n ;
1420+ do {
1421+ n = recv (fd , buf , size , flags );
1422+ } while (n == -1 && php_socket_errno () == EINTR );
1423+ return n ;
1424+ }
1425+
14101426int single_send (ftpbuf_t * ftp , php_socket_t s , void * buf , size_t size ) {
14111427#ifdef HAVE_FTP_SSL
14121428 int err ;
@@ -1422,7 +1438,7 @@ int single_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t size) {
14221438 handle = ftp -> data -> ssl_handle ;
14231439 fd = ftp -> data -> fd ;
14241440 } else {
1425- return send (s , buf , size , 0 );
1441+ return my_send_wrapper_with_restart (s , buf , size , 0 );
14261442 }
14271443
14281444 do {
@@ -1461,8 +1477,33 @@ int single_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t size) {
14611477 } while (retry );
14621478 return sent ;
14631479#else
1464- return send (s , buf , size , 0 );
1480+ return my_send_wrapper_with_restart (s , buf , size , 0 );
1481+ #endif
1482+ }
1483+
1484+ static int my_poll (php_socket_t fd , int events , int timeout ) {
1485+ int n ;
1486+ zend_hrtime_t timeout_hr = (zend_hrtime_t ) timeout * 1000000 ;
1487+
1488+ while (true) {
1489+ zend_hrtime_t start_ns = zend_hrtime ();
1490+ n = php_pollfd_for_ms (fd , events , (int ) (timeout_hr / 1000000 ));
1491+
1492+ if (n == -1 && php_socket_errno () == EINTR ) {
1493+ zend_hrtime_t delta_ns = zend_hrtime () - start_ns ;
1494+ if (delta_ns > timeout_hr ) {
1495+ #ifndef PHP_WIN32
1496+ errno = ETIMEDOUT ;
14651497#endif
1498+ break ;
1499+ }
1500+ timeout_hr -= delta_ns ;
1501+ } else {
1502+ break ;
1503+ }
1504+ }
1505+
1506+ return n ;
14661507}
14671508
14681509/* {{{ my_send */
@@ -1474,7 +1515,7 @@ my_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len)
14741515
14751516 size = len ;
14761517 while (size ) {
1477- n = php_pollfd_for_ms (s , POLLOUT , ftp -> timeout_sec * 1000 );
1518+ n = my_poll (s , POLLOUT , ftp -> timeout_sec * 1000 );
14781519
14791520 if (n < 1 ) {
14801521 char buf [256 ];
@@ -1513,7 +1554,7 @@ my_recv(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len)
15131554 SSL * handle = NULL ;
15141555 php_socket_t fd ;
15151556#endif
1516- n = php_pollfd_for_ms (s , PHP_POLLREADABLE , ftp -> timeout_sec * 1000 );
1557+ n = my_poll (s , PHP_POLLREADABLE , ftp -> timeout_sec * 1000 );
15171558 if (n < 1 ) {
15181559 char buf [256 ];
15191560 if (n == 0 ) {
@@ -1573,7 +1614,7 @@ my_recv(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len)
15731614 } while (retry );
15741615 } else {
15751616#endif
1576- nr_bytes = recv (s , buf , len , 0 );
1617+ nr_bytes = my_recv_wrapper_with_restart (s , buf , len , 0 );
15771618#ifdef HAVE_FTP_SSL
15781619 }
15791620#endif
@@ -1587,7 +1628,7 @@ data_available(ftpbuf_t *ftp, php_socket_t s)
15871628{
15881629 int n ;
15891630
1590- n = php_pollfd_for_ms (s , PHP_POLLREADABLE , 1000 );
1631+ n = my_poll (s , PHP_POLLREADABLE , 1000 );
15911632 if (n < 1 ) {
15921633 char buf [256 ];
15931634 if (n == 0 ) {
@@ -1610,7 +1651,7 @@ data_writeable(ftpbuf_t *ftp, php_socket_t s)
16101651{
16111652 int n ;
16121653
1613- n = php_pollfd_for_ms (s , POLLOUT , 1000 );
1654+ n = my_poll (s , POLLOUT , 1000 );
16141655 if (n < 1 ) {
16151656 char buf [256 ];
16161657 if (n == 0 ) {
@@ -1634,7 +1675,7 @@ my_accept(ftpbuf_t *ftp, php_socket_t s, struct sockaddr *addr, socklen_t *addrl
16341675{
16351676 int n ;
16361677
1637- n = php_pollfd_for_ms (s , PHP_POLLREADABLE , ftp -> timeout_sec * 1000 );
1678+ n = my_poll (s , PHP_POLLREADABLE , ftp -> timeout_sec * 1000 );
16381679 if (n < 1 ) {
16391680 char buf [256 ];
16401681 if (n == 0 ) {
0 commit comments