| 
        php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
  [2009-01-22 18:13 UTC] fmassei at gmail dot com
 Description:
------------
gethostbyname() is not interruptible by signals. If it cannot resolve an hostname there is no way it can be interrupted except for a SIGKILL.
Reproduce code:
---------------
declare(ticks=1);
function al($sig)
{
    echo $sig;
    exit(0);
}
pcntl_signal(SIGINT, "al");
pcntl_signal(SIGTERM, "al");
pcntl_signal(SIGALRM, "al");
pcntl_alarm(3);
echo gethostbyname("google.com");
Expected result:
----------------
I was expected to interrupt gethostbyname() with any signal.
Actual result:
--------------
When running the above code, if the system cannot resolve google's hostname, the function blocks and doesn't respond to any signal.
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits             
             | 
    |||||||||||||||||||||||||||||||||||||
            
                 
                Copyright © 2001-2025 The PHP GroupAll rights reserved.  | 
        Last updated: Tue Nov 04 10:00:02 2025 UTC | 
Quick and dirty workaround: create a child process for resolving the hostname and let the parent manage the signals. <?php /* signal handling */ declare(ticks=1); function sa($signo) { global $pid; echo "Received signal $signo (with child $pid)\n"; /* check if the pid is zero: thus it will work even if the behaviour of this * function will be fixed in the future. */ if ($pid!=0) posix_kill($pid, SIGKILL); /* the only possible signal */ } /* register the signal */ pcntl_signal(SIGALRM, "sa"); /* get an ipc queue */ if (($sysId = ftok("/tmp/pr", "a"))===-1) die("Could not ftok\n"); $key_t = msg_get_queue($sysId); /* ipc message type based on parent's pid */ $msgtype = posix_getpid(); /* fork */ $pid = pcntl_fork(); if ($pid==-1) { echo "Failed to fork.\n"; exit(1); } else if ($pid==0) { /* child process */ $ip = gethostbyname($hostname); msg_send($key_t, $msgtype, $ip, true, false, $err); exit(0); } else { /* parent process */ pcntl_alarm(5); /* timeout before giving up */ if (msg_receive($key_t, $msgtype, $type, 100, $msg, true, 0, $err)===false) echo("receive failed.\n"); else echo $msg."\n"; pcntl_alarm(0); } /* clean and finish */ msg_remove_queue($key_t); echo "Done.\n"; ?>