some shm and socket work
PATCH 1/1 some shm and socket work
Hi,
This patch has been coded by Paul McKerras <[email protected]>. It adds SHM basic and some socketopt stuff.
syscall.c +123 -3
@@ -41,8 +41,10 @@#include <sys/uio.h> #include <sys/poll.h> #include <sys/times.h> +#include <sys/shm.h> #include <utime.h> //#include <sys/user.h> +#include <netinet/ip.h> #include <netinet/tcp.h> #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
syscall_defs.h +13 -0
@@ -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
Signature · 4 lines
Guillaume Morin <[email protected]> I love you, I love you like a chocolate cake, like the trains, like the sea. See me loving you, please. (Dionysos)