@ -75,6 +75,8 @@ struct QTestState
{
int fd ;
int qmp_fd ;
int sock ;
int qmpsock ;
pid_t qemu_pid ; /* our child QEMU process */
int wstatus ;
# ifdef _WIN32
@ -458,18 +460,19 @@ static QTestState *G_GNUC_PRINTF(2, 3) qtest_spawn_qemu(const char *qemu_bin,
return s ;
}
static char * qtest_socket_path ( const char * suffix )
{
return g_strdup_printf ( " %s/qtest-%d.%s " , g_get_tmp_dir ( ) , getpid ( ) , suffix ) ;
}
static QTestState * qtest_init_internal ( const char * qemu_bin ,
const char * extra_args )
const char * extra_args ,
bool do_connect )
{
QTestState * s ;
int sock , qmpsock , i ;
gchar * socket_path ;
gchar * qmp_socket_path ;
socket_path = g_strdup_printf ( " %s/qtest-%d.sock " ,
g_get_tmp_dir ( ) , getpid ( ) ) ;
qmp_socket_path = g_strdup_printf ( " %s/qtest-%d.qmp " ,
g_get_tmp_dir ( ) , getpid ( ) ) ;
g_autofree gchar * socket_path = qtest_socket_path ( " sock " ) ;
g_autofree gchar * qmp_socket_path = qtest_socket_path ( " qmp " ) ;
/*
* It ' s possible that if an earlier test run crashed it might
@ -501,22 +504,19 @@ static QTestState *qtest_init_internal(const char *qemu_bin,
qtest_client_set_rx_handler ( s , qtest_client_socket_recv_line ) ;
qtest_client_set_tx_handler ( s , qtest_client_socket_send ) ;
s - > fd = socket_accept ( sock ) ;
if ( s - > fd > = 0 ) {
s - > qmp_fd = socket_accept ( qmpsock ) ;
}
unlink ( socket_path ) ;
unlink ( qmp_socket_path ) ;
g_free ( socket_path ) ;
g_free ( qmp_socket_path ) ;
g_assert ( s - > fd > = 0 & & s - > qmp_fd > = 0 ) ;
s - > rx = g_string_new ( " " ) ;
for ( i = 0 ; i < MAX_IRQ ; i + + ) {
s - > irq_level [ i ] = false ;
}
s - > fd = - 1 ;
s - > qmp_fd = - 1 ;
s - > sock = sock ;
s - > qmpsock = qmpsock ;
if ( do_connect ) {
qtest_connect ( s ) ;
}
/*
* Stopping QEMU for debugging is not supported on Windows .
*
@ -531,28 +531,38 @@ static QTestState *qtest_init_internal(const char *qemu_bin,
}
# endif
/* ask endianness of the target */
return s ;
}
s - > big_endian = qtest_query_target_endianness ( s ) ;
void qtest_connect ( QTestState * s )
{
g_autofree gchar * socket_path = qtest_socket_path ( " sock " ) ;
g_autofree gchar * qmp_socket_path = qtest_socket_path ( " qmp " ) ;
return s ;
g_assert ( s - > sock > = 0 & & s - > qmpsock > = 0 ) ;
s - > fd = socket_accept ( s - > sock ) ;
if ( s - > fd > = 0 ) {
s - > qmp_fd = socket_accept ( s - > qmpsock ) ;
}
unlink ( socket_path ) ;
unlink ( qmp_socket_path ) ;
g_assert ( s - > fd > = 0 & & s - > qmp_fd > = 0 ) ;
s - > sock = s - > qmpsock = - 1 ;
/* ask endianness of the target */
s - > big_endian = qtest_query_target_endianness ( s ) ;
}
QTestState * qtest_init_without_qmp_handshake ( const char * extra_args )
{
return qtest_init_internal ( qtest_qemu_binary ( NULL ) , extra_args ) ;
return qtest_init_internal ( qtest_qemu_binary ( NULL ) , extra_args , true ) ;
}
QTestState * qtest_init_with_env_and_capabilities ( const char * var ,
const char * extra_args ,
QList * capabilities )
void qtest_qmp_handshake ( QTestState * s , QList * capabilities )
{
QTestState * s = qtest_init_internal ( qtest_qemu_binary ( var ) , extra_args ) ;
QDict * greeting ;
/* Read the QMP greeting and then do the handshake */
greeting = qtest_qmp_receive ( s ) ;
QDict * greeting = qtest_qmp_receive ( s ) ;
qobject_unref ( greeting ) ;
if ( capabilities ) {
qtest_qmp_assert_success ( s ,
" { 'execute': 'qmp_capabilities', "
@ -561,18 +571,37 @@ QTestState *qtest_init_with_env_and_capabilities(const char *var,
} else {
qtest_qmp_assert_success ( s , " { 'execute': 'qmp_capabilities' } " ) ;
}
}
QTestState * qtest_init_with_env_and_capabilities ( const char * var ,
const char * extra_args ,
QList * capabilities ,
bool do_connect )
{
QTestState * s = qtest_init_internal ( qtest_qemu_binary ( var ) , extra_args ,
do_connect ) ;
if ( do_connect ) {
qtest_qmp_handshake ( s , capabilities ) ;
} else {
/*
* If the connection is delayed , the capabilities must be set
* at that moment .
*/
assert ( ! capabilities ) ;
}
return s ;
}
QTestState * qtest_init_with_env ( const char * var , const char * extra_args )
QTestState * qtest_init_with_env ( const char * var , const char * extra_args ,
bool do_connect )
{
return qtest_init_with_env_and_capabilities ( var , extra_args , NULL ) ;
return qtest_init_with_env_and_capabilities ( var , extra_args , NULL , true ) ;
}
QTestState * qtest_init ( const char * extra_args )
{
return qtest_init_with_env ( NULL , extra_args ) ;
return qtest_init_with_env ( NULL , extra_args , true ) ;
}
QTestState * qtest_vinitf ( const char * fmt , va_list ap )
@ -1580,7 +1609,7 @@ static struct MachInfo *qtest_get_machines(const char *var)
silence_spawn_log = ! g_test_verbose ( ) ;
qts = qtest_init_with_env ( qemu_var , " -machine none " ) ;
qts = qtest_init_with_env ( qemu_var , " -machine none " , true ) ;
response = qtest_qmp ( qts , " { 'execute': 'query-machines' } " ) ;
g_assert ( response ) ;
list = qdict_get_qlist ( response , " return " ) ;
@ -1635,7 +1664,7 @@ static struct CpuModel *qtest_get_cpu_models(void)
silence_spawn_log = ! g_test_verbose ( ) ;
qts = qtest_init_with_env ( NULL , " -machine none " ) ;
qts = qtest_init_with_env ( NULL , " -machine none " , true ) ;
response = qtest_qmp ( qts , " { 'execute': 'query-cpu-definitions' } " ) ;
g_assert ( response ) ;
list = qdict_get_qlist ( response , " return " ) ;