2
0
Fork 0

Added spx local X interface.

This commit is contained in:
mike 1994-03-04 15:11:17 +00:00
parent a16c86001b
commit 2eab4322f6
11 changed files with 273 additions and 37 deletions

17
DEVICES Normal file
View file

@ -0,0 +1,17 @@
The interfaces to some subsystems occur at the device layer and thus
you need to create some device files:
/dev/socksys - interface for STREAMS based TCP/IP applications
# mknod /dev/socksys c 30 0
/dev/X0R - server side of SVR local X interface (see comments in TECH)
# ln -s /dev/null /dev/X0R
/dev/spx - client side of SVR local X interface (see comments in TECH)
# mknod /dev/spx c 30 1

View file

@ -1,7 +1,7 @@
#
# Makefile for the iBCS emulator files
#
# $Id: Makefile,v 1.4 1994/03/03 11:36:07 mike Exp $
# $Id: Makefile,v 1.5 1994/03/04 15:09:06 mike Exp $
# $Source: /nfs4/sophia/home/mjagdis/src/ibcs.cvs/ibcs/Makefile,v $
#
# Note! Dependencies are done automagically by 'make dep', which also
@ -41,8 +41,6 @@ SOCKSYS_MAJOR=30
# the trace log. (This only makes sense if IBCS_TRACE
# is also defined)
#
# -DSOCKSYS_DEBUG Give some useful(?) information from the socksys
# driver.
OPTIONS=-DIBCS_TRACE -DVERBOSE_ERRORS
# END CONFIGURATION SECTION
@ -69,7 +67,7 @@ include /usr/src/linux/.config
OBJS = binfmt_coff.o binfmt_elf.o map.o coff.o ioctl.o ipc.o mmap.o open.o \
socket.o poll.o signal.o stat.o sysconf.o sysfs.o sysi86.o socksys.o \
ulimit.o wysev386.o wysev386i.o xnx.o xstat.o
ulimit.o wysev386.o wysev386i.o xnx.o xstat.o stream.o
ifdef CONFIG_BINFMT_IBCS

32
Patches/spxkern.patch Normal file
View file

@ -0,0 +1,32 @@
--- linux/net/socket.c.old Thu Mar 3 17:07:39 1994
+++ linux/net/socket.c Thu Mar 3 15:13:21 1994
@@ -424,7 +424,7 @@
* Perform the socket system call. we locate the appropriate
* family, then create a fresh socket.
*/
-static int
+int
sock_socket(int family, int type, int protocol)
{
int i, fd;
@@ -635,7 +635,7 @@
/* Attempt to connect to a socket with the server address. */
-static int
+int
sock_connect(int fd, struct sockaddr *uservaddr, int addrlen)
{
struct socket *sock;
--- linux/include/linux/sockfunc.h.old Thu Mar 3 17:08:14 1994
+++ linux/include/linux/sockfunc.h Thu Mar 3 15:14:12 1994
@@ -18,6 +18,9 @@
extern int sock_getsockopt(int fd, int level, int optname, char *optval, int optlen);
extern int sock_setsockopt(int fd, int level, int optname, char *optval, int optlen);
+extern int sock_socket(int family, int type, int protocol);
+extern int sock_connect(int fd, struct sockaddr *uservaddr, int addrlen);
+
extern struct socket * socki_lookup(struct inode *inode);
#endif /* __KERNEL__ */

22
TECH Normal file
View file

@ -0,0 +1,22 @@
** Local X interface
The local X interface is simplistic. It assumes only one local X server
exists and assumes that the pathname of the Unix domain socket for
local connections is always /tmp/.X11-unix/X0.
The SCO code opens both /dev/X0R and /dev/spx, writes a single byte
to /dev/X0R, reads a message from /dev/X0R with getmsg then writes this
message to /dev/spx with putmsg and closes /dev/X0R. This establishes
the /dev/spx file descriptor as a connection to the X server listening
on /dev/X0R.
We ignore all activity on the /dev/X0R device (hence it is a link to
/dev/null), getmsg and putmsg are stubbed so don't do anything and opens
on the /dev/spx simply replace the open inode with a socket connected
to the X server's Unix domain socket.
At some point in the future we will implement a simple minded /dev/X*
driver that returns some form of id via the getmsg which can then be
passed to /dev/spx with putmsg and which will allow /dev/spx to connect
to the relevant X server. This will only happen if someone actually
*needs* multiple local X servers...

View file

@ -1,7 +1,7 @@
#
# Makefile for the iBCS emulator files
#
# $Id: Makefile,v 1.4 1994/03/03 11:36:07 mike Exp $
# $Id: Makefile,v 1.5 1994/03/04 15:09:06 mike Exp $
# $Source: /nfs4/sophia/home/mjagdis/src/ibcs.cvs/ibcs/iBCSemul/Makefile,v $
#
# Note! Dependencies are done automagically by 'make dep', which also
@ -41,8 +41,6 @@ SOCKSYS_MAJOR=30
# the trace log. (This only makes sense if IBCS_TRACE
# is also defined)
#
# -DSOCKSYS_DEBUG Give some useful(?) information from the socksys
# driver.
OPTIONS=-DIBCS_TRACE -DVERBOSE_ERRORS
# END CONFIGURATION SECTION
@ -69,7 +67,7 @@ include /usr/src/linux/.config
OBJS = binfmt_coff.o binfmt_elf.o map.o coff.o ioctl.o ipc.o mmap.o open.o \
socket.o poll.o signal.o stat.o sysconf.o sysfs.o sysi86.o socksys.o \
ulimit.o wysev386.o wysev386i.o xnx.o xstat.o
ulimit.o wysev386.o wysev386i.o xnx.o xstat.o stream.o
ifdef CONFIG_BINFMT_IBCS

View file

@ -8,7 +8,7 @@
* to resolve a syscall or when changing trace settings.
* Careful!
*
* $Id: callmap.inc,v 1.4 1994/03/03 11:36:08 mike Exp $
* $Id: callmap.inc,v 1.5 1994/03/04 15:09:08 mike Exp $
* $Source: /nfs4/sophia/home/mjagdis/src/ibcs.cvs/ibcs/iBCSemul/maps/callmap.inc,v $
*/
@ -140,7 +140,7 @@ static IBCS_func XNX_func_0x20[] = {
{ xnx_execseg, 2 ITR(1, "execseg", "xd") }, /* 33 */
{ xnx_unexecseg, 1 ITR(1, "unexecseg", "x") }, /* 34 */
{ 0, Ukn ITR(1, "?", "") }, /* 35 */
{ ibcs_select, Spl ITR(1, "select", "dxxxx")}, /* 36 */
{ ibcs_select, Spl ITR(0, "select", "dxxxx")}, /* 36 */
{ xnx_eaccess, 2 ITR(1, "eaccess", "so") }, /* 37 */
{ xnx_paccess, 5 ITR(1, "paccess", "dddds")},/* 38 */
{ xnx_sigaction, 3 ITR(1, "sigaction", "dxx") } /* 39 */
@ -287,8 +287,8 @@ static IBCS_func iBCS_func_0x50[] = {
{ 0, Ukn ITR(1, "libattach", "") }, /* 82 */
{ 0, Ukn ITR(1, "libdetach", "") }, /* 83 */
{ ibcs_sysfs, Spl ITR(0, "sysfs", "dxx") }, /* 84 */
{ 0, 4 ITR(1, "getmsg", "dxxx") }, /* 85 */
{ 0, 4 ITR(1, "putmsg", "dxxd") }, /* 86 */
{ ibcs_getmsg, 4 ITR(1, "getmsg", "dxxx") }, /* 85 */
{ ibcs_putmsg, 4 ITR(1, "putmsg", "dxxd") }, /* 86 */
{ ibcs_poll, 3 ITR(0, "poll", "xdd") } /* 87 */
};
static IBCS_func iBCS_func_0x58[] = {

View file

@ -3,7 +3,7 @@
*
* Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk)
*
* $Id: socksys.c,v 1.5 1994/03/03 11:36:15 mike Exp $
* $Id: socksys.c,v 1.6 1994/03/04 15:09:10 mike Exp $
* $Source: /nfs4/sophia/home/mjagdis/src/ibcs.cvs/ibcs/iBCSemul/socksys.c,v $
*/
@ -24,6 +24,7 @@
#include <linux/signal.h>
#include <linux/socket.h>
#include <linux/sockfunc.h>
#include <linux/un.h>
#include <linux/utsname.h>
#include <linux/time.h>
#include <linux/termios.h>
@ -43,17 +44,15 @@
#include "socksys.h"
/* socksys_fops defines the file operations that can be applied to the
* /dev/socksys device. socksys_socket_fops defines the file operations
* that can be applied to sockets themselves.
*/
static int socksys_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg);
static int socksys_open(struct inode *ino, struct file *filep);
static void socksys_close(struct inode *ino, struct file *filep);
/* socksys_fops defines the file operations that can be applied to the
* /dev/socksys device.
*/
static struct file_operations socksys_fops = {
NULL, /* lseek */
NULL, /* read */
@ -67,6 +66,9 @@ static struct file_operations socksys_fops = {
NULL /* fsync */
};
/* socksys_socket_fops defines the file operations
* that can be applied to sockets themselves.
*/
static struct file_operations socksys_socket_fops = {
sock_lseek, /* lseek */
sock_read, /* read */
@ -89,8 +91,8 @@ socksys_syscall(struct inode *inode, struct file *file, int *sp)
cmd = (int)get_fs_long(sp);
sp++;
#ifdef SOCKSYS_DEBUG
{
#ifdef IBCS_TRACE
if (ibcs_trace & TRACE_SOCKSYS) {
int a0, a1, a2, a3, a4, a5;
static char *cmd_map[] = {
"", "accept", "bind", "connect", "getpeername",
@ -287,7 +289,7 @@ socksys_ioctl(struct inode *inode, struct file *file,
error = sock_ioctl(inode, file, TIOCINQ, arg);
#ifdef IBCS_TRACE
if (!error)
if (!error && (ibcs_trace & TRACE_SOCKSYS))
printk(KERN_DEBUG
"iBCS: socksys FIONREAD found %lu bytes ready\n",
(unsigned long)get_fs_long(arg));
@ -419,26 +421,104 @@ socksys_open(struct inode *ino, struct file *filep)
#ifndef CONFIG_BINFMT_IBCS
MOD_INC_USE_COUNT;
#endif
#ifdef SOCKSYS_DEBUG
printk(KERN_DEBUG "socksys: [%d] %lx opening\n",
current->pid, (unsigned long)filep);
#ifdef IBCS_TRACE
if (ibcs_trace & TRACE_SOCKSYS)
printk(KERN_DEBUG "socksys: [%d] %lx opening\n",
current->pid, (unsigned long)filep);
#endif
/* Minor = 0 is the socksys device itself. No special handling
* will be needed as it is controlled by the application
* via ioctls.
*/
if (MINOR(ino->i_rdev) == 0)
return 0;
/* Minor = 1 is the spx device. This is the client side of a
* streams pipe to the X server. Under SCO and friends
* the library code messes around setting the connection
* up itself. We do it ourselves - this means we don't
* need to worry about the implementation of the server
* side (/dev/X0R - which must exist but can be a link
* to /dev/null) nor do we need to actually implement
* getmsg/putmsg.
*/
{ /* SPX */
int fd, err, old_fs;
struct sockaddr_un Xaddr = {
AF_UNIX, "/tmp/.X11-unix/X0"
};
#ifdef IBCS_TRACE
if (ibcs_trace & TRACE_SOCKSYS)
printk(KERN_DEBUG "SPX: [%d] %lx opening\n",
current->pid, (unsigned long)filep);
#endif
/* Grab a socket. */
#ifdef IBCS_TRACE
if (ibcs_trace & TRACE_SOCKSYS)
printk(KERN_DEBUG "SPX: [%d] %lx get a Unix domain socket\n",
current->pid, (unsigned long)filep);
#endif
fd = sock_socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0) {
#ifndef CONFIG_BINFMT_IBCS
MOD_DEC_USE_COUNT;
#endif
return fd;
}
/* Connect the socket to X. */
#ifdef IBCS_TRACE
if (ibcs_trace & TRACE_SOCKSYS)
printk(KERN_DEBUG "SPX: [%d] %lx connect to /tmp/X11-unix/X0\n",
current->pid, (unsigned long)filep);
#endif
old_fs = get_fs();
set_fs (get_ds());
err = sock_connect(fd, (struct sockaddr *)&Xaddr, sizeof(struct sockaddr_un));
set_fs(old_fs);
if (err) {
sys_close(fd);
#ifndef CONFIG_BINFMT_IBCS
MOD_DEC_USE_COUNT;
#endif
return err;
}
/* Release the inode we were given, replace with the socket
* inode, redirect operations to our emulation handlers then
* clear down the descriptor used for the socket.
*/
#ifdef IBCS_TRACE
if (ibcs_trace & TRACE_SOCKSYS)
printk(KERN_DEBUG "SPX: [%d] %lx swap inodes\n",
current->pid, (unsigned long)filep);
#endif
iput(ino);
filep->f_inode = current->filp[fd]->f_inode;
filep->f_op = &socksys_socket_fops;
if (--current->filp[fd]->f_count == 0)
current->filp[fd] = NULL;
return 0;
} /* SPX */
}
static void
socksys_close(struct inode *ino, struct file *filep)
{
#ifndef CONFIG_BINFMT_IBCS
MOD_DEC_USE_COUNT;
#endif
if (ino->i_socket)
sock_close(ino, filep);
#ifdef SOCKSYS_DEBUG
printk(KERN_DEBUG "socksys: [%d] %lx closed\n",
current->pid, (unsigned long)filep);
#ifdef IBCS_TRACE
if (ibcs_trace & TRACE_SOCKSYS)
printk(KERN_DEBUG "socksys: [%d] %lx closed\n",
current->pid, (unsigned long)filep);
#endif
#ifndef CONFIG_BINFMT_IBCS
MOD_DEC_USE_COUNT;
#endif
}

62
iBCSemul/stream.c Normal file
View file

@ -0,0 +1,62 @@
/*
* linux/ibcs/stream.c
*
* Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk)
*
* $Id: stream.c,v 1.1 1994/03/04 15:09:10 mike Exp $
* $Source: /nfs4/sophia/home/mjagdis/src/ibcs.cvs/ibcs/iBCSemul/stream.c,v $
*/
#include <asm/segment.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <ibcs/ibcs.h>
#include <ibcs/stream.h>
#ifdef IBCS_TRACE
#include <ibcs/trace.h>
#endif
/* We LIE and pretend that getmsg and putmsg succeeded. This is necessary
* for the emulation of the /dev/spx interface to the local X server.
* If you plan on implmenting these tread very carefully...
*/
int
ibcs_getmsg(int fd, struct strbuf *ctlptr, struct strbuf *dataptr, int *flags)
{
#ifdef IBCS_TRACE
if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace) {
printk(KERN_DEBUG "iBCS: getmsg from %d, ctl=%lx[%ld], data=%lx[%ld], flags=%lx\n",
fd,
(unsigned long)(ctlptr ? get_fs_long(&ctlptr->buf) : 0L),
(unsigned long)(ctlptr ? get_fs_long(&ctlptr->maxlen) : 0L),
(unsigned long)(dataptr ? get_fs_long(&dataptr->buf) : 0L),
(unsigned long)(dataptr ? get_fs_long(&dataptr->maxlen) : 0L),
(unsigned long)get_fs_long(flags));
}
#endif
return 0;
}
int
ibcs_putmsg(int fd, struct strbuf *ctlptr, struct strbuf *dataptr, int *flags)
{
#ifdef IBCS_TRACE
if ((ibcs_trace & TRACE_API) || ibcs_func_p->trace) {
printk(KERN_DEBUG "iBCS: putmsg from %d, ctl=%lx[%ld], data=%lx[%ld], flags=%lx\n",
fd,
(unsigned long)(ctlptr ? get_fs_long(&ctlptr->buf) : 0L),
(unsigned long)(ctlptr ? get_fs_long(&ctlptr->maxlen) : 0L),
(unsigned long)(dataptr ? get_fs_long(&dataptr->buf) : 0L),
(unsigned long)(dataptr ? get_fs_long(&dataptr->maxlen) : 0L),
(unsigned long)get_fs_long(flags));
}
#endif
return 0;
}

View file

@ -1,13 +1,15 @@
/*
* Function prototypes used by the iBCS2 emulator
*
* $Id: ibcs.h,v 1.4 1994/03/03 11:36:11 mike Exp $
* $Id: ibcs.h,v 1.5 1994/03/04 15:09:09 mike Exp $
* $Source: /nfs4/sophia/home/mjagdis/src/ibcs.cvs/ibcs/include/ibcs/ibcs.h,v $
*/
#include <linux/sys.h> /* for fn_ptr */
#include <linux/ptrace.h> /* for pt_regs */
#include <linux/signal.h>
#include <ibcs/stream.h>
/*
* the function prefix sys_... are used by linux in native mode.
* ibcs_... are emulation interfaces for routine that differ from iBCS2
@ -123,6 +125,12 @@ extern int ibcs_stat(char * filename, struct ibcs_stat * statbuf);
extern int ibcs_lstat(char * filename, struct ibcs_stat * statbuf);
extern int ibcs_fstat(unsigned int fd, struct ibcs_stat * statbuf);
/* stream.c */
extern int ibcs_getmsg(int fd, struct strbuf *ctlptr, struct strbuf *dataptr,
int *flags);
extern int ibcs_putmsg(int fd, struct strbuf *ctlptr, struct strbuf *dataptr,
int *flags);
/* sysconf.c */
extern int sys_sysconf(int name);

19
include/ibcs/stream.h Normal file
View file

@ -0,0 +1,19 @@
/*
* linux/ibcs/stream.h
*
* Copyright (C) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk)
*
* $Id: stream.h,v 1.1 1994/03/04 15:09:11 mike Exp $
* $Source: /nfs4/sophia/home/mjagdis/src/ibcs.cvs/ibcs/include/ibcs/stream.h,v $
*/
#ifndef _IBCS_STREAM_H_
#define _IBCS_STREAM_H_
struct strbuf {
int maxlen; /* size of buffer */
int len; /* number of bytes in buffer */
char *buf; /* pointer to buffer */
};
#endif

View file

@ -1,16 +1,16 @@
/*
* ibcs trace -- mask of trace values
*
* $Id: trace.h,v 1.1 1994/02/10 09:31:22 mike Exp $
* $Id: trace.h,v 1.2 1994/03/04 15:09:11 mike Exp $
* $Source: /nfs4/sophia/home/mjagdis/src/ibcs.cvs/ibcs/include/ibcs/trace.h,v $
*/
#define IBCS_TRACE 1 /* trace code support */
#define TRACE_API 0x00000001 /* all call/return values */
#define TRACE_IOCTL 0x00000002 /* all ioctl calls */
#define TRACE_IOCTL_F 0x00000004 /* ioctl calls that fail */
#define TRACE_SIGNAL 0x00000008 /* all signal calls */
#define TRACE_SIGNAL_F 0x00000010 /* signal calls that fail */
#define TRACE_SOCKSYS 0x00000020 /* socksys and spx devices */
#define TRACE_FUNC 0x10000000 /* trace this function */
extern int ibcs_trace;
IBCS_func *ibcs_func_p;
extern int ibcs_trace;
extern IBCS_func *ibcs_func_p;