Commit 24e1003a524922782bb0290ecceef01676f92c16

Authored by aurel32
1 parent a3a1e0fc

linux-user: Added posix message queue syscalls except mq_notify

Signed-off-by: Lionel Landwerlin <lionel.landwerlin@openwide.fr>
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7114 c046a42c-6fe2-441c-8c8c-71466251a162
linux-user/strace.list
... ... @@ -524,22 +524,22 @@
524 524 { TARGET_NR_mpx, "mpx" , NULL, NULL, NULL },
525 525 #endif
526 526 #ifdef TARGET_NR_mq_getsetattr
527   -{ TARGET_NR_mq_getsetattr, "mq_getsetattr" , NULL, NULL, NULL },
  527 +{ TARGET_NR_mq_getsetattr, "mq_getsetattr" , "%s(%d,%p,%p)", NULL, NULL },
528 528 #endif
529 529 #ifdef TARGET_NR_mq_notify
530   -{ TARGET_NR_mq_notify, "mq_notify" , NULL, NULL, NULL },
  530 +{ TARGET_NR_mq_notify, "mq_notify" , "%s(%d,%p)", NULL, NULL },
531 531 #endif
532 532 #ifdef TARGET_NR_mq_open
533   -{ TARGET_NR_mq_open, "mq_open" , NULL, NULL, NULL },
  533 +{ TARGET_NR_mq_open, "mq_open" , "%s(\"/%s\",%#x,%#o,%p)", NULL, NULL },
534 534 #endif
535 535 #ifdef TARGET_NR_mq_timedreceive
536   -{ TARGET_NR_mq_timedreceive, "mq_timedreceive" , NULL, NULL, NULL },
  536 +{ TARGET_NR_mq_timedreceive, "mq_timedreceive" , "%s(%d,%p,%d,%u,%p)", NULL, NULL },
537 537 #endif
538 538 #ifdef TARGET_NR_mq_timedsend
539   -{ TARGET_NR_mq_timedsend, "mq_timedsend" , NULL, NULL, NULL },
  539 +{ TARGET_NR_mq_timedsend, "mq_timedsend" , "%s(%d,%p,%d,%u,%p)", NULL, NULL },
540 540 #endif
541 541 #ifdef TARGET_NR_mq_unlink
542   -{ TARGET_NR_mq_unlink, "mq_unlink" , NULL, NULL, NULL },
  542 +{ TARGET_NR_mq_unlink, "mq_unlink" , "%s(%s)", NULL, NULL },
543 543 #endif
544 544 #ifdef TARGET_NR_mremap
545 545 { TARGET_NR_mremap, "mremap" , NULL, NULL, NULL },
... ...
linux-user/syscall.c
... ... @@ -29,6 +29,7 @@
29 29 #include <fcntl.h>
30 30 #include <time.h>
31 31 #include <limits.h>
  32 +#include <mqueue.h>
32 33 #include <sys/types.h>
33 34 #include <sys/ipc.h>
34 35 #include <sys/msg.h>
... ... @@ -635,6 +636,43 @@ static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
635 636 return 0;
636 637 }
637 638  
  639 +static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
  640 + abi_ulong target_mq_attr_addr)
  641 +{
  642 + struct target_mq_attr *target_mq_attr;
  643 +
  644 + if (!lock_user_struct(VERIFY_READ, target_mq_attr,
  645 + target_mq_attr_addr, 1))
  646 + return -TARGET_EFAULT;
  647 +
  648 + __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
  649 + __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
  650 + __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
  651 + __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
  652 +
  653 + unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
  654 +
  655 + return 0;
  656 +}
  657 +
  658 +static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
  659 + const struct mq_attr *attr)
  660 +{
  661 + struct target_mq_attr *target_mq_attr;
  662 +
  663 + if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
  664 + target_mq_attr_addr, 0))
  665 + return -TARGET_EFAULT;
  666 +
  667 + __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
  668 + __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
  669 + __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
  670 + __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
  671 +
  672 + unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
  673 +
  674 + return 0;
  675 +}
638 676  
639 677 /* do_select() must return target values and target errnos. */
640 678 static abi_long do_select(int n,
... ... @@ -6148,6 +6186,81 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
6148 6186 break;
6149 6187 #endif
6150 6188  
  6189 +#ifdef TARGET_NR_mq_open
  6190 + case TARGET_NR_mq_open:
  6191 + {
  6192 + struct mq_attr posix_mq_attr;
  6193 +
  6194 + p = lock_user_string(arg1 - 1);
  6195 + if (arg4 != 0)
  6196 + copy_from_user_mq_attr (&posix_mq_attr, arg4);
  6197 + ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
  6198 + unlock_user (p, arg1, 0);
  6199 + }
  6200 + break;
  6201 +
  6202 + case TARGET_NR_mq_unlink:
  6203 + p = lock_user_string(arg1 - 1);
  6204 + ret = get_errno(mq_unlink(p));
  6205 + unlock_user (p, arg1, 0);
  6206 + break;
  6207 +
  6208 + case TARGET_NR_mq_timedsend:
  6209 + {
  6210 + struct timespec ts;
  6211 +
  6212 + p = lock_user (VERIFY_READ, arg2, arg3, 1);
  6213 + if (arg5 != 0) {
  6214 + target_to_host_timespec(&ts, arg5);
  6215 + ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
  6216 + host_to_target_timespec(arg5, &ts);
  6217 + }
  6218 + else
  6219 + ret = get_errno(mq_send(arg1, p, arg3, arg4));
  6220 + unlock_user (p, arg2, arg3);
  6221 + }
  6222 + break;
  6223 +
  6224 + case TARGET_NR_mq_timedreceive:
  6225 + {
  6226 + struct timespec ts;
  6227 + unsigned int prio;
  6228 +
  6229 + p = lock_user (VERIFY_READ, arg2, arg3, 1);
  6230 + if (arg5 != 0) {
  6231 + target_to_host_timespec(&ts, arg5);
  6232 + ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
  6233 + host_to_target_timespec(arg5, &ts);
  6234 + }
  6235 + else
  6236 + ret = get_errno(mq_receive(arg1, p, arg3, &prio));
  6237 + unlock_user (p, arg2, arg3);
  6238 + if (arg4 != 0)
  6239 + put_user_u32(prio, arg4);
  6240 + }
  6241 + break;
  6242 +
  6243 + /* Not implemented for now... */
  6244 +/* case TARGET_NR_mq_notify: */
  6245 +/* break; */
  6246 +
  6247 + case TARGET_NR_mq_getsetattr:
  6248 + {
  6249 + struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
  6250 + ret = 0;
  6251 + if (arg3 != 0) {
  6252 + ret = mq_getattr(arg1, &posix_mq_attr_out);
  6253 + copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
  6254 + }
  6255 + if (arg2 != 0) {
  6256 + copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
  6257 + ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
  6258 + }
  6259 +
  6260 + }
  6261 + break;
  6262 +#endif
  6263 +
6151 6264 default:
6152 6265 unimplemented:
6153 6266 gemu_log("qemu: Unsupported syscall: %d\n", num);
... ...
linux-user/syscall_defs.h
... ... @@ -1998,6 +1998,13 @@ struct linux_dirent64 {
1998 1998 char d_name[256];
1999 1999 };
2000 2000  
  2001 +struct target_mq_attr {
  2002 + abi_long mq_flags;
  2003 + abi_long mq_maxmsg;
  2004 + abi_long mq_msgsize;
  2005 + abi_long mq_curmsgs;
  2006 +};
  2007 +
2001 2008 #include "socket.h"
2002 2009  
2003 2010 #include "errno_defs.h"
... ...