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,22 +524,22 @@ | ||
| 524 | { TARGET_NR_mpx, "mpx" , NULL, NULL, NULL }, | 524 | { TARGET_NR_mpx, "mpx" , NULL, NULL, NULL }, |
| 525 | #endif | 525 | #endif |
| 526 | #ifdef TARGET_NR_mq_getsetattr | 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 | #endif | 528 | #endif |
| 529 | #ifdef TARGET_NR_mq_notify | 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 | #endif | 531 | #endif |
| 532 | #ifdef TARGET_NR_mq_open | 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 | #endif | 534 | #endif |
| 535 | #ifdef TARGET_NR_mq_timedreceive | 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 | #endif | 537 | #endif |
| 538 | #ifdef TARGET_NR_mq_timedsend | 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 | #endif | 540 | #endif |
| 541 | #ifdef TARGET_NR_mq_unlink | 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 | #endif | 543 | #endif |
| 544 | #ifdef TARGET_NR_mremap | 544 | #ifdef TARGET_NR_mremap |
| 545 | { TARGET_NR_mremap, "mremap" , NULL, NULL, NULL }, | 545 | { TARGET_NR_mremap, "mremap" , NULL, NULL, NULL }, |
linux-user/syscall.c
| @@ -29,6 +29,7 @@ | @@ -29,6 +29,7 @@ | ||
| 29 | #include <fcntl.h> | 29 | #include <fcntl.h> |
| 30 | #include <time.h> | 30 | #include <time.h> |
| 31 | #include <limits.h> | 31 | #include <limits.h> |
| 32 | +#include <mqueue.h> | ||
| 32 | #include <sys/types.h> | 33 | #include <sys/types.h> |
| 33 | #include <sys/ipc.h> | 34 | #include <sys/ipc.h> |
| 34 | #include <sys/msg.h> | 35 | #include <sys/msg.h> |
| @@ -635,6 +636,43 @@ static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr, | @@ -635,6 +636,43 @@ static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr, | ||
| 635 | return 0; | 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 | /* do_select() must return target values and target errnos. */ | 677 | /* do_select() must return target values and target errnos. */ |
| 640 | static abi_long do_select(int n, | 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,6 +6186,81 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
| 6148 | break; | 6186 | break; |
| 6149 | #endif | 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 | default: | 6264 | default: |
| 6152 | unimplemented: | 6265 | unimplemented: |
| 6153 | gemu_log("qemu: Unsupported syscall: %d\n", num); | 6266 | gemu_log("qemu: Unsupported syscall: %d\n", num); |
linux-user/syscall_defs.h
| @@ -1998,6 +1998,13 @@ struct linux_dirent64 { | @@ -1998,6 +1998,13 @@ struct linux_dirent64 { | ||
| 1998 | char d_name[256]; | 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 | #include "socket.h" | 2008 | #include "socket.h" |
| 2002 | 2009 | ||
| 2003 | #include "errno_defs.h" | 2010 | #include "errno_defs.h" |