--- linux-user/syscall.c 2005-04-26 10:01:22.771568612 +0300 +++ linux-user/syscall.c 2005-04-26 10:03:21.850447511 +0300 @@ -41,7 +41,10 @@ #include #include #include +#include #include +#include +#include #include #include //#include @@ -906,7 +909,6 @@ return ret; } - #define N_SHM_REGIONS 32 static struct shm_region { @@ -914,6 +916,14 @@ uint32_t size; } shm_regions[N_SHM_REGIONS]; +union semunion { + int val; /* value for SETVAL */ + struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ + unsigned short *array; /* array for GETALL, SETALL */ + /* Linux specific part: */ + struct seminfo *__buf; /* buffer for IPC_INFO */ +}; + static long do_ipc(long call, long first, long second, long third, long ptr, long fifth) { @@ -927,6 +937,53 @@ call &= 0xffff; switch (call) { + case IPCOP_semop: + ret = get_errno(semop(first,(struct sembuf *) ptr, second)); + break; + + case IPCOP_semget: + ret = get_errno(semget(first, second, third)); + break; + + case IPCOP_semctl: + /* We use syscall directly to avoid c-librarys __IPC_64 hacks */ + ret = syscall(__NR_ipc, IPCOP_semctl, first, + second, third, ptr); + break; + + case IPCOP_semtimedop: + gemu_log("Unsupported ipc call: %ld (version %d)\n", call, version); + ret = -ENOSYS; + break; + + case IPCOP_msgget: + ret = get_errno(msgget(first, second)); + break; + + case IPCOP_msgsnd: + ret = get_errno(msgsnd(first, (struct msgbuf *) ptr, second, third)); + break; + + case IPCOP_msgctl: + ret = get_errno(msgctl(first, second, (struct msqid_ds *) ptr)); + break; + + case IPCOP_msgrcv: + { + struct ipc_kludge + { + void *__unbounded msgp; + long int msgtyp; + }; + + struct ipc_kludge *foo = (struct ipc_kludge *) ptr; + struct msgbuf *msgp = (struct msgbuf *) foo->msgp; + + ret = get_errno(msgrcv(first, msgp, second, 0, third)); + + } + break; + case IPCOP_shmat: /* SHM_* flags are the same on all linux platforms */ ret = get_errno((long) shmat(first, (void *) ptr, second)); @@ -955,6 +1012,7 @@ return -EFAULT; ret = 0; break; + case IPCOP_shmdt: for (i = 0; i < N_SHM_REGIONS; ++i) { if (shm_regions[i].start == ptr) { @@ -980,15 +1038,17 @@ ret = get_errno(shmctl(first, second, NULL)); break; default: - goto unimplemented; + ret = get_errno(shmctl(first, second, (struct shmid_ds *) ptr)); + break; } break; + default: - unimplemented: gemu_log("Unsupported ipc call: %ld (version %d)\n", call, version); ret = -ENOSYS; break; } + return ret; }