--TEST--
Forking a child and using the same connection.
--SKIPIF--
<?php
require_once('skipif.inc');
require_once(
'skipifemb.inc');
require_once(
'skipifconnectfailure.inc');

if (!
function_exists('pcntl_fork'))
    die(
"skip Process Control Functions not available");

if (!
function_exists('posix_getpid'))
    die(
"skip POSIX functions not available");

require_once(
'connect.inc');
if (!
$link my_mysqli_connect($host$user$passwd$db$port$socket))
    die(
sprintf("Cannot connect, [%d] %s"mysqli_connect_errno(), mysqli_connect_error()));

if (!
have_innodb($link))
    die(
sprintf("Needs InnoDB support, [%d] %s"$link->errno$link->error));
?>
--FILE--
<?php
    
require_once("table.inc");

    
$res mysqli_query($link"SELECT 'dumped by the parent' AS message");
    
$pid pcntl_fork();
    switch (
$pid) {
        case -
1:
            
printf("[001] Cannot fork child");
            break;

        case 
0:
            
/* child */
            
exit(0);
            break;

        default:
            
/* parent */
            
$status null;
            
$wait_id pcntl_waitpid($pid$status);
            if (
pcntl_wifexited($status) && (!= ($tmp pcntl_wexitstatus($status)))) {
                
printf("Exit code: %s\n", (pcntl_wifexited($status)) ? pcntl_wexitstatus($status) : 'n/a');
                
printf("Signal: %s\n", (pcntl_wifsignaled($status)) ? pcntl_wtermsig($status) : 'n/a');
                
printf("Stopped: %d\n", (pcntl_wifstopped($status)) ? pcntl_wstopsig($status) : 'n/a');
            }
            
var_dump(mysqli_fetch_assoc($res));
            
mysqli_free_result($res);
            break;
    }

    if (@
mysqli_query($link"SELECT id FROM test WHERE id = 1"))
        
printf("[003] Expecting error and closed connection, child exit should have closed connection\n");
    else if (((
$errno mysqli_errno($link)) == 0) || ('' == ($error mysqli_error($link))))
        
printf("[004] Expecting error string and error code from MySQL, got errno = %s/%s, error = %s/%s\n",
            
gettype($errno), $errnogettype($error), $error);

    
mysqli_close($link);
    if (!
$link my_mysqli_connect($host$user$passwd$db$port$socket))
        
printf("[005] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
            
$host$user$db$port$socket);

    
/* non trivial tests require a message list for parent-child communication */
    
if (!mysqli_query($link"DROP TABLE IF EXISTS messages"))
        
printf("[006] [%d] %s\n"mysqli_error($link), mysqli_errno($link));

    if (!
mysqli_query($link"CREATE TABLE messages(
        msg_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
        msg_time TIMESTAMP,
        pid INT NOT NULL,
        sender ENUM('child', 'parent') NOT NULL,
        msg TEXT) ENGINE = InnoDB"
))
        
printf("[007] [%d] %s\n"mysqli_error($link), mysqli_errno($link));

    
mysqli_autocommit($linkfalse);
    if (!
$res mysqli_query($link"SELECT id, label FROM test ORDER BY id ASC LIMIT 3"MYSQLI_USE_RESULT))
        
printf("[008] [%d] %s\n"mysqli_error($link), mysqli_errno($link));

    
$pid pcntl_fork();

    switch (
$pid) {
        case -
1:
            
printf("[009] Cannot fork child");
            break;

        case 
0:
            
/* child */
            
if (!($plink my_mysqli_connect($host$user$passwd$db$port$socket)) || !mysqli_autocommit($plinktrue))
                exit(
mysqli_errno($plink));

            
$sql sprintf("INSERT INTO messages(pid, sender, msg) VALUES (%d, 'child', '%%s')"posix_getpid());
            if (!
mysqli_query($plinksprintf($sql'start')))
                exit(
mysqli_errno($plink));

            
$parent_sql sprintf("SELECT msg_id, msg_time, msg FROM messages WHERE pid = %d  AND sender = 'parent' ORDER BY msg_id DESC LIMIT 1"posix_getppid());
            
$msg_id 0;
            while (
$row mysqli_fetch_assoc($res)) {
                
/* send row to parent */
                
ob_start();
                
var_dump($row);
                
$tmp ob_get_contents();
                
ob_end_clean();
                if (!
mysqli_query($plinksprintf($sql$tmp)))
                    exit(
mysqli_errno($plink));

                
/* let the parent reply... */
                
$start time();
                do {
                    
usleep(100);
                    if (!
$pres mysqli_query($plink$parent_sql))
                        continue;
                    
$tmp mysqli_fetch_assoc($pres);
                    
mysqli_free_result($pres);
                    if (
$tmp['msg_id'] == $msg_id)
                        
/* no new message */
                        
continue;
                    if (
$tmp['msg'] == 'stop')
                        break 
2;
                    
$msg_id $tmp['msg_id'];
                    break;
                } while ((
time() - $start) < 5);

            }

            if (!
mysqli_query($plinksprintf($sql'stop')) || !mysqli_commit($link))
                exit(
mysqli_errno($plink));
            exit(
0);
            break;

        default:
            
/* parent */
            
if (!$plink my_mysqli_connect($host$user$passwd$db$port$socket))
                    
printf("[010] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
                    
$host$user$db$port$socket);

            
$status null;
            
$start time();
            
$sql sprintf("SELECT msg_id, msg_time, msg FROM messages WHERE pid = %d AND sender = 'child' ORDER BY msg_id DESC LIMIT 1"$pid);
            
$parent_sql sprintf("INSERT INTO messages (pid, sender, msg) VALUES (%d, 'parent', '%%s')"posix_getpid());
            
$last_msg_id 0;
            
$num_rows 0;
            do {
                
$wait_id pcntl_waitpid($pid$statusWNOHANG);
                if (
$pres mysqli_query($plink$sql)) {
                    
$row mysqli_fetch_assoc($pres);
                    if (
$row['msg_id'] != $last_msg_id) {
                        
$last_msg_id $row['msg_id'];
                        switch (
$row['msg']) {
                            case 
'start':
                                break;
                            case 
'stop':
                                break 
2;
                            default:
                                
/* client has started fetching rows */
                                
$client_row $row['msg'];

                                
$num_rows++;
                                if (
$num_rows 3) {
                                    
printf("[011] Child has fetched more than three rows!\n");
                                    
var_dump($client_row);
                                    if (!
mysqli_query($plinksprintf($parent_sql'stop'))) {
                                        
printf("[012] Parent cannot inform child\n"mysqli_errno($plink), mysqli_error($plink));
                                    }
                                    break 
2;
                                }

                                if (!
$parent_row mysqli_fetch_assoc($res)) {
                                    
printf("[013] Parent cannot fetch row %d\n"$num_rowsmysqli_errno($link), mysqli_error($link));
                                    if (!
mysqli_query($plinksprintf($parent_sql'stop'))) {
                                        
printf("[014] Parent cannot inform child\n"mysqli_errno($plink), mysqli_error($plink));
                                    }
                                    break 
2;
                                }

                                
ob_start();
                                
var_dump($parent_row);
                                
$parent_row ob_get_contents();
                                
ob_end_clean();

                                if (
$parent_row != $client_row) {
                                    
printf("[015] Child indicates different results than parent.\n");
                                    
var_dump($child_row);
                                    
var_dump($parent_row);
                                    if (!
mysqli_query($plinksprintf($parent_sql'stop'))) {
                                        
printf("[016] Parent cannot inform child\n"mysqli_errno($plink), mysqli_error($plink));
                                    }
                                    break 
2;
                                }

                                if (!
mysqli_query($plinksprintf($parent_sql'continue'))) {
                                    
printf("[017] Parent cannot inform child to continue.\n"mysqli_errno($plink), mysqli_error($plink));
                                }
                                break;
                        }
                    }
                    
mysqli_free_result($pres);
                }
                
usleep(100);
            } while (((
time() - $start) < 5) && ($num_rows 3));
            
mysqli_close($plink);
            
$wait_id pcntl_waitpid($pid$status);
            if (
pcntl_wifexited($status) && (!= ($tmp pcntl_wexitstatus($status)))) {
                
printf("Exit code: %s\n", (pcntl_wifexited($status)) ? pcntl_wexitstatus($status) : 'n/a');
                
printf("Signal: %s\n", (pcntl_wifsignaled($status)) ? pcntl_wtermsig($status) : 'n/a');
                
printf("Stopped: %d\n", (pcntl_wifstopped($status)) ? pcntl_wstopsig($status) : 'n/a');
            }
            break;
    }
    
mysqli_free_result($res);
    
mysqli_close($link);

    if (!
$link my_mysqli_connect($host$user$passwd$db$port$socket))
        
printf("[018] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
            
$host$user$db$port$socket);

    if (!
$res mysqli_query($link"SELECT sender, msg FROM messages ORDER BY msg_id ASC"))
        
printf("[019] [%d] %s\n"mysqli_errno($link), mysqli_error($link));

    while (
$row mysqli_fetch_assoc($res))
        
printf("%10s %s\n"$row['sender'], substr($row['msg'], 05));
    
mysqli_free_result($res);

    print 
"done!";
?>
--CLEAN--
<?php
require_once("connect.inc");
if (!
$link my_mysqli_connect($host$user$passwd$db$port$socket))
   
printf("[c001] [%d] %s\n"mysqli_connect_errno(), mysqli_connect_error());

if (!
mysqli_query($link"DROP TABLE IF EXISTS test"))
    
printf("[c002] Cannot drop table, [%d] %s\n"mysqli_errno($link), mysqli_error($link));

if (!
mysqli_query($link"DROP TABLE IF EXISTS messages"))
    
printf("[c003] Cannot drop table, [%d] %s\n"mysqli_errno($link), mysqli_error($link));

mysqli_close($link);
?>
--EXPECTF--
array(1) {
  ["message"]=>
  string(20) "dumped by the parent"
}
     child start
     child array
    parent conti
     child array
    parent conti
     child array
    parent conti
     child stop
done!