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,6 +1437,117 @@ static inline long do_semctl(long first, long second, long third, long ptr) | ||
1437 | return ret; | 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 | /* ??? This only works with linear mappings. */ | 1551 | /* ??? This only works with linear mappings. */ |
1441 | static long do_ipc(long call, long first, long second, long third, | 1552 | static long do_ipc(long call, long first, long second, long third, |
1442 | long ptr, long fifth) | 1553 | long ptr, long fifth) |
@@ -1473,27 +1584,27 @@ static long do_ipc(long call, long first, long second, long third, | @@ -1473,27 +1584,27 @@ static long do_ipc(long call, long first, long second, long third, | ||
1473 | break; | 1584 | break; |
1474 | 1585 | ||
1475 | case IPCOP_msgsnd: | 1586 | case IPCOP_msgsnd: |
1476 | - ret = get_errno(msgsnd(first, (struct msgbuf *) ptr, second, third)); | 1587 | + ret = do_msgsnd(first, ptr, second, third); |
1477 | break; | 1588 | break; |
1478 | 1589 | ||
1479 | case IPCOP_msgctl: | 1590 | case IPCOP_msgctl: |
1480 | - ret = get_errno(msgctl(first, second, (struct msqid_ds *) ptr)); | 1591 | + ret = do_msgctl(first, second, ptr); |
1481 | break; | 1592 | break; |
1482 | 1593 | ||
1483 | case IPCOP_msgrcv: | 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 | break; | 1608 | break; |
1498 | 1609 | ||
1499 | case IPCOP_shmat: | 1610 | case IPCOP_shmat: |