Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.30) id 1Au0EL-00072Z-I0 for qemu-devel@nongnu.org; Thu, 19 Feb 2004 21:17:29 -0500 Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.30) id 1Au0Cw-0006Qc-MB for qemu-devel@nongnu.org; Thu, 19 Feb 2004 21:16:34 -0500 Received: from [62.4.22.236] (helo=bender.morinfr.org) by monty-python.gnu.org with esmtp (TLSv1:RC4-SHA:128) (Exim 4.30) id 1Au08n-00032F-Tk for qemu-devel@nongnu.org; Thu, 19 Feb 2004 21:11:46 -0500 Received: from 66-65-114-133.nyc.rr.com ([66.65.114.133] helo=localhost) by bender.morinfr.org with asmtp (TLS-1.0:RSA_ARCFOUR_SHA:16) (Exim 4.30) id 1Au07y-0001SA-3M for qemu-devel@nongnu.org; Fri, 20 Feb 2004 03:10:55 +0100 Received: from guillaum by localhost with local (Exim 4.30) id 1Au08h-0004Bo-Kk for qemu-devel@nongnu.org; Thu, 19 Feb 2004 21:11:39 -0500 Date: Thu, 19 Feb 2004 21:11:39 -0500 From: Guillaume Morin Message-ID: <20040220021137.GC3364@siri.morinfr.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Subject: [Qemu-devel] [PATCH] some shm and socket work Reply-To: qemu-devel@nongnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Hi, This patch has been coded by Paul McKerras . It adds SHM basic and some socketopt stuff. diff -ur qemu-0.5.2/syscall.c qemu-0.5.2-dev/syscall.c --- qemu-0.5.2/syscall.c 2004-01-25 10:50:02.000000000 -0500 +++ qemu-0.5.2-dev/syscall.c 2004-02-19 12:24:09.000000000 -0500 @@ -41,8 +41,10 @@ #include #include #include +#include #include //#include +#include #include #define termios host_termios @@ -346,7 +348,7 @@ target_long v; if (target_fds) { - nw = n / TARGET_LONG_BITS; + nw = (n + TARGET_LONG_BITS - 1) / TARGET_LONG_BITS; k = 0; for(i = 0;i < nw; i++) { v = 0; @@ -551,6 +553,9 @@ static long do_setsockopt(int sockfd, int level, int optname, void *optval, socklen_t optlen) { + if ((unsigned long) optval < 0x1000) + return -EFAULT; + if (level == SOL_TCP) { /* TCP options all take an 'int' value. */ int val; @@ -562,7 +567,18 @@ return get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); } - else if (level != SOL_SOCKET) { + if (level == SOL_IP && optname == IP_HDRINCL) { + int val = 0; + + if (optlen >= sizeof(uint32_t)) + val = tswap32(*(uint32_t *)optval); + else if (optlen >= 1) + val = *(unsigned char *)optval; + + return get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); + } + + if (level != SOL_SOCKET) { gemu_log("Unsupported setsockopt level: %d\n", level); return -ENOSYS; } @@ -604,6 +620,31 @@ static long do_getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen) { + int32_t lv, result; + + if (level == SOL_SOCKET) { + lv = sizeof(int32_t); + switch (optname) { + case SO_LINGER: + case SO_RCVTIMEO: + case SO_SNDTIMEO: + case SO_PEERCRED: + case SO_PEERNAME: + /* These don't just return a single integer */ + goto unimp; + } + if (*optlen < 0) + return -EINVAL; + if (getsockopt(sockfd, level, optname, &result, &lv) == -1) + return -errno; + result = tswap32(result); + if (lv > *optlen) + lv = *optlen; + memcpy(optval, &result, lv); + return 0; + } + + unimp: gemu_log("getsockopt not yet supported\n"); return -ENOSYS; } @@ -844,6 +885,84 @@ return ret; } + +#define N_SHM_REGIONS 32 +static struct shm_region { + uint32_t start; + uint32_t size; +} shm_regions[N_SHM_REGIONS]; + +static long do_ipc(long call, long first, long second, long third, + long ptr, long fifth) +{ + int version; + long ret = 0; + long raddr; + struct shmid_ds shm_info; + int i; + + version = call >> 16; + call &= 0xffff; + + switch (call) { + case IPCOP_shmat: + /* SHM_* flags are the same on all linux platforms */ + raddr = (long) shmat(first, (void *) ptr, second); + if (raddr == -1) { + ret = -errno; + break; + } + + /* find out the length of the shared memory segment */ + if (shmctl(first, IPC_STAT, &shm_info) == -1) { + /* can't get length, bail out */ + shmdt((void *) raddr); + ret = -errno; + break; + } + page_set_flags(raddr, raddr + shm_info.shm_segsz, + PAGE_VALID + PAGE_READ + + ((second & SHM_RDONLY)? 0: PAGE_WRITE)); + for (i = 0; i < N_SHM_REGIONS; ++i) { + if (shm_regions[i].start == 0) { + shm_regions[i].start = raddr; + shm_regions[i].size = shm_info.shm_segsz; + break; + } + } + + *(uint32_t *)third = tswap32(raddr); + break; + + case IPCOP_shmdt: + for (i = 0; i < N_SHM_REGIONS; ++i) { + if (shm_regions[i].start == ptr) { + shm_regions[i].start = 0; + page_set_flags(ptr, shm_regions[i].size, 0); + break; + } + } + ret = get_errno(shmdt((void *) ptr)); + break; + + case IPCOP_shmget: + /* IPC_* flag values are the same on all linux platforms */ + ret = get_errno(shmget(first, second, third)); + break; + + case IPCOP_shmctl: + /* IPC_* and SHM_* command values are the same on all linux platforms */ + ret = -ENOSYS; /* XXX lazy */ + break; + + default: + gemu_log("Unsupported ipc call: %ld (version %d)\n", call, version); + ret = -ENOSYS; + break; + } + return ret; +} + /* kernel structure types definitions */ #define IFNAMSIZ 16 @@ -2224,7 +2343,8 @@ case TARGET_NR_sysinfo: goto unimplemented; case TARGET_NR_ipc: - goto unimplemented; + ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6); + break; case TARGET_NR_fsync: ret = get_errno(fsync(arg1)); break; Seulement dans qemu-0.5.2-dev/: syscall.c.orig diff -ur qemu-0.5.2/syscall_defs.h qemu-0.5.2-dev/syscall_defs.h --- qemu-0.5.2/syscall_defs.h 2004-01-25 10:50:02.000000000 -0500 +++ qemu-0.5.2-dev/syscall_defs.h 2004-02-19 12:24:09.000000000 -0500 @@ -24,6 +24,19 @@ #define SOCKOP_sendmsg 16 #define SOCKOP_recvmsg 17 +#define IPCOP_semop 1 +#define IPCOP_semget 2 +#define IPCOP_semctl 3 +#define IPCOP_semtimedop 4 +#define IPCOP_msgsnd 11 +#define IPCOP_msgrcv 12 +#define IPCOP_msgget 13 +#define IPCOP_msgctl 14 +#define IPCOP_shmat 21 +#define IPCOP_shmdt 22 +#define IPCOP_shmget 23 +#define IPCOP_shmctl 24 + /* * The following is for compatibility across the various Linux * platforms. The i386 ioctl numbering scheme doesn't really enforce Guillaume. PS: Please cc'me if you reply -- Guillaume Morin I love you, I love you like a chocolate cake, like the trains, like the sea. See me loving you, please. (Dionysos)