php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #47192 gethostbyname is not interruptible by signals
Submitted: 2009-01-22 18:13 UTC Modified: 2011-04-08 20:45 UTC
Votes:2
Avg. Score:4.5 ± 0.5
Reproduced:2 of 2 (100.0%)
Same Version:2 (100.0%)
Same OS:1 (50.0%)
From: fmassei at gmail dot com Assigned:
Status: Open Package: PCNTL related
PHP Version: 5.2.8 OS: linux
Private report: No CVE-ID: None
 [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.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-01-23 13:52 UTC] fmassei at gmail dot com
Somehow I posted this bug in the wrong category. It's not a "Feature/Change Request" but more a "Network related" bug.
 [2009-01-24 23:55 UTC] jani@php.net
No, it's a change request since this function is not designed to do 
what you ask. Not everything is a bug..
 [2009-01-25 16:00 UTC] fmassei at gmail dot com
well, it actually IS a bug, as long as the "pcntl_" functions are not working as described for this function only.
 [2009-01-26 11:22 UTC] fmassei at gmail dot com
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";
?>
 [2011-04-08 20:45 UTC] jani@php.net
-Package: Feature/Change Request +Package: PCNTL related
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 14:01:29 2024 UTC