@ -17,6 +17,8 @@
# include "qemu-bsd.h"
static int bsd_msgmax ;
/* quotactl(2) */
static inline abi_long do_bsd_quotactl ( abi_ulong path , abi_long cmd ,
__unused abi_ulong target_addr )
@ -260,6 +262,101 @@ static inline abi_long do_bsd_msgctl(int msgid, int target_cmd, abi_long ptr)
return ret ;
}
struct kern_mymsg {
long mtype ;
char mtext [ 1 ] ;
} ;
static inline abi_long bsd_validate_msgsz ( abi_ulong msgsz )
{
/* Fetch msgmax the first time we need it. */
if ( bsd_msgmax = = 0 ) {
size_t len = sizeof ( bsd_msgmax ) ;
if ( sysctlbyname ( " kern.ipc.msgmax " , & bsd_msgmax , & len , NULL , 0 ) = = - 1 ) {
return - TARGET_EINVAL ;
}
}
if ( msgsz > bsd_msgmax ) {
return - TARGET_EINVAL ;
}
return 0 ;
}
/* msgsnd(2) */
static inline abi_long do_bsd_msgsnd ( int msqid , abi_long msgp ,
abi_ulong msgsz , int msgflg )
{
struct target_msgbuf * target_mb ;
struct kern_mymsg * host_mb ;
abi_long ret ;
ret = bsd_validate_msgsz ( msgsz ) ;
if ( is_error ( ret ) ) {
return ret ;
}
if ( ! lock_user_struct ( VERIFY_READ , target_mb , msgp , 0 ) ) {
return - TARGET_EFAULT ;
}
host_mb = g_malloc ( msgsz + sizeof ( long ) ) ;
host_mb - > mtype = ( abi_long ) tswapal ( target_mb - > mtype ) ;
memcpy ( host_mb - > mtext , target_mb - > mtext , msgsz ) ;
ret = get_errno ( msgsnd ( msqid , host_mb , msgsz , msgflg ) ) ;
g_free ( host_mb ) ;
unlock_user_struct ( target_mb , msgp , 0 ) ;
return ret ;
}
/* msgget(2) */
static inline abi_long do_bsd_msgget ( abi_long key , abi_long msgflag )
{
abi_long ret ;
ret = get_errno ( msgget ( key , msgflag ) ) ;
return ret ;
}
/* msgrcv(2) */
static inline abi_long do_bsd_msgrcv ( int msqid , abi_long msgp ,
abi_ulong msgsz , abi_long msgtyp , int msgflg )
{
struct target_msgbuf * target_mb = NULL ;
char * target_mtext ;
struct kern_mymsg * host_mb ;
abi_long ret = 0 ;
ret = bsd_validate_msgsz ( msgsz ) ;
if ( is_error ( ret ) ) {
return ret ;
}
if ( ! lock_user_struct ( VERIFY_WRITE , target_mb , msgp , 0 ) ) {
return - TARGET_EFAULT ;
}
host_mb = g_malloc ( msgsz + sizeof ( long ) ) ;
ret = get_errno ( msgrcv ( msqid , host_mb , msgsz , tswapal ( msgtyp ) , msgflg ) ) ;
if ( ret > 0 ) {
abi_ulong target_mtext_addr = msgp + sizeof ( abi_ulong ) ;
target_mtext = lock_user ( VERIFY_WRITE , target_mtext_addr , ret , 0 ) ;
if ( target_mtext = = NULL ) {
ret = - TARGET_EFAULT ;
goto end ;
}
memcpy ( target_mb - > mtext , host_mb - > mtext , ret ) ;
unlock_user ( target_mtext , target_mtext_addr , ret ) ;
}
if ( ! is_error ( ret ) ) {
target_mb - > mtype = tswapal ( host_mb - > mtype ) ;
}
end :
if ( target_mb ! = NULL ) {
unlock_user_struct ( target_mb , msgp , 1 ) ;
}
g_free ( host_mb ) ;
return ret ;
}
/* getdtablesize(2) */
static inline abi_long do_bsd_getdtablesize ( void )
{