@ -863,6 +863,7 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,
char * pathbuf = NULL ;
const char * path ;
size_t pathlen ;
size_t addrlen ;
sock = qemu_socket ( PF_UNIX , SOCK_STREAM , 0 ) ;
if ( sock < 0 ) {
@ -879,9 +880,11 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,
}
pathlen = strlen ( path ) ;
if ( pathlen > sizeof ( un . sun_path ) ) {
if ( pathlen > sizeof ( un . sun_path ) | |
( saddr - > abstract & & pathlen > ( sizeof ( un . sun_path ) - 1 ) ) ) {
error_setg ( errp , " UNIX socket path '%s' is too long " , path ) ;
error_append_hint ( errp , " Path must be less than %zu bytes \n " ,
saddr - > abstract ? sizeof ( un . sun_path ) - 1 :
sizeof ( un . sun_path ) ) ;
goto err ;
}
@ -903,7 +906,7 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,
close ( fd ) ;
}
if ( unlink ( path ) < 0 & & errno ! = ENOENT ) {
if ( ! saddr - > abstract & & unlink ( path ) < 0 & & errno ! = ENOENT ) {
error_setg_errno ( errp , errno ,
" Failed to unlink socket %s " , path ) ;
goto err ;
@ -911,9 +914,19 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,
memset ( & un , 0 , sizeof ( un ) ) ;
un . sun_family = AF_UNIX ;
memcpy ( un . sun_path , path , pathle n) ;
addrlen = sizeof ( u n) ;
if ( bind ( sock , ( struct sockaddr * ) & un , sizeof ( un ) ) < 0 ) {
if ( saddr - > abstract ) {
un . sun_path [ 0 ] = ' \0 ' ;
memcpy ( & un . sun_path [ 1 ] , path , pathlen ) ;
if ( saddr - > tight ) {
addrlen = offsetof ( struct sockaddr_un , sun_path ) + 1 + pathlen ;
}
} else {
memcpy ( un . sun_path , path , pathlen ) ;
}
if ( bind ( sock , ( struct sockaddr * ) & un , addrlen ) < 0 ) {
error_setg_errno ( errp , errno , " Failed to bind socket to %s " , path ) ;
goto err ;
}
@ -936,6 +949,7 @@ static int unix_connect_saddr(UnixSocketAddress *saddr, Error **errp)
struct sockaddr_un un ;
int sock , rc ;
size_t pathlen ;
size_t addrlen ;
if ( saddr - > path = = NULL ) {
error_setg ( errp , " unix connect: no path specified " ) ;
@ -949,21 +963,32 @@ static int unix_connect_saddr(UnixSocketAddress *saddr, Error **errp)
}
pathlen = strlen ( saddr - > path ) ;
if ( pathlen > sizeof ( un . sun_path ) ) {
if ( pathlen > sizeof ( un . sun_path ) | |
( saddr - > abstract & & pathlen > ( sizeof ( un . sun_path ) - 1 ) ) ) {
error_setg ( errp , " UNIX socket path '%s' is too long " , saddr - > path ) ;
error_append_hint ( errp , " Path must be less than %zu bytes \n " ,
saddr - > abstract ? sizeof ( un . sun_path ) - 1 :
sizeof ( un . sun_path ) ) ;
goto err ;
}
memset ( & un , 0 , sizeof ( un ) ) ;
un . sun_family = AF_UNIX ;
memcpy ( un . sun_path , saddr - > path , pathle n) ;
addrlen = sizeof ( u n) ;
if ( saddr - > abstract ) {
un . sun_path [ 0 ] = ' \0 ' ;
memcpy ( & un . sun_path [ 1 ] , saddr - > path , pathlen ) ;
if ( saddr - > tight ) {
addrlen = offsetof ( struct sockaddr_un , sun_path ) + 1 + pathlen ;
}
} else {
memcpy ( un . sun_path , saddr - > path , pathlen ) ;
}
/* connect to peer */
do {
rc = 0 ;
if ( connect ( sock , ( struct sockaddr * ) & un , sizeof ( un ) ) < 0 ) {
if ( connect ( sock , ( struct sockaddr * ) & un , addrlen ) < 0 ) {
rc = - errno ;
}
} while ( rc = = - EINTR ) ;