Commit 1bc012f65a9b269ec373ca7586032c205d112d8a
1 parent
3eb6b044
IPC message translation.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2930 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
123 additions
and
12 deletions
linux-user/syscall.c
... | ... | @@ -1437,6 +1437,117 @@ static inline long do_semctl(long first, long second, long third, long ptr) |
1437 | 1437 | return ret; |
1438 | 1438 | } |
1439 | 1439 | |
1440 | +struct target_msqid_ds | |
1441 | +{ | |
1442 | + struct target_ipc_perm msg_perm; | |
1443 | + target_ulong msg_stime; | |
1444 | + target_ulong __unused1; | |
1445 | + target_ulong msg_rtime; | |
1446 | + target_ulong __unused2; | |
1447 | + target_ulong msg_ctime; | |
1448 | + target_ulong __unused3; | |
1449 | + target_ulong __msg_cbytes; | |
1450 | + target_ulong msg_qnum; | |
1451 | + target_ulong msg_qbytes; | |
1452 | + target_ulong msg_lspid; | |
1453 | + target_ulong msg_lrpid; | |
1454 | + target_ulong __unused4; | |
1455 | + target_ulong __unused5; | |
1456 | +}; | |
1457 | + | |
1458 | +static inline void target_to_host_msqid_ds(struct msqid_ds *host_md, | |
1459 | + target_ulong target_addr) | |
1460 | +{ | |
1461 | + struct target_msqid_ds *target_md; | |
1462 | + | |
1463 | + lock_user_struct(target_md, target_addr, 1); | |
1464 | + target_to_host_ipc_perm(&(host_md->msg_perm),target_addr); | |
1465 | + host_md->msg_stime = tswapl(target_md->msg_stime); | |
1466 | + host_md->msg_rtime = tswapl(target_md->msg_rtime); | |
1467 | + host_md->msg_ctime = tswapl(target_md->msg_ctime); | |
1468 | + host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes); | |
1469 | + host_md->msg_qnum = tswapl(target_md->msg_qnum); | |
1470 | + host_md->msg_qbytes = tswapl(target_md->msg_qbytes); | |
1471 | + host_md->msg_lspid = tswapl(target_md->msg_lspid); | |
1472 | + host_md->msg_lrpid = tswapl(target_md->msg_lrpid); | |
1473 | + unlock_user_struct(target_md, target_addr, 0); | |
1474 | +} | |
1475 | + | |
1476 | +static inline void host_to_target_msqid_ds(target_ulong target_addr, | |
1477 | + struct msqid_ds *host_md) | |
1478 | +{ | |
1479 | + struct target_msqid_ds *target_md; | |
1480 | + | |
1481 | + lock_user_struct(target_md, target_addr, 0); | |
1482 | + host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)); | |
1483 | + target_md->msg_stime = tswapl(host_md->msg_stime); | |
1484 | + target_md->msg_rtime = tswapl(host_md->msg_rtime); | |
1485 | + target_md->msg_ctime = tswapl(host_md->msg_ctime); | |
1486 | + target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes); | |
1487 | + target_md->msg_qnum = tswapl(host_md->msg_qnum); | |
1488 | + target_md->msg_qbytes = tswapl(host_md->msg_qbytes); | |
1489 | + target_md->msg_lspid = tswapl(host_md->msg_lspid); | |
1490 | + target_md->msg_lrpid = tswapl(host_md->msg_lrpid); | |
1491 | + unlock_user_struct(target_md, target_addr, 1); | |
1492 | +} | |
1493 | + | |
1494 | +static inline long do_msgctl(long first, long second, long ptr) | |
1495 | +{ | |
1496 | + struct msqid_ds dsarg; | |
1497 | + int cmd = second&0xff; | |
1498 | + long ret = 0; | |
1499 | + switch( cmd ) { | |
1500 | + case IPC_STAT: | |
1501 | + case IPC_SET: | |
1502 | + target_to_host_msqid_ds(&dsarg,ptr); | |
1503 | + ret = get_errno(msgctl(first, cmd, &dsarg)); | |
1504 | + host_to_target_msqid_ds(ptr,&dsarg); | |
1505 | + default: | |
1506 | + ret = get_errno(msgctl(first, cmd, &dsarg)); | |
1507 | + } | |
1508 | + return ret; | |
1509 | +} | |
1510 | + | |
1511 | +struct target_msgbuf { | |
1512 | + target_ulong mtype; | |
1513 | + char mtext[1]; | |
1514 | +}; | |
1515 | + | |
1516 | +static inline long do_msgsnd(long msqid, long msgp, long msgsz, long msgflg) | |
1517 | +{ | |
1518 | + struct target_msgbuf *target_mb; | |
1519 | + struct msgbuf *host_mb; | |
1520 | + long ret = 0; | |
1521 | + | |
1522 | + lock_user_struct(target_mb,msgp,0); | |
1523 | + host_mb = malloc(msgsz+sizeof(long)); | |
1524 | + host_mb->mtype = tswapl(target_mb->mtype); | |
1525 | + memcpy(host_mb->mtext,target_mb->mtext,msgsz); | |
1526 | + ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg)); | |
1527 | + free(host_mb); | |
1528 | + unlock_user_struct(target_mb, msgp, 0); | |
1529 | + | |
1530 | + return ret; | |
1531 | +} | |
1532 | + | |
1533 | +static inline long do_msgrcv(long msqid, long msgp, long msgsz, long msgtype, long msgflg) | |
1534 | +{ | |
1535 | + struct target_msgbuf *target_mb; | |
1536 | + struct msgbuf *host_mb; | |
1537 | + long ret = 0; | |
1538 | + | |
1539 | + lock_user_struct(target_mb, msgp, 0); | |
1540 | + host_mb = malloc(msgsz+sizeof(long)); | |
1541 | + ret = get_errno(msgrcv(msqid, host_mb, msgsz, 1, msgflg)); | |
1542 | + if (ret > 0) | |
1543 | + memcpy(target_mb->mtext, host_mb->mtext, ret); | |
1544 | + target_mb->mtype = tswapl(host_mb->mtype); | |
1545 | + free(host_mb); | |
1546 | + unlock_user_struct(target_mb, msgp, 0); | |
1547 | + | |
1548 | + return ret; | |
1549 | +} | |
1550 | + | |
1440 | 1551 | /* ??? This only works with linear mappings. */ |
1441 | 1552 | static long do_ipc(long call, long first, long second, long third, |
1442 | 1553 | long ptr, long fifth) |
... | ... | @@ -1473,27 +1584,27 @@ static long do_ipc(long call, long first, long second, long third, |
1473 | 1584 | break; |
1474 | 1585 | |
1475 | 1586 | case IPCOP_msgsnd: |
1476 | - ret = get_errno(msgsnd(first, (struct msgbuf *) ptr, second, third)); | |
1587 | + ret = do_msgsnd(first, ptr, second, third); | |
1477 | 1588 | break; |
1478 | 1589 | |
1479 | 1590 | case IPCOP_msgctl: |
1480 | - ret = get_errno(msgctl(first, second, (struct msqid_ds *) ptr)); | |
1591 | + ret = do_msgctl(first, second, ptr); | |
1481 | 1592 | break; |
1482 | 1593 | |
1483 | 1594 | case IPCOP_msgrcv: |
1484 | - { | |
1485 | - struct ipc_kludge | |
1486 | - { | |
1487 | - void *__unbounded msgp; | |
1488 | - long int msgtyp; | |
1489 | - }; | |
1595 | + { | |
1596 | + struct ipc_kludge | |
1597 | + { | |
1598 | + void *__unbounded msgp; | |
1599 | + long int msgtyp; | |
1600 | + }; | |
1490 | 1601 | |
1491 | - struct ipc_kludge *foo = (struct ipc_kludge *) ptr; | |
1492 | - struct msgbuf *msgp = (struct msgbuf *) foo->msgp; | |
1602 | + struct ipc_kludge *foo = (struct ipc_kludge *) ptr; | |
1603 | + struct msgbuf *msgp = (struct msgbuf *) foo->msgp; | |
1493 | 1604 | |
1494 | - ret = get_errno(msgrcv(first, msgp, second, 0, third)); | |
1605 | + ret = do_msgrcv(first, (long)msgp, second, 0, third); | |
1495 | 1606 | |
1496 | - } | |
1607 | + } | |
1497 | 1608 | break; |
1498 | 1609 | |
1499 | 1610 | case IPCOP_shmat: | ... | ... |