Commit 24e1003a524922782bb0290ecceef01676f92c16
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
Showing
3 changed files
with
126 additions
and
6 deletions
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" | ... | ... |