swoole_process的exec是exec系统调用的封装,用于执行外部的一个程序,其使用实例如下:
bool swoole_process->exec(string $execfile, array $args)
$execfile指定可执行文件的绝对路径,如 "/usr/bin/python"
$args是一个数组,是exec的参数列表,如 array('test.py', 123),相当与python test.py 123
执行成功后,当前进程的代码段将会被新程序替换。子进程蜕变成另外一套程序。父进程与当前进程仍然是父子进程关系。父进程与新进程之间可以通过可以通过标准输入输出进行通信,必须启用标准输入输出重定向。
下面我们看看其实现过程。
//swoole_process的exec过程解析
static PHP_METHOD(swoole_process, exec)
{
char *execfile = NULL;
zend_size_t execfile_len = 0;
zval *args;
//解析输入参数信息,这里会解析出文件执行路径和输入参数信息
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa", &execfile, &execfile_len, &args) == FAILURE)
{
RETURN_FALSE;
}
if (execfile_len < 1)//文件执行路径信息为空
{
swoole_php_fatal_error(E_WARNING, "exec file name is empty.");
RETURN_FALSE;
}
int exec_argc = php_swoole_array_length(args);//获取输入参数数组的长度信息
char **exec_args = emalloc(sizeof(char*) * (exec_argc + 2));//申请空间,申请的空间大小为输入参数数组长度+2的空间
zval *value = NULL;
exec_args[0] = sw_strdup(execfile);//空间的第0个元素设置为文件执行路径信息
int i = 1;
//循环赋值
SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(args), value)
convert_to_string(value);
sw_zval_add_ref(&value);
exec_args[i] = Z_STRVAL_P(value);
i++;
SW_HASHTABLE_FOREACH_END();
exec_args[i] = NULL;
//调用linux的execv系统函数,上面参数的处理,就是为了满足execv的要求,具体要求可以查看linux系统调用手册
if (execv(execfile, exec_args) < 0)
{
swoole_php_fatal_error(E_WARNING, "execv(%s) failed. Error: %s[%d]", execfile, strerror(errno), errno);
RETURN_FALSE;
}
else
{
RETURN_TRUE;
}
}