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" | ... | ... |