diff -urNp 36/arch/um/Makefile 40/arch/um/Makefile --- 36/arch/um/Makefile Tue Jul 16 17:07:52 2002 +++ 40/arch/um/Makefile Tue Jul 16 17:08:05 2002 @@ -1,8 +1,10 @@ ARCH_DIR = arch/um +OS := $(shell uname -s) -include arch/$(ARCH)/Makefile-$(SUBARCH) +include $(ARCH_DIR)/Makefile-$(SUBARCH) +include $(ARCH_DIR)/Makefile-os-$(OS) -EXTRAVERSION := $(EXTRAVERSION)-36um +EXTRAVERSION := $(EXTRAVERSION)-40um include/linux/version.h: arch/$(ARCH)/Makefile # Recalculate MODLIB to reflect the EXTRAVERSION changes (via KERNELRELEASE) @@ -29,13 +31,13 @@ LINK_PROFILE = $(PROFILE) -Wl,--wrap,__m endif ARCH_SUBDIRS = $(ARCH_DIR)/fs $(ARCH_DIR)/drivers $(ARCH_DIR)/kernel \ - $(ARCH_DIR)/sys-$(SUBARCH) + $(ARCH_DIR)/sys-$(SUBARCH) $(ARCH_DIR)/os-$(OS) SUBDIRS += $(ARCH_SUBDIRS) LIBS += $(shell [ -e $(ARCH_DIR)/fs/fs.o ] && echo $(ARCH_DIR)/fs/fs.o) \ - $(ARCH_DIR)/kernel/um.o $(ARCH_DIR)/drivers/um_drivers.o \ - $(ARCH_DIR)/sys-$(SUBARCH)/sys.o + $(ARCH_DIR)/kernel/um.o $(ARCH_DIR)/drivers/drivers.o \ + $(ARCH_DIR)/sys-$(SUBARCH)/sys.o $(ARCH_DIR)/os/os.o ifeq ($(CONFIG_PT_PROXY), y) SUBDIRS += $(ARCH_DIR)/ptproxy @@ -67,7 +69,8 @@ SYMLINK_HEADERS = include/asm-um/archpar include/asm-um/sigcontext.h include/asm-um/processor.h \ include/asm-um/ptrace.h include/asm-um/arch-signal.h -ARCH_SYMLINKS = include/asm-um/arch arch/um/include/sysdep $(SYMLINK_HEADERS) +ARCH_SYMLINKS = include/asm-um/arch arch/um/include/sysdep arch/um/os \ + $(SYMLINK_HEADERS) GEN_HEADERS = $(ARCH_DIR)/include/task.h @@ -120,6 +123,9 @@ include/asm-um/arch: arch/um/include/sysdep: cd $(TOPDIR)/arch/um/include && ln -sf sysdep-$(SUBARCH) sysdep +arch/um/os: + cd $(ARCH_DIR) && ln -sf os-$(OS) os + $(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task $< > $@ @@ -127,4 +133,4 @@ $(ARCH_DIR)/util/mk_task : $(ARCH_DIR)/u $(ARCH_DIR)/util/mk_task_kern.c $(MAKE) $(MFLAGS) -C $(ARCH_DIR)/util all -export SUBARCH USER_CFLAGS +export SUBARCH USER_CFLAGS OS diff -urNp 36/arch/um/Makefile-os-Linux 40/arch/um/Makefile-os-Linux --- 36/arch/um/Makefile-os-Linux Thu Jan 1 01:00:00 1970 +++ 40/arch/um/Makefile-os-Linux Tue Jul 16 17:08:05 2002 @@ -0,0 +1,7 @@ +# +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com) +# Licensed under the GPL +# + +SUBDIRS += $(ARCH_DIR)/os-$(OS)/drivers +LIBS += $(ARCH_DIR)/os-$(OS)/drivers/drivers.o diff -urNp 36/arch/um/config.release 40/arch/um/config.release --- 36/arch/um/config.release Tue Jul 16 17:07:52 2002 +++ 40/arch/um/config.release Tue Jul 16 17:08:05 2002 @@ -36,6 +36,8 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_CON_ZERO_CHAN="fd:0,fd:1" CONFIG_CON_CHAN="xterm" CONFIG_SSL_CHAN="pty" +CONFIG_NEST_LEVEL=0 +CONFIG_KERNEL_HALF_GIGS=1 # # Loadable module support @@ -57,6 +59,8 @@ CONFIG_BLK_DEV_INITRD=y CONFIG_UML_SOUND=y CONFIG_SOUND=y CONFIG_HOSTAUDIO=y +# CONFIG_UML_WATCHDOG is not set +# CONFIG_TTY_LOG is not set CONFIG_FD_CHAN=y # CONFIG_NULL_CHAN is not set CONFIG_PORT_CHAN=y @@ -137,12 +141,19 @@ CONFIG_TUN=y # # Ethernet (1000 Mbit) # -# CONFIG_ACENIC_OMIT_TIGON_I is not set +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set CONFIG_PLIP=m CONFIG_PPP=m CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set # CONFIG_PPP_ASYNC is not set CONFIG_PPP_SYNC_TTY=m CONFIG_PPP_DEFLATE=m @@ -163,6 +174,7 @@ CONFIG_SLIP_SMART=y # # CONFIG_TR is not set # CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set CONFIG_SHAPER=m # @@ -192,6 +204,8 @@ CONFIG_MSDOS_FS=y CONFIG_UMSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_EFS_FS=m +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set CONFIG_CRAMFS=m CONFIG_TMPFS=y CONFIG_RAMFS=m @@ -201,6 +215,7 @@ CONFIG_ISO9660_FS=y CONFIG_MINIX_FS=m CONFIG_VXFS_FS=m # CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set CONFIG_HPFS_FS=m CONFIG_PROC_FS=y CONFIG_DEVFS_FS=y @@ -224,6 +239,7 @@ CONFIG_UFS_FS=m # CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_ROOT_NFS is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y CONFIG_SUNRPC=y @@ -231,6 +247,14 @@ CONFIG_LOCKD=y CONFIG_LOCKD_V4=y # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set # CONFIG_ZISOFS_FS is not set CONFIG_ZLIB_FS_INFLATE=m @@ -288,6 +312,13 @@ CONFIG_NLS_DEFAULT="iso8859-1" # Multi-device support (RAID and LVM) # # CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set # # Memory Technology Devices (MTD) @@ -299,3 +330,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUGSYM is not set +# CONFIG_PT_PROXY is not set +# CONFIG_GPROF is not set +# CONFIG_GCOV is not set diff -urNp 36/arch/um/drivers/Makefile 40/arch/um/drivers/Makefile --- 36/arch/um/drivers/Makefile Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/Makefile Tue Jul 16 17:08:05 2002 @@ -3,45 +3,38 @@ # Licensed under the GPL # -OBJ := um_drivers.o +O_TARGET = drivers.o CHAN_OBJS = chan_kern.o chan_user.o line.o -OBJS-y = -OBJS-$(CONFIG_SSL) += ssl.o -OBJS-$(CONFIG_UML_NET_SLIP) += slip_kern.o slip_user.o -OBJS-$(CONFIG_UML_NET_ETHERTAP) += ethertap_kern.o ethertap_user.o -OBJS-$(CONFIG_UML_NET_TUNTAP) += tuntap_kern.o tuntap_user.o -OBJS-$(CONFIG_UML_NET_DAEMON) += daemon_kern.o daemon_user.o -OBJS-$(CONFIG_UML_NET_MCAST) += mcast_user.o mcast_kern.o -OBJS-$(CONFIG_UML_NET) += net_kern.o net_user.o -OBJS-$(CONFIG_MCONSOLE) += mconsole_kern.o mconsole_user.o -OBJS-$(CONFIG_MMAPPER) += mmapper_kern.o -OBJS-$(CONFIG_BLK_DEV_UBD) += ubd.o ubd_user.o -OBJS-$(CONFIG_HOSTAUDIO) += hostaudio_kern.o hostaudio_user.o -OBJS-$(CONFIG_FD_CHAN) += fd.o -OBJS-$(CONFIG_NULL_CHAN) += null.o -OBJS-$(CONFIG_PORT_CHAN) += port.o port_kern.o -OBJS-$(CONFIG_PTY_CHAN) += pty.o -OBJS-$(CONFIG_TTY_CHAN) += tty.o -OBJS-$(CONFIG_XTERM_CHAN) += xterm.o -OBJS-$(CONFIG_UML_WATCHDOG) += harddog.o harddog_user.o +obj-y = +obj-$(CONFIG_SSL) += ssl.o +obj-$(CONFIG_UML_NET_SLIP) += slip_kern.o slip_user.o +obj-$(CONFIG_UML_NET_DAEMON) += daemon_kern.o daemon_user.o +obj-$(CONFIG_UML_NET_MCAST) += mcast_user.o mcast_kern.o +obj-$(CONFIG_UML_NET) += net_kern.o net_user.o +obj-$(CONFIG_MCONSOLE) += mconsole_kern.o mconsole_user.o +obj-$(CONFIG_MMAPPER) += mmapper_kern.o +obj-$(CONFIG_BLK_DEV_UBD) += ubd.o ubd_user.o +obj-$(CONFIG_HOSTAUDIO) += hostaudio_kern.o hostaudio_user.o +obj-$(CONFIG_FD_CHAN) += fd.o +obj-$(CONFIG_NULL_CHAN) += null.o +obj-$(CONFIG_PORT_CHAN) += port.o port_kern.o +obj-$(CONFIG_PTY_CHAN) += pty.o +obj-$(CONFIG_TTY_CHAN) += tty.o +obj-$(CONFIG_XTERM_CHAN) += xterm.o +obj-$(CONFIG_UML_WATCHDOG) += harddog.o harddog_user.o -OBJS = stdio_console.o $(OBJS-y) $(CHAN_OBJS) +obj-y += stdio_console.o $(CHAN_OBJS) -USER_OBJS = $(filter %_user.o,$(OBJS)) fd.o null.o port.o pty.o tty.o xterm.o +USER_OBJS = $(filter %_user.o,$(obj-y)) fd.o null.o port.o pty.o tty.o xterm.o -all : $(OBJ) +include $(TOPDIR)/Rules.make $(USER_OBJS) : %.o: %.c $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $< -$(OBJ): $(OBJS) $(export-objs) - rm -f $@ - $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@ - clean: - rm -f $(OBJS) $(export-objs) modules: @@ -51,4 +44,3 @@ dep: archmrproper: -include $(TOPDIR)/Rules.make diff -urNp 36/arch/um/drivers/chan_user.c 40/arch/um/drivers/chan_user.c --- 36/arch/um/drivers/chan_user.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/chan_user.c Tue Jul 16 17:08:05 2002 @@ -18,6 +18,7 @@ #include "chan_user.h" #include "user.h" #include "helper.h" +#include "os.h" void generic_close(int fd, void *unused) { @@ -155,7 +156,7 @@ static int winch_thread(void *arg) printk("winch_thread : TIOCSCTTY failed, errno = %d\n", errno); exit(1); } - if(tcsetpgrp(pty_fd, getpid()) < 0){ + if(tcsetpgrp(pty_fd, os_getpid()) < 0){ printk("winch_thread : tcsetpgrp failed, errno = %d\n", errno); exit(1); } @@ -187,9 +188,12 @@ static void tracer_winch_handler(int sig void setup_tracer_winch(void) { - if(socketpair(AF_UNIX, SOCK_STREAM, 0, tracer_winch) < 0){ - printk("setup_tracer_winch : socketpair failed, errno = %d\n", - errno); + int err; + + err = os_pipe(tracer_winch, 1); + if(err){ + printk("setup_tracer_winch : os_pipe failed, errno = %d\n", + -err); return; } signal(SIGWINCH, tracer_winch_handler); @@ -199,12 +203,13 @@ static int winch_tramp(int fd, void *dev { struct winch_data data; unsigned long stack; - int fds[2], pid, n; + int fds[2], pid, n, err; char c; - if(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0){ - printk("winch_tramp : socketpair failed, errno = %d\n", errno); - return(-errno); + err = os_pipe(fds, 1); + if(err){ + printk("winch_tramp : os_pipe failed, errno = %d\n", -err); + return(err); } data = ((struct winch_data) { pty_fd : fd, diff -urNp 36/arch/um/drivers/daemon_kern.c 40/arch/um/drivers/daemon_kern.c --- 36/arch/um/drivers/daemon_kern.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/daemon_kern.c Tue Jul 16 17:08:05 2002 @@ -105,6 +105,19 @@ int daemon_setup(char *str, struct uml_n return(0); } +static struct transport daemon_transport = { + list : LIST_HEAD_INIT(daemon_transport.list), + name : "daemon", + setup : daemon_setup +}; + +static int register_daemon(void) +{ + register_transport(&daemon_transport); + return(1); +} + +__initcall(register_daemon); /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically diff -urNp 36/arch/um/drivers/daemon_user.c 40/arch/um/drivers/daemon_user.c --- 36/arch/um/drivers/daemon_user.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/daemon_user.c Tue Jul 16 17:08:05 2002 @@ -15,6 +15,7 @@ #include "kern_util.h" #include "user_util.h" #include "user.h" +#include "os.h" #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) @@ -129,7 +130,7 @@ static void daemon_user_init(void *data, pri->ctl_addr = new_addr(pri->ctl_sock, strlen(pri->ctl_sock) + 1); name.zero = 0; - name.pid = getpid(); + name.pid = os_getpid(); gettimeofday(&tv, NULL); name.usecs = tv.tv_usec; pri->local_addr = new_addr(&name, sizeof(name)); diff -urNp 36/arch/um/drivers/etap.h 40/arch/um/drivers/etap.h --- 36/arch/um/drivers/etap.h Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/etap.h Thu Jan 1 01:00:00 1970 @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include "net_user.h" - -struct ethertap_data { - char *dev_name; - char *gate_addr; - int data_fd; - int control_fd; - void *dev; -}; - -extern struct net_user_info ethertap_user_info; - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff -urNp 36/arch/um/drivers/etap_kern.h 40/arch/um/drivers/etap_kern.h --- 36/arch/um/drivers/etap_kern.h Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/etap_kern.h Thu Jan 1 01:00:00 1970 @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __UM_ETHERTAP_KERN_H -#define __UM_ETHERTAP_KERN_H - -#include "net_kern.h" - -extern int ethertap_setup(char *arg, struct uml_net *dev); - -#endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff -urNp 36/arch/um/drivers/ethertap_kern.c 40/arch/um/drivers/ethertap_kern.c --- 36/arch/um/drivers/ethertap_kern.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/ethertap_kern.c Thu Jan 1 01:00:00 1970 @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and - * James Leu (jleu@mindspring.net). - * Copyright (C) 2001 by various other people who didn't put their name here. - * Licensed under the GPL. - */ - -#include "linux/init.h" -#include "linux/netdevice.h" -#include "linux/etherdevice.h" -#include "net_kern.h" -#include "net_user.h" -#include "etap.h" -#include "etap_kern.h" - -struct ethertap_setup { - char *dev_name; - char *gate_addr; -}; - -struct ethertap_setup ethertap_priv[MAX_UML_NETDEV] = { - [ 0 ... MAX_UML_NETDEV - 1 ] = - { - dev_name: NULL, - gate_addr: NULL, - } -}; - -struct net_device *etap_init(int private_size, int index) -{ - struct net_device *dev; - struct uml_net_private *pri; - struct ethertap_data *epri; - - dev = init_etherdev(NULL, private_size); - if(dev == NULL) return(NULL); - pri = dev->priv; - epri = (struct ethertap_data *) pri->user; - epri->dev_name = ethertap_priv[index].dev_name; - epri->gate_addr = ethertap_priv[index].gate_addr; - printk("ethertap backend - %s", epri->dev_name); - if(epri->gate_addr != NULL) - printk(", IP = %s", epri->gate_addr); - printk("\n"); - epri->data_fd = -1; - epri->control_fd = -1; - return(dev); -} - -static unsigned short etap_protocol(struct sk_buff *skb) -{ - return(eth_type_trans(skb, skb->dev)); -} - -static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) -{ - int len; - - *skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP); - if(*skb == NULL) return(-ENOMEM); - len = net_recvfrom(fd, (*skb)->mac.raw, - (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP); - if(len <= 0) return(len); - skb_pull(*skb, 2); - len -= 2; - return(len); -} - -static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) -{ - if(skb_headroom(*skb) < 2){ - struct sk_buff *skb2; - - skb2 = skb_realloc_headroom(*skb, 2); - dev_kfree_skb(*skb); - if (skb2 == NULL) return(-ENOMEM); - *skb = skb2; - } - skb_push(*skb, 2); - return(net_send(fd, (*skb)->data, (*skb)->len)); -} - -struct net_kern_info ethertap_kern_info = { - init: etap_init, - protocol: etap_protocol, - read: etap_read, - write: etap_write, -}; - -static int ethertap_count = 0; - -int ethertap_setup(char *str, struct uml_net *dev) -{ - struct ethertap_setup *pri; - int err; - - pri = ðertap_priv[ethertap_count]; - err = tap_setup_common(str, "ethertap", &pri->dev_name, dev->mac, - &dev->have_mac, &pri->gate_addr); - if(err) return(err); - if(pri->dev_name == NULL){ - printk("ethertap_setup : Missing tap device name\n"); - return(1); - } - - dev->user = ðertap_user_info; - dev->kern = ðertap_kern_info; - dev->private_size = sizeof(struct ethertap_data); - dev->transport_index = ethertap_count++; - return(0); -} - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff -urNp 36/arch/um/drivers/ethertap_user.c 40/arch/um/drivers/ethertap_user.c --- 36/arch/um/drivers/ethertap_user.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/ethertap_user.c Thu Jan 1 01:00:00 1970 @@ -1,235 +0,0 @@ -/* - * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and - * James Leu (jleu@mindspring.net). - * Copyright (C) 2001 by various other people who didn't put their name here. - * Licensed under the GPL. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "user.h" -#include "kern_util.h" -#include "net_user.h" -#include "etap.h" -#include "helper.h" - -#define MAX_PACKET ETH_MAX_PACKET - -void etap_user_init(void *data, void *dev) -{ - struct ethertap_data *pri = data; - - pri->dev = dev; -} - -struct addr_change { - enum { ADD_ADDR, DEL_ADDR } what; - unsigned char addr[4]; - unsigned char netmask[4]; -}; - -static void etap_change(int op, unsigned char *addr, unsigned char *netmask, - int fd) -{ - struct addr_change change; - void *output; - - change.what = op; - memcpy(change.addr, addr, sizeof(change.addr)); - memcpy(change.netmask, netmask, sizeof(change.netmask)); - if(write(fd, &change, sizeof(change)) != sizeof(change)) - printk("etap_change - request failed, errno = %d\n", - errno); - output = um_kmalloc(page_size()); - if(output == NULL) - printk("etap_change : Failed to allocate output buffer\n"); - read_output(fd, output, page_size()); - if(output != NULL){ - printk("%s", output); - kfree(output); - } -} - -static void etap_open_addr(unsigned char *addr, unsigned char *netmask, - void *arg) -{ - etap_change(ADD_ADDR, addr, netmask, *((int *) arg)); -} - -static void etap_close_addr(unsigned char *addr, unsigned char *netmask, - void *arg) -{ - etap_change(DEL_ADDR, addr, netmask, *((int *) arg)); -} - -struct etap_pre_exec_data { - int control_remote; - int control_me; - int data_me; -}; - -static void etap_pre_exec(void *arg) -{ - struct etap_pre_exec_data *data = arg; - - dup2(data->control_remote, 1); - close(data->data_me); - close(data->control_me); -} - -static int etap_tramp(char *dev, char *gate, int control_me, - int control_remote, int data_me, int data_remote) -{ - struct etap_pre_exec_data pe_data; - int pid, status, err; - char version_buf[sizeof("nnnnn\0")]; - char data_fd_buf[sizeof("nnnnnn\0")]; - char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")]; - char *setup_args[] = { "uml_net", version_buf, "ethertap", dev, - data_fd_buf, gate_buf, NULL }; - char *nosetup_args[] = { "uml_net", version_buf, "ethertap", - dev, data_fd_buf, NULL }; - char **args, c; - - sprintf(data_fd_buf, "%d", data_remote); - sprintf(version_buf, "%d", UML_NET_VERSION); - if(gate != NULL){ - strcpy(gate_buf, gate); - args = setup_args; - } - else args = nosetup_args; - - err = 0; - pe_data.control_remote = control_remote; - pe_data.control_me = control_me; - pe_data.data_me = data_me; - pid = run_helper(etap_pre_exec, &pe_data, args, NULL); - - if(pid < 0) err = errno; - close(data_remote); - close(control_remote); - if(read(control_me, &c, sizeof(c)) != sizeof(c)){ - printk("etap_tramp : read of status failed, errno = %d\n", - errno); - return(EINVAL); - } - if(c != 1){ - printk("etap_tramp : uml_net failed\n"); - err = EINVAL; - if(waitpid(pid, &status, 0) < 0) err = errno; - else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)){ - printk("uml_net didn't exit with status 1\n"); - } - } - return(err); -} - -static int etap_open(void *data) -{ - struct ethertap_data *pri = data; - char *output; - int data_fds[2], control_fds[2], err, output_len; - - err = tap_open_common(pri->dev, pri->gate_addr); - if(err) return(err); - - if(socketpair(PF_UNIX, SOCK_DGRAM, 0, data_fds) < 0){ - printk("data socketpair failed - errno = %d\n", errno); - return(-errno); - } - - if(socketpair(PF_UNIX, SOCK_STREAM, 0, control_fds) < 0){ - printk("data socketpair failed - errno = %d\n", errno); - return(-errno); - } - - err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], - control_fds[1], data_fds[0], data_fds[1]); - output_len = page_size(); - output = um_kmalloc(output_len); - read_output(control_fds[0], output, output_len); - - if(output == NULL) - printk("etap_open : failed to allocate output buffer\n"); - else { - printk("%s", output); - kfree(output); - } - - if(err != 0){ - printk("etap_tramp failed - errno = %d\n", err); - return(-err); - } - - pri->data_fd = data_fds[0]; - pri->control_fd = control_fds[0]; - iter_addresses(pri->dev, etap_open_addr, &pri->control_fd); - return(data_fds[0]); -} - -static void etap_close(int fd, void *data) -{ - struct ethertap_data *pri = data; - - iter_addresses(pri->dev, etap_close_addr, &pri->control_fd); - close(fd); - shutdown(pri->data_fd, SHUT_RDWR); - close(pri->data_fd); - pri->data_fd = -1; - close(pri->control_fd); - pri->control_fd = -1; -} - -static int etap_set_mtu(int mtu, void *data) -{ - return(mtu); -} - -static void etap_add_addr(unsigned char *addr, unsigned char *netmask, - void *data) -{ - struct ethertap_data *pri = data; - - tap_check_ips(pri->gate_addr, addr); - if(pri->control_fd == -1) return; - etap_open_addr(addr, netmask, &pri->control_fd); -} - -static void etap_del_addr(unsigned char *addr, unsigned char *netmask, - void *data) -{ - struct ethertap_data *pri = data; - - if(pri->control_fd == -1) return; - etap_close_addr(addr, netmask, &pri->control_fd); -} - -struct net_user_info ethertap_user_info = { - init: etap_user_init, - open: etap_open, - close: etap_close, - remove: NULL, - set_mtu: etap_set_mtu, - add_address: etap_add_addr, - delete_address: etap_del_addr, - max_packet: MAX_PACKET - ETH_HEADER_ETHERTAP -}; - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff -urNp 36/arch/um/drivers/harddog_user.c 40/arch/um/drivers/harddog_user.c --- 36/arch/um/drivers/harddog_user.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/harddog_user.c Tue Jul 16 17:08:05 2002 @@ -10,6 +10,7 @@ #include "user.h" #include "helper.h" #include "mconsole.h" +#include "os.h" struct dog_data { int stdin; @@ -40,10 +41,18 @@ int start_watchdog(int *in_fd_ret, int * NULL }; char **args = NULL; - if(pipe(in_fds) || pipe(out_fds)){ - printk("harddog_open - pipe failed, errno = %d\n", errno); - return(-errno); + err = os_pipe(in_fds, 1); + if(err){ + printk("harddog_open - os_pipe failed, errno = %d\n", -err); + return(err); } + + err = os_pipe(out_fds, 1); + if(err){ + printk("harddog_open - os_pipe failed, errno = %d\n", -err); + return(err); + } + data.stdin = out_fds[0]; data.stdout = in_fds[1]; data.close_me[0] = out_fds[1]; diff -urNp 36/arch/um/drivers/hostaudio_user.c 40/arch/um/drivers/hostaudio_user.c --- 36/arch/um/drivers/hostaudio_user.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/hostaudio_user.c Tue Jul 16 17:08:05 2002 @@ -13,6 +13,7 @@ #include "user_util.h" #include "kern_util.h" #include "user.h" +#include "os.h" /* /dev/dsp file operations */ @@ -62,17 +63,11 @@ int hostaudio_ioctl_user(struct hostaudi int hostaudio_open_user(struct hostaudio_state *state, int r, int w, char *dsp) { - int flags = 0; - #ifdef DEBUG printk("hostaudio: open_user called\n"); #endif - if(r && !w) flags = O_RDONLY; - else if(!r && w) flags = O_WRONLY; - else if(r && w) flags = O_RDWR; - - state->fd = open(dsp, flags); + state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); if(state->fd >= 0) return(0); @@ -114,17 +109,11 @@ int hostmixer_ioctl_mixdev_user(struct h int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, int w, char *mixer) { - int flags = 0; - #ifdef DEBUG printk("hostmixer: open_user called\n"); #endif - if(r && !w) flags = O_RDONLY; - else if(!r && w) flags = O_WRONLY; - else if(r && w) flags = O_RDWR; - - state->fd = open(mixer, flags); + state->fd = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0); if(state->fd >= 0) return(0); diff -urNp 36/arch/um/drivers/line.c 40/arch/um/drivers/line.c --- 36/arch/um/drivers/line.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/line.c Tue Jul 16 17:08:05 2002 @@ -13,6 +13,7 @@ #include "line.h" #include "kern.h" #include "user_util.h" +#include "os.h" #define LINE_BUFSIZE 4096 @@ -430,7 +431,7 @@ static void winch_cleanup(void) winch = list_entry(ele, struct winch, list); close(winch->fd); free_irq_by_fd(winch->fd); - if(winch->pid != -1) kill_pid(winch->pid); + if(winch->pid != -1) os_kill_process(winch->pid); } } diff -urNp 36/arch/um/drivers/mcast_kern.c 40/arch/um/drivers/mcast_kern.c --- 36/arch/um/drivers/mcast_kern.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/mcast_kern.c Tue Jul 16 17:08:05 2002 @@ -134,6 +134,19 @@ int mcast_setup(char *str, struct uml_ne return(0); } +static struct transport mcast_transport = { + list : LIST_HEAD_INIT(mcast_transport.list), + name : "mcast", + setup : mcast_setup +}; + +static int register_mcast(void) +{ + register_transport(&mcast_transport); + return(1); +} + +__initcall(register_mcast); /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically diff -urNp 36/arch/um/drivers/mconsole_kern.c 40/arch/um/drivers/mconsole_kern.c --- 36/arch/um/drivers/mconsole_kern.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/mconsole_kern.c Tue Jul 16 17:08:05 2002 @@ -1,5 +1,6 @@ /* * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -20,6 +21,7 @@ #include "mconsole_kern.h" #include "irq_user.h" #include "init.h" +#include "os.h" static int do_unlink_socket(struct notifier_block *notifier, unsigned long what, void *data) @@ -99,7 +101,7 @@ void mconsole_version(struct mc_request reboot - Reboot UML config = - Add a new device to UML; same syntax as command line - remove - Remove a device from the client + remove - Remove a device from UML sysrq - Performs the SysRq action controlled by the letter cad - invoke the Ctl-Alt-Del handler " @@ -129,6 +131,25 @@ void mconsole_cad(struct mc_request *req ctrl_alt_del(); } +void mconsole_go(struct mc_request *req) +{ + mconsole_reply(req, "Not stopped", 1, 0); +} + +void mconsole_stop(struct mc_request *req) +{ + deactivate_fd(req->originating_fd, MCONSOLE_IRQ); + os_set_fd_block(req->originating_fd, 1); + mconsole_reply(req, "", 0, 0); + while(mconsole_get_request(req->originating_fd, req)){ + if(req->cmd->handler == mconsole_go) break; + (*req->cmd->handler)(req); + } + os_set_fd_block(req->originating_fd, 0); + reactivate_fd(req->originating_fd, MCONSOLE_IRQ); + mconsole_reply(req, "", 0, 0); +} + LIST_HEAD(mconsole_devices); void mconsole_register_dev(struct mc_device *new) diff -urNp 36/arch/um/drivers/mconsole_user.c 40/arch/um/drivers/mconsole_user.c --- 36/arch/um/drivers/mconsole_user.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/mconsole_user.c Tue Jul 16 17:08:05 2002 @@ -26,6 +26,8 @@ static struct mconsole_command commands[ { "sysrq", mconsole_sysrq, 1 }, { "help", mconsole_help, 1 }, { "cad", mconsole_cad, 1 }, + { "stop", mconsole_stop, 0 }, + { "go", mconsole_go, 1 }, }; char mconsole_socket_name[256]; diff -urNp 36/arch/um/drivers/net_kern.c 40/arch/um/drivers/net_kern.c --- 36/arch/um/drivers/net_kern.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/net_kern.c Tue Jul 16 17:08:05 2002 @@ -17,20 +17,11 @@ #include "linux/list.h" #include "linux/inetdevice.h" #include "linux/ctype.h" +#include "linux/bootmem.h" #include "user_util.h" #include "kern_util.h" #include "net_kern.h" #include "net_user.h" -#include "slip.h" -#include "slip_kern.h" -#include "etap.h" -#include "etap_kern.h" -#include "tuntap.h" -#include "tuntap_kern.h" -#include "daemon.h" -#include "daemon_kern.h" -#include "mcast.h" -#include "mcast_kern.h" #include "mconsole_kern.h" #include "init.h" #include "irq_user.h" @@ -47,112 +38,6 @@ struct uml_net devices[MAX_UML_NETDEV] = } }; -static int eth_setup_common(char *str, int *index_out) -{ - char *end; - int n; - - n = simple_strtoul(str, &end, 0); - if(end == str){ - printk(KERN_ERR "eth_setup: Failed to parse '%s'\n", str); - return(1); - } - if((n < 0) || (n > sizeof(devices)/sizeof(devices[0]))){ - printk(KERN_ERR "eth_setup: device %d out of range\n", n); - return(1); - } - str = end; - if(*str != '='){ - printk(KERN_ERR - "eth_setup: expected '=' after device number\n"); - return(1); - } - str++; - if(devices[n].dev != NULL){ - printk(KERN_ERR "eth_setup: Device %d already configured\n", - n); - return(1); - } - if(index_out) *index_out = n; -#ifdef CONFIG_UML_NET_ETHERTAP - if(!strncmp(str, "ethertap", strlen("ethertap"))) - return(ethertap_setup(&str[strlen("ethertap")], &devices[n])); -#endif -#ifdef CONFIG_UML_NET_TUNTAP - if(!strncmp(str, "tuntap", strlen("tuntap"))) - return(tuntap_setup(&str[strlen("tuntap")], &devices[n])); -#endif -#ifdef CONFIG_UML_NET_DAEMON - if(!strncmp(str, "daemon", strlen("daemon"))) - return(daemon_setup(&str[strlen("daemon")], &devices[n])); -#endif -#ifdef CONFIG_UML_NET_SLIP - if(!strncmp(str, "slip", strlen("slip"))) - return(slip_setup(&str[strlen("slip")], &devices[n])); -#endif -#ifdef CONFIG_UML_NET_MCAST - if(!strncmp(str, "mcast", strlen("mcast"))) - return(mcast_setup(&str[strlen("mcast")], &devices[n])); -#endif - printk(KERN_ERR "Unknown transport in eth_setup : %s\n", str); - return(1); -} - -static int eth_setup(char *str) -{ - eth_setup_common(str, NULL); - return(1); -} - -#ifdef CONFIG_UML_NET_ETHERTAP -#define UML_NET_ETHERTAP_HELP \ -" eth[0-9]+=ethertap,,,\n" \ -" eth0=ethertap,tap0,,192.168.0.1\n\n" -#else -#define UML_NET_ETHERTAP_HELP -#endif -#ifdef CONFIG_UML_NET_TUNTAP -#define UML_NET_TUNTAP_HELP \ -" eth[0-9]+=tuntap,,,\n" \ -" eth0=tuntap,,fe:fd:0:0:0:1,192.168.0.1\n\n" -#else -#define UML_NET_TUNTAP_HELP -#endif -#ifdef CONFIG_UML_NET_DAEMON -#define UML_NET_DAEMON_HELP \ -" eth[0-9]+=daemon,,,,\n" \ -" eth0=daemon,unix,/tmp/uml.ctl,/tmp/uml.data\n\n" -#else -#define UML_NET_DAEMON_HELP -#endif -#ifdef CONFIG_UML_NET_SLIP -#define UML_NET_SLIP_HELP \ -" eth[0-9]+=slip,\n" \ -" eth0=slip,192.168.0.1\n\n" -#else -#define UML_NET_SLIP_HELP -#endif -#ifdef CONFIG_UML_NET_MCAST -#define UML_NET_MCAST_HELP \ -" eth[0-9]+=mcast,,
,,\n" \ -" eth0=mcast,,224.2.3.4:5555,3\n\n" -#else -#define UML_NET_MCAST_HELP -#endif - -__setup("eth", eth_setup); -__uml_help(eth_setup, -"eth[0-9]+=,\n" -" Configure a network device. Formats and examples follow (one \n" -" for each configured transport).\n\n" -UML_NET_ETHERTAP_HELP -UML_NET_TUNTAP_HELP -UML_NET_DAEMON_HELP -UML_NET_SLIP_HELP -UML_NET_MCAST_HELP -); -int ndev = 0; - static int uml_net_rx(struct net_device *dev) { struct uml_net_private *lp = dev->priv; @@ -443,27 +328,143 @@ static int eth_configure(struct uml_net return(0); } -int __init uml_net_probe(void) +static int eth_parse(char *str, int *index_out, char **str_out) { - int i; + char *end; + int n; - for(i = 0; i < sizeof(devices)/sizeof(devices[0]); i++){ - if(devices[i].user == NULL) continue; - eth_configure(&devices[i], i); + n = simple_strtoul(str, &end, 0); + if(end == str){ + printk(KERN_ERR "eth_setup: Failed to parse '%s'\n", str); + return(1); } + if((n < 0) || (n > sizeof(devices)/sizeof(devices[0]))){ + printk(KERN_ERR "eth_setup: device %d out of range\n", n); + return(1); + } + str = end; + if(*str != '='){ + printk(KERN_ERR + "eth_setup: expected '=' after device number\n"); + return(1); + } + str++; + if(devices[n].dev != NULL){ + printk(KERN_ERR "eth_setup: Device %d already configured\n", + n); + return(1); + } + if(index_out) *index_out = n; + *str_out = str; return(0); } +struct eth_init { + struct list_head list; + char *init; + int index; +}; + +struct list_head transports = LIST_HEAD_INIT(transports); + +struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line); + +void register_transport(struct transport *new) +{ + struct list_head *ele, *next; + struct eth_init *eth; + char *str; + int err; + + list_add(&new->list, &transports); + + list_for_each_safe(ele, next, ð_cmd_line){ + eth = list_entry(ele, struct eth_init, list); + if(!strncmp(eth->init, new->name, strlen(new->name))){ + str = eth->init + strlen(new->name); + err = new->setup(str, &devices[eth->index]); + if(!err) eth_configure(&devices[eth->index], + eth->index); + list_del(ð->list); + } + } +} + +static int eth_setup_common(char *str, int index) +{ + struct list_head *ele; + struct transport *transport; + + list_for_each(ele, &transports){ + transport = list_entry(ele, struct transport, list); + if(!strncmp(str, transport->name, strlen(transport->name))){ + str += strlen(transport->name); + return(transport->setup(str, &devices[index])); + } + } + + return(-1); +} + +static int eth_setup(char *str) +{ + struct eth_init *new; + int n, err; + + err = eth_parse(str, &n, &str); + if(err) return(1); + + new = alloc_bootmem(sizeof(new)); + if(new == NULL){ + printk("eth_init : alloc_bootmem failed\n"); + return(1); + } + *new = ((struct eth_init) { list : LIST_HEAD_INIT(new->list), + index : n, + init : str }); + list_add_tail(&new->list, ð_cmd_line); + return(1); +} + +__setup("eth", eth_setup); +__uml_help(eth_setup, +"eth[0-9]+=,\n" +" Configure a network device.\n\n" +); + +int ndev = 0; + +static int eth_init(void) +{ + struct list_head *ele, *next; + struct eth_init *eth; + int err; + + list_for_each_safe(ele, next, ð_cmd_line){ + eth = list_entry(ele, struct eth_init, list); + err = eth_setup_common(eth->init, eth->index); + if(!err) eth_configure(&devices[eth->index], eth->index); + if(err >= 0) list_del(ð->list); + } + + return(1); +} + +__initcall(eth_init); + static int net_config(char *str) { int err, n; + err = eth_parse(str, &n, &str); + if(err) return(err); + str = uml_strdup(str); if(str == NULL){ printk(KERN_ERR "net_config failed to strdup string\n"); return(1); } - err = eth_setup_common(str, &n); + err = eth_setup_common(str, n); if(err){ kfree(str); return(err); diff -urNp 36/arch/um/drivers/net_kern.h 40/arch/um/drivers/net_kern.h --- 36/arch/um/drivers/net_kern.h Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/net_kern.h Thu Jan 1 01:00:00 1970 @@ -1,68 +0,0 @@ -#ifndef __UM_NET_KERN_H -#define __UM_NET_KERN_H - -#include "linux/netdevice.h" -#include "linux/skbuff.h" -#include "linux/socket.h" -#include "linux/list.h" - -#define MAX_UML_NETDEV (16) - -struct uml_net { - struct net_device *dev; - struct net_user_info *user; - struct net_kern_info *kern; - int private_size; - int transport_index; - unsigned char mac[ETH_ALEN]; - int have_mac; -}; - -struct uml_net_private { - struct list_head list; - spinlock_t lock; - struct net_device *dev; - struct timer_list tl; - struct net_device_stats stats; - int fd; - unsigned char mac[ETH_ALEN]; - int have_mac; - unsigned short (*protocol)(struct sk_buff *); - int (*open)(void *); - void (*close)(int, void *); - void (*remove)(void *); - int (*read)(int, struct sk_buff **skb, struct uml_net_private *); - int (*write)(int, struct sk_buff **skb, struct uml_net_private *); - - void (*add_address)(unsigned char *, unsigned char *, void *); - void (*delete_address)(unsigned char *, unsigned char *, void *); - int (*set_mtu)(int mtu, void *); - int user[1]; -}; - -struct net_kern_info { - struct net_device *(*init)(int, int); - unsigned short (*protocol)(struct sk_buff *); - int (*read)(int, struct sk_buff **skb, struct uml_net_private *); - int (*write)(int, struct sk_buff **skb, struct uml_net_private *); -}; - -extern struct net_device *ether_init(int); -extern unsigned short ether_protocol(struct sk_buff *); -extern int setup_etheraddr(char *str, unsigned char *addr); -extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra); -extern int tap_setup_common(char *str, char *type, char **dev_name, - char *hw_addr, int *hw_setup, char **gate_addr); - -#endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff -urNp 36/arch/um/drivers/net_user.c 40/arch/um/drivers/net_user.c --- 36/arch/um/drivers/net_user.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/net_user.c Tue Jul 16 17:08:05 2002 @@ -16,6 +16,7 @@ #include "kern_util.h" #include "net_user.h" #include "helper.h" +#include "os.h" int tap_open_common(void *dev, char *gate_addr) { @@ -161,13 +162,13 @@ static void change_pre_exec(void *arg) static int change_tramp(char **argv, char *output, int output_len) { - int pid, fds[2]; + int pid, fds[2], err; struct change_pre_exec_data pe_data; - if(pipe(fds) < 0){ - printk("change_tramp - pipe failed, errno = %d\n", - errno); - return(-errno); + err = os_pipe(fds, 1); + if(err){ + printk("change_tramp - pipe failed, errno = %d\n", -err); + return(err); } pe_data.close_me = fds[0]; pe_data.stdout = fds[1]; diff -urNp 36/arch/um/drivers/net_user.h 40/arch/um/drivers/net_user.h --- 36/arch/um/drivers/net_user.h Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/net_user.h Thu Jan 1 01:00:00 1970 @@ -1,57 +0,0 @@ -#ifndef __UM_NET_USER_H__ -#define __UM_NET_USER_H__ - -#define ETH_ADDR_LEN (6) -#define ETH_HEADER_ETHERTAP (16) -#define ETH_HEADER_OTHER (14) -#define ETH_MAX_PACKET (1500) - -#define UML_NET_VERSION (4) - -struct net_user_info { - void (*init)(void *, void *); - int (*open)(void *); - void (*close)(int, void *); - void (*remove)(void *); - int (*set_mtu)(int mtu, void *); - void (*add_address)(unsigned char *, unsigned char *, void *); - void (*delete_address)(unsigned char *, unsigned char *, void *); - int max_packet; -}; - -extern void ether_user_init(void *data, void *dev); -extern void dev_ip_addr(void *d, char *buf, char *bin_buf); -extern void set_ether_mac(void *d, unsigned char *addr); -extern void iter_addresses(void *d, void (*cb)(unsigned char *, - unsigned char *, void *), - void *arg); - -extern void *get_output_buffer(int *len_out); -extern void free_output_buffer(void *buffer); - -extern int tap_open_common(void *dev, char *gate_addr); -extern void tap_check_ips(char *gate_addr, char *eth_addr); - -extern void read_output(int fd, char *output_out, int len); - -extern int net_read(int fd, void *buf, int len); -extern int net_recvfrom(int fd, void *buf, int len); -extern int net_write(int fd, void *buf, int len); -extern int net_send(int fd, void *buf, int len); -extern int net_sendto(int fd, void *buf, int len, void *to, int sock_len); - -extern void open_addr(unsigned char *addr, unsigned char *netmask, void *arg); -extern void close_addr(unsigned char *addr, unsigned char *netmask, void *arg); - -#endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff -urNp 36/arch/um/drivers/null.c 40/arch/um/drivers/null.c --- 36/arch/um/drivers/null.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/null.c Tue Jul 16 17:08:05 2002 @@ -6,6 +6,7 @@ #include #include #include "chan_user.h" +#include "os.h" static int null_chan; @@ -16,7 +17,7 @@ void *null_init(char *str, int device, s int null_open(int input, int output, int primary, void *d) { - return(open("/dev/null", O_RDWR)); + return(os_open_file(DEV_NULL, of_rdwr(OPENFLAGS()), 0)); } int null_read(int fd, char *c_out, void *unused) diff -urNp 36/arch/um/drivers/port.c 40/arch/um/drivers/port.c --- 36/arch/um/drivers/port.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/port.c Tue Jul 16 17:08:05 2002 @@ -18,10 +18,10 @@ #include "chan_user.h" #include "port.h" #include "helper.h" +#include "os.h" struct port_chan { int raw; - int socket[2]; struct termios tt; void *kernel_data; }; @@ -49,7 +49,6 @@ void *port_init(char *str, int device, s if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL); *data = ((struct port_chan) { raw : opts->raw, - socket : { -1, -1 }, kernel_data : kern_data }); return(data); @@ -60,7 +59,7 @@ int port_open(int input, int output, int struct port_chan *data = d; int fd; - fd = port_wait(data->kernel_data, data->socket); + fd = port_wait(data->kernel_data); if((fd >= 0) && data->raw){ tcgetattr(fd, &data->tt); raw(fd, 0); @@ -72,10 +71,8 @@ void port_close(int fd, void *d) { struct port_chan *data = d; - shutdown(data->socket[0], SHUT_RDWR); - data->socket[0] = -1; - shutdown(data->socket[1], SHUT_RDWR); - data->socket[1] = -1; + port_remove_dev(data->kernel_data); + close(fd); } int port_console_write(int fd, const char *buf, int n, void *d) @@ -96,7 +93,7 @@ void port_free(void *d) struct chan_ops port_ops = { init: port_init, open: port_open, - close: port_close, + close: generic_close, read: generic_read, write: generic_write, console_write: port_console_write, @@ -108,7 +105,7 @@ struct chan_ops port_ops = { int port_listen_fd(int port) { struct sockaddr_in addr; - int fd; + int fd, err; fd = socket(PF_INET, SOCK_STREAM, 0); if(fd == -1) return(-errno); @@ -116,15 +113,23 @@ int port_listen_fd(int port) addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = htonl(INADDR_ANY); - if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) - return(-errno); + if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0){ + err = -errno; + goto out; + } - if(listen(fd, 1) < 0) return(-errno); + if(listen(fd, 1) < 0){ + err = -errno; + goto out; + } return(fd); + out: + os_close_file(fd); + return(err); } -static int rcv_fd(int fd) +int port_rcv_fd(int fd) { int new, n; char buf[CMSG_SPACE(sizeof(new))]; @@ -162,7 +167,7 @@ static int rcv_fd(int fd) struct port_pre_exec_data { int sock_fd; - int pipe_fds[2]; + int pipe_fd; }; void port_pre_exec(void *arg) @@ -173,8 +178,9 @@ void port_pre_exec(void *arg) dup2(data->sock_fd, 1); dup2(data->sock_fd, 2); close(data->sock_fd); - dup2(data->pipe_fds[1], 3); - close(data->pipe_fds[1]); + dup2(data->pipe_fd, 3); + shutdown(3, SHUT_RD); + close(data->pipe_fd); } int port_connection(int fd, int *socket) @@ -186,21 +192,26 @@ int port_connection(int fd, int *socket) if((new = accept(fd, NULL, 0)) < 0) return(-errno); - if(socketpair(PF_UNIX, SOCK_DGRAM, 0, socket) < 0) return(-errno); + err = os_pipe(socket, 0); + if(err) goto out_close; data = ((struct port_pre_exec_data) { sock_fd : new, - pipe_fds : { socket[0], socket[1] } }); + pipe_fd : socket[1] }); err = run_helper(port_pre_exec, &data, argv, NULL); + if(err < 0) goto out_shutdown; - if(err < 0){ - shutdown(socket[0], SHUT_RDWR); - shutdown(socket[1], SHUT_RDWR); - return(err); - } + return(new); - return(rcv_fd(socket[0])); + out_shutdown: + shutdown(socket[0], SHUT_RDWR); + close(socket[0]); + shutdown(socket[1], SHUT_RDWR); + close(socket[1]); + out_close: + close(new); + return(err); } /* diff -urNp 36/arch/um/drivers/port.h 40/arch/um/drivers/port.h --- 36/arch/um/drivers/port.h Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/port.h Tue Jul 16 17:08:05 2002 @@ -7,12 +7,14 @@ #define __PORT_H__ extern void *port_data(int port); -extern int port_wait(void *data, int *socket_out); +extern int port_wait(void *data); extern void port_kern_close(void *d); extern int port_connection(int fd, int *socket_out); extern int port_listen_fd(int port); extern void port_read(int fd, void *data); extern void port_kern_free(void *d); +extern int port_rcv_fd(int fd); +extern void port_remove_dev(void *d); #endif diff -urNp 36/arch/um/drivers/port_kern.c 40/arch/um/drivers/port_kern.c --- 36/arch/um/drivers/port_kern.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/port_kern.c Tue Jul 16 17:08:05 2002 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -14,6 +14,8 @@ #include "kern.h" #include "irq_user.h" #include "port.h" +#include "init.h" +#include "os.h" struct port_list { struct list_head list; @@ -21,6 +23,7 @@ struct port_list { int port; int fd; spinlock_t lock; + struct list_head pending; struct list_head connections; }; @@ -33,15 +36,68 @@ struct connection { struct list_head list; int fd; int socket[2]; + struct port_list *port; }; +static void pipe_interrupt(int irq, void *data, struct pt_regs *regs) +{ + struct connection *conn = data; + int fd; + + list_del(&conn->list); + + fd = port_rcv_fd(conn->socket[0]); + if(fd < 0){ + printk("os_accept_connection returned %d\n", -fd); + os_close_file(conn->fd); + } + conn->fd = fd; + list_add(&conn->list, &conn->port->connections); + + up(&conn->port->sem); +} + struct list_head ports = LIST_HEAD_INIT(ports); static void port_interrupt(int irq, void *data, struct pt_regs *regs) { struct port_list *port = data; + struct connection *conn; + int fd, socket[2]; + + fd = port_connection(port->fd, socket); + if(fd < 0){ + printk("port_connection returned %d\n", -fd); + goto out; + } - up(&port->sem); + conn = kmalloc(sizeof(*conn), GFP_ATOMIC); + if(conn == NULL){ + printk("port_interrupt : failed to allocate connection\n"); + goto out_close; + } + *conn = ((struct connection) + { list : LIST_HEAD_INIT(conn->list), + fd : fd, + socket : { socket[0], socket[1] }, + port : port }); + + if(um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, + SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, + "telnetd", conn)){ + printk(KERN_ERR "Failed to get IRQ for telnetd\n"); + goto out_free; + } + + list_add(&conn->list, &port->pending); + goto out; + + out_free: + kfree(conn); + out_close: + os_close_file(fd); + out: + reactivate_fd(port->fd, ACCEPT_IRQ); } void *port_data(int port_num) @@ -65,13 +121,13 @@ void *port_data(int port_num) if(fd < 0){ printk(KERN_ERR "binding to port %d failed, errno = %d\n", port_num, -fd); - return(NULL); + goto out_free; } if(um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, "port", port)){ printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); - return(NULL); + goto out_close; } *port = ((struct port_list) @@ -80,6 +136,7 @@ void *port_data(int port_num) lock : SPIN_LOCK_UNLOCKED, port : port_num, fd : fd, + pending : LIST_HEAD_INIT(port->pending), connections : LIST_HEAD_INIT(port->connections) }); list_add(&port->list, &ports); @@ -90,48 +147,72 @@ void *port_data(int port_num) return(NULL); } - *dev = ((struct port_dev) - { port : port, - fd : -1 }); + *dev = ((struct port_dev) { port : port, + fd : -1 }); return(dev); + + out_free: + kfree(port); + out_close: + os_close_file(fd); + return(NULL); +} + +void port_remove_dev(void *d) +{ + struct port_dev *dev = d; + + kfree(dev); +} + +static void free_port(void) +{ + struct list_head *ele; + struct port_list *port; + + list_for_each(ele, &ports){ + port = list_entry(ele, struct port_list, list); + os_close_file(port->fd); + } } -int port_wait(void *data, int *socket_out) +__uml_exitcall(free_port); + +int port_wait(void *data) { struct port_dev *dev = data; struct connection *conn; struct port_list *port = dev->port; - int fd, socket[2]; - if(down_interruptible(&port->sem)) return(-ERESTARTSYS); + while(1){ + if(down_interruptible(&port->sem)) return(-ERESTARTSYS); - spin_lock(&port->lock); - reactivate_fd(port->fd, ACCEPT_IRQ); + spin_lock(&port->lock); - fd = port_connection(port->fd, socket); - if(fd < 0){ - printk("port_connection returned %d\n", -fd); - return(fd); + conn = list_entry(port->connections.next, struct connection, + list); + list_del(&conn->list); + spin_unlock(&port->lock); + + os_shutdown_socket(conn->socket[0]); + os_close_file(conn->socket[0]); + os_shutdown_socket(conn->socket[1]); + os_close_file(conn->socket[1]); + + /* This is done here because freeing an IRQ can't be done + * within the IRQ handler. So, pipe_interrupt always ups + * the semaphore regardless of whether it got a successful + * connection. Then we loop here throwing out failed + * connections until a good one is found. + */ + free_irq(TELNETD_IRQ, conn); + + if(conn->fd >= 0) break; + os_close_file(conn->fd); + kfree(conn); } - conn = kmalloc(sizeof(*conn), GFP_ATOMIC); - if(conn == NULL){ - printk("port_wait : failed to allocate connection\n"); - close(fd); - return(-ENOMEM); - } - *conn = ((struct connection) - { list : LIST_HEAD_INIT(conn->list), - fd : fd, - socket : { socket[0], socket[1] } }); - list_add(&conn->list, &port->connections); - - conn = list_entry(port->connections.next, struct connection, list); - list_del(&conn->list); - spin_unlock(&port->lock); dev->fd = conn->fd; - socket_out[0] = conn->socket[0]; - socket_out[1] = conn->socket[1]; kfree(conn); return(dev->fd); diff -urNp 36/arch/um/drivers/slip_kern.c 40/arch/um/drivers/slip_kern.c --- 36/arch/um/drivers/slip_kern.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/slip_kern.c Tue Jul 16 17:08:05 2002 @@ -89,6 +89,20 @@ int slip_setup(char *str, struct uml_net return(0); } +static struct transport slip_transport = { + list : LIST_HEAD_INIT(slip_transport.list), + name : "slip", + setup : slip_setup +}; + +static int register_slip(void) +{ + register_transport(&slip_transport); + return(1); +} + +__initcall(register_slip); + /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically diff -urNp 36/arch/um/drivers/slip_user.c 40/arch/um/drivers/slip_user.c --- 36/arch/um/drivers/slip_user.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/slip_user.c Tue Jul 16 17:08:05 2002 @@ -16,6 +16,7 @@ #include "net_user.h" #include "slip.h" #include "helper.h" +#include "os.h" void slip_user_init(void *data, void *dev) { @@ -74,9 +75,10 @@ static int slip_tramp(char **argv, int f char *output; int status, pid, fds[2], err, output_len; - if(pipe(fds) != 0){ - printk("slip_tramp : pipe failed, errno = %d\n", errno); - return(-errno); + err = os_pipe(fds, 1); + if(err){ + printk("slip_tramp : pipe failed, errno = %d\n", -err); + return(err); } err = 0; @@ -121,7 +123,7 @@ static int slip_open(void *data) printk("umn : Failed to open pty\n"); return(-1); } - if((sfd = open(ptsname(mfd), O_RDWR)) < 0){ + if((sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0)) < 0){ printk("Couldn't open tty for slip line\n"); return(-1); } diff -urNp 36/arch/um/drivers/tty.c 40/arch/um/drivers/tty.c --- 36/arch/um/drivers/tty.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/tty.c Tue Jul 16 17:08:05 2002 @@ -11,6 +11,7 @@ #include "chan_user.h" #include "user_util.h" #include "user.h" +#include "os.h" struct tty_chan { char *dev; @@ -39,14 +40,10 @@ void *tty_chan_init(char *str, int devic int tty_open(int input, int output, int primary, void *d) { struct tty_chan *data = d; - int fd, mode; + int fd; - if(input && output) mode = O_RDWR; - else if(input) mode = O_RDONLY; - else mode = O_WRONLY; - - fd = open(data->dev, mode); - if(fd < 0) return(-errno); + fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0); + if(fd < 0) return(fd); if(data->raw){ tcgetattr(fd, &data->tt); raw(fd, 0); diff -urNp 36/arch/um/drivers/tuntap.h 40/arch/um/drivers/tuntap.h --- 36/arch/um/drivers/tuntap.h Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/tuntap.h Thu Jan 1 01:00:00 1970 @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __UM_TUNTAP_H -#define __UM_TUNTAP_H - -#include "net_user.h" - -struct tuntap_data { - char *dev_name; - int fixed_config; - char *gate_addr; - int fd; - void *dev; - unsigned char hw_addr[ETH_ADDR_LEN]; - int hw_setup; -}; - -extern struct net_user_info tuntap_user_info; - -#endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff -urNp 36/arch/um/drivers/tuntap_kern.c 40/arch/um/drivers/tuntap_kern.c --- 36/arch/um/drivers/tuntap_kern.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/tuntap_kern.c Thu Jan 1 01:00:00 1970 @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include "linux/stddef.h" -#include "linux/netdevice.h" -#include "linux/etherdevice.h" -#include "linux/skbuff.h" -#include "asm/errno.h" -#include "net_kern.h" -#include "net_user.h" -#include "tuntap.h" - -struct tuntap_setup { - char *dev_name; - char *gate_addr; -}; - -struct tuntap_setup tuntap_priv[MAX_UML_NETDEV] = { - [ 0 ... MAX_UML_NETDEV - 1 ] = - { - dev_name: NULL, - gate_addr: NULL, - } -}; - -struct net_device *tuntap_init(int private_size, int index) -{ - struct net_device *dev; - struct uml_net_private *pri; - struct tuntap_data *tpri; - - dev = init_etherdev(NULL, private_size); - if(dev == NULL) return(NULL); - pri = dev->priv; - tpri = (struct tuntap_data *) pri->user; - tpri->dev_name = tuntap_priv[index].dev_name; - tpri->fixed_config = (tpri->dev_name != NULL); - tpri->gate_addr = tuntap_priv[index].gate_addr; - printk("TUN/TAP backend - "); - if(tpri->gate_addr != NULL) - printk("IP = %s", tpri->gate_addr); - printk("\n"); - tpri->fd = -1; - return(dev); -} - -static unsigned short tuntap_protocol(struct sk_buff *skb) -{ - return(eth_type_trans(skb, skb->dev)); -} - -static int tuntap_read(int fd, struct sk_buff **skb, - struct uml_net_private *lp) -{ - *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); - if(*skb == NULL) return(-ENOMEM); - return(net_read(fd, (*skb)->mac.raw, - (*skb)->dev->mtu + ETH_HEADER_OTHER)); -} - -static int tuntap_write(int fd, struct sk_buff **skb, - struct uml_net_private *lp) -{ - return(net_write(fd, (*skb)->data, (*skb)->len)); -} - -struct net_kern_info tuntap_kern_info = { - init: tuntap_init, - protocol: tuntap_protocol, - read: tuntap_read, - write: tuntap_write, -}; - -static int tuntap_count = 0; - -int tuntap_setup(char *str, struct uml_net *dev) -{ - struct tuntap_setup *pri; - int err; - - pri = &tuntap_priv[tuntap_count]; - err = tap_setup_common(str, "tuntap", &pri->dev_name, dev->mac, - &dev->have_mac, &pri->gate_addr); - if(err) return(err); - - dev->user = &tuntap_user_info; - dev->kern = &tuntap_kern_info; - dev->private_size = sizeof(struct tuntap_data); - dev->transport_index = tuntap_count++; - return(0); -} - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff -urNp 36/arch/um/drivers/tuntap_kern.h 40/arch/um/drivers/tuntap_kern.h --- 36/arch/um/drivers/tuntap_kern.h Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/tuntap_kern.h Thu Jan 1 01:00:00 1970 @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#ifndef __UM_TUNTAP_KERN_H -#define __UM_TUNTAP_KERN_H - -#include "net_kern.h" - -extern int tuntap_setup(char *arg, struct uml_net *dev); - -#endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff -urNp 36/arch/um/drivers/tuntap_user.c 40/arch/um/drivers/tuntap_user.c --- 36/arch/um/drivers/tuntap_user.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/tuntap_user.c Thu Jan 1 01:00:00 1970 @@ -1,220 +0,0 @@ -/* - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "net_user.h" -#include "tuntap.h" -#include "kern_util.h" -#include "user.h" -#include "helper.h" - -#define MAX_PACKET ETH_MAX_PACKET - -void tuntap_user_init(void *data, void *dev) -{ - struct tuntap_data *pri = data; - - pri->dev = dev; -} - -static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask, - void *data) -{ - struct tuntap_data *pri = data; - - tap_check_ips(pri->gate_addr, addr); - if((pri->fd == -1) || pri->fixed_config) return; - open_addr(addr, netmask, pri->dev_name); -} - -static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask, - void *data) -{ - struct tuntap_data *pri = data; - - if((pri->fd == -1) || pri->fixed_config) return; - close_addr(addr, netmask, pri->dev_name); -} - -struct tuntap_pre_exec_data { - int stdout; - int close_me; -}; - -static void tuntap_pre_exec(void *arg) -{ - struct tuntap_pre_exec_data *data = arg; - - dup2(data->stdout, 1); - close(data->close_me); -} - -static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, - char *buffer, int buffer_len, int *used_out) -{ - struct tuntap_pre_exec_data data; - char version_buf[sizeof("nnnnn\0")]; - char *argv[] = { "uml_net", version_buf, "tuntap", "up", gate, - NULL }; - char buf[CMSG_SPACE(sizeof(*fd_out))]; - struct msghdr msg; - struct cmsghdr *cmsg; - struct iovec iov; - int pid, n; - - sprintf(version_buf, "%d", UML_NET_VERSION); - - data.stdout = remote; - data.close_me = me; - - pid = run_helper(tuntap_pre_exec, &data, argv, NULL); - - if(pid < 0) return(-pid); - - close(remote); - - msg.msg_name = NULL; - msg.msg_namelen = 0; - if(buffer != NULL){ - iov = ((struct iovec) { buffer, buffer_len }); - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - } - else { - msg.msg_iov = NULL; - msg.msg_iovlen = 0; - } - msg.msg_control = buf; - msg.msg_controllen = sizeof(buf); - msg.msg_flags = 0; - n = recvmsg(me, &msg, 0); - *used_out = n; - if(n < 0){ - printk("tuntap_open_tramp : recvmsg failed - errno = %d\n", - errno); - return(errno); - } - waitpid(pid, NULL, 0); - - cmsg = CMSG_FIRSTHDR(&msg); - if(cmsg == NULL){ - printk("tuntap_open_tramp : didn't receive a message\n"); - return(EINVAL); - } - if((cmsg->cmsg_level != SOL_SOCKET) || - (cmsg->cmsg_type != SCM_RIGHTS)){ - printk("tuntap_open_tramp : didn't receive a descriptor\n"); - return(EINVAL); - } - *fd_out = ((int *) CMSG_DATA(cmsg))[0]; - return(0); -} - -static int tuntap_open(void *data) -{ - struct ifreq ifr; - struct tuntap_data *pri = data; - char *output, *buffer; - int err, fds[2], len, used; - - err = tap_open_common(pri->dev, pri->gate_addr); - if(err) return(err); - - if(pri->fixed_config){ - if((pri->fd = open("/dev/net/tun", O_RDWR)) < 0){ - printk("Failed to open /dev/net/tun, errno = %d\n", - errno); - return(-errno); - } - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_flags = IFF_TAP; - strncpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name) - 1); - if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){ - printk("TUNSETIFF failed, errno = %d", errno); - close(pri->fd); - return(-errno); - } - } - else { - if(socketpair(PF_UNIX, SOCK_DGRAM, 0, fds) < 0){ - printk("data socketpair failed - errno = %d\n", errno); - return(-errno); - } - - buffer = get_output_buffer(&len); - if(buffer != NULL) len--; - used = 0; - - err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0], - fds[1], buffer, len, &used); - - output = buffer; - if(err == 0){ - pri->dev_name = uml_strdup(buffer); - output += IFNAMSIZ; - printk(output); - free_output_buffer(buffer); - } - else { - printk(output); - free_output_buffer(buffer); - printk("tuntap_open_tramp failed - errno = %d\n", err); - return(-err); - } - close(fds[0]); - iter_addresses(pri->dev, open_addr, pri->dev_name); - } - - return(pri->fd); -} - -static void tuntap_close(int fd, void *data) -{ - struct tuntap_data *pri = data; - - if(!pri->fixed_config) - iter_addresses(pri->dev, close_addr, pri->dev_name); - close(fd); - pri->fd = -1; -} - -static int tuntap_set_mtu(int mtu, void *data) -{ - return(mtu); -} - -struct net_user_info tuntap_user_info = { - init: tuntap_user_init, - open: tuntap_open, - close: tuntap_close, - remove: NULL, - set_mtu: tuntap_set_mtu, - add_address: tuntap_add_addr, - delete_address: tuntap_del_addr, - max_packet: MAX_PACKET -}; - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff -urNp 36/arch/um/drivers/ubd.c 40/arch/um/drivers/ubd.c --- 36/arch/um/drivers/ubd.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/ubd.c Tue Jul 16 17:08:05 2002 @@ -38,6 +38,7 @@ #include "irq_user.h" #include "ubd_user.h" #include "2_5compat.h" +#include "os.h" static int ubd_open(struct inode * inode, struct file * filp); static int ubd_release(struct inode * inode, struct file * file); @@ -95,12 +96,12 @@ static struct gendisk fake_gendisk = INI &ubd_blops); #ifdef CONFIG_BLK_DEV_UBD_SYNC -#define OPEN_FLAGS O_RDWR | O_SYNC +#define OPEN_FLAGS ((struct openflags) { r : 1, w : 1, s : 1, c : 0 }) #else -#define OPEN_FLAGS O_RDWR +#define OPEN_FLAGS ((struct openflags) { r : 1, w : 1, s : 0, c : 0 }) #endif -static int global_openflags = OPEN_FLAGS; +static struct openflags global_openflags = OPEN_FLAGS; struct cow { char *file; @@ -117,8 +118,8 @@ struct ubd { int count; int fd; __u64 size; - int boot_openflags; - int openflags; + struct openflags boot_openflags; + struct openflags openflags; devfs_handle_t real; devfs_handle_t fake; struct cow cow; @@ -228,8 +229,9 @@ __uml_help(fake_ide_setup, static int ubd_setup_common(char *str, int *index_out) { + struct openflags flags = global_openflags; char *backing_file; - int n, sync, perm = O_RDWR; + int n; if(index_out) *index_out = -1; n = *str++; @@ -238,7 +240,7 @@ static int ubd_setup_common(char *str, i int major; if(!strcmp(str, "sync")){ - global_openflags |= O_SYNC; + global_openflags.s = 1; return(0); } major = simple_strtoul(str, &end, 0); @@ -269,13 +271,13 @@ static int ubd_setup_common(char *str, i return(1); } if(index_out) *index_out = n; - sync = ubd_dev[n].boot_openflags & O_SYNC; - if (*str == 'r') { - perm = O_RDONLY; + + if (*str == 'r'){ + flags.w = 0; str++; } - if (*str == 's') { - sync = O_SYNC; + if (*str == 's'){ + flags.s = 1; str++; } if(*str++ != '='){ @@ -289,7 +291,7 @@ static int ubd_setup_common(char *str, i } ubd_dev[n].file = str; ubd_dev[n].cow.file = backing_file; - ubd_dev[n].boot_openflags = global_openflags | perm | sync; + ubd_dev[n].boot_openflags = flags; return(0); } @@ -361,7 +363,7 @@ static void ubd_handler(void) n = read_ubd_fs(thread_fd, &req, sizeof(req)); if(n != sizeof(req)){ printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, " - "errno = %d\n", getpid(), -n); + "errno = %d\n", os_getpid(), -n); spin_lock(&REQUEST_LOCK); end_request(0); spin_unlock(&REQUEST_LOCK); @@ -552,7 +554,8 @@ static void ubd_close(struct ubd *dev) static int ubd_open_dev(struct ubd *dev) { - int err, flags, n, create_cow, *create_ptr; + struct openflags flags; + int err, n, create_cow, *create_ptr; create_cow = 0; create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL; @@ -562,7 +565,8 @@ static int ubd_open_dev(struct ubd *dev) if((dev->fd == -ENOENT) && create_cow){ n = dev - ubd_dev; - dev->fd = create_cow_file(dev->file, dev->cow.file, 1 << 9, + dev->fd = create_cow_file(dev->file, dev->cow.file, + dev->openflags, 1 << 9, &dev->cow.bitmap_offset, &dev->cow.bitmap_len, &dev->cow.data_offset); @@ -585,7 +589,8 @@ static int ubd_open_dev(struct ubd *dev) dev->cow.bitmap_len); if(err) goto error; - flags = O_RDONLY; + flags = dev->openflags; + flags.w = 0; err = open_ubd_file(dev->cow.file, &flags, NULL, NULL, NULL, NULL, NULL); if(err < 0) goto error; @@ -602,7 +607,7 @@ static int ubd_file_size(struct ubd *dev char *file; file = dev->cow.file ? dev->cow.file : dev->file; - return(file_size(file, size_out)); + return(os_file_size(file, size_out)); } static int ubd_open(struct inode *inode, struct file *filp) @@ -636,8 +641,7 @@ static int ubd_open(struct inode *inode, ubd_part[offset].nr_sects = dev->size / hardsect_sizes[offset]; } dev->count++; - if ((filp->f_mode & FMODE_WRITE) && - ((dev->openflags & ~O_SYNC) == O_RDONLY)){ + if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){ if(--dev->count == 0) ubd_close(dev); return -EROFS; } @@ -720,7 +724,7 @@ static int prepare_request(struct reques end_request(1); return(1); } - if(IS_WRITE(req) && ((dev->openflags & O_ACCMODE) == O_RDONLY)){ + if(IS_WRITE(req) && !dev->openflags.w){ printk("Write attempted on readonly ubd device %d\n", n); end_request(0); return(1); diff -urNp 36/arch/um/drivers/ubd_user.c 40/arch/um/drivers/ubd_user.c --- 36/arch/um/drivers/ubd_user.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/ubd_user.c Tue Jul 16 17:08:05 2002 @@ -23,6 +23,7 @@ #include "kern_util.h" #include "user.h" #include "ubd_user.h" +#include "os.h" #include #include @@ -183,7 +184,7 @@ static int backing_file_mismatch(char *f return(-errno); } - err = file_size(file, &actual); + err = os_file_size(file, &actual); if(err){ printk("Failed to get size of backing file \"%s\", " "errno = %d\n", file, -err); @@ -207,8 +208,8 @@ int read_cow_bitmap(int fd, void *buf, i { int err; - err = lseek64(fd, offset, SEEK_SET); - if(err != offset) return(-errno); + err = os_seek_file(fd, offset); + if(err != 0) return(-errno); err = read(fd, buf, len); if(err < 0) return(-errno); return(0); @@ -267,7 +268,7 @@ static int write_cow_header(char *cow_fi struct stat64 buf; int err; - err = lseek64(fd, 0, SEEK_SET); + err = os_seek_file(fd, 0); if(err != 0){ printk("write_cow_header - lseek failed, errno = %d\n", errno); return(-errno); @@ -302,7 +303,7 @@ static int write_cow_header(char *cow_fi goto out_free; } - err = file_size(header->backing_file, size); + err = os_file_size(header->backing_file, size); if(err){ printk("Couldn't get size of backing file '%s', errno = %d\n", header->backing_file, -*size); @@ -326,23 +327,24 @@ static int write_cow_header(char *cow_fi return(err); } -int open_ubd_file(char *file, int *openflags, char **backing_file_out, - int *bitmap_offset_out, unsigned long *bitmap_len_out, - int *data_offset_out, int *create_cow_out) +int open_ubd_file(char *file, struct openflags *openflags, + char **backing_file_out, int *bitmap_offset_out, + unsigned long *bitmap_len_out, int *data_offset_out, + int *create_cow_out) { time_t mtime; __u64 size; char *backing_file; int fd, err, sectorsize, magic, same, mode = 0644; - if((fd = open64(file, *openflags, mode)) < 0){ - if((errno == ENOENT) && (create_cow_out != NULL)) + if((fd = os_open_file(file, *openflags, mode)) < 0){ + if((fd == -ENOENT) && (create_cow_out != NULL)) *create_cow_out = 1; - if(((*openflags & O_ACCMODE) != O_RDWR) || + if(!openflags->w || ((errno != EROFS) && (errno != EACCES))) return(-errno); - *openflags &= ~O_ACCMODE; - *openflags |= O_RDONLY; - if((fd = open64(file, *openflags, mode)) < 0) return(-errno); + openflags->w = 0; + if((fd = os_open_file(file, *openflags, mode)) < 0) + return(fd); } if(backing_file_out == NULL) return(fd); @@ -383,16 +385,16 @@ int open_ubd_file(char *file, int *openf return(err); } -int create_cow_file(char *cow_file, char *backing_file, int sectorsize, - int *bitmap_offset_out, unsigned long *bitmap_len_out, - int *data_offset_out) +int create_cow_file(char *cow_file, char *backing_file, struct openflags flags, + int sectorsize, int *bitmap_offset_out, + unsigned long *bitmap_len_out, int *data_offset_out) { __u64 blocks; long zero; - int err, fd, i, flags; + int err, fd, i; long long size; - flags = O_RDWR | O_CREAT; + flags.c = 1; fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL); if(fd < 0){ err = fd; @@ -476,7 +478,7 @@ void do_io(struct io_thread_req *req) len = (end - start) * req->sectorsize; buf = &req->buffer[start * req->sectorsize]; - if(lseek64(req->fds[bit], off, SEEK_SET) != off){ + if(os_seek_file(req->fds[bit], off) != 0){ printk("do_io - lseek failed : errno = %d\n", errno); req->error = 1; return; @@ -512,8 +514,7 @@ void do_io(struct io_thread_req *req) } while(start < nsectors); if(req->cow_offset != -1){ - if(lseek64(req->fds[1], req->cow_offset, SEEK_SET) != - req->cow_offset){ + if(os_seek_file(req->fds[1], req->cow_offset) != 0){ printk("do_io - bitmap lseek failed : errno = %d\n", errno); req->error = 1; @@ -561,11 +562,11 @@ int io_thread(void *arg) int start_io_thread(unsigned long sp, int *fd_out) { - int pid, fds[2]; + int pid, fds[2], err; - if(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0){ - printk("start_io_thread - socketpair failed, errno = %d\n", - errno); + err = os_pipe(fds, 1); + if(err){ + printk("start_io_thread - os_pipe failed, errno = %d\n", -err); return(-1); } kernel_fd = fds[0]; diff -urNp 36/arch/um/drivers/xterm.c 40/arch/um/drivers/xterm.c --- 36/arch/um/drivers/xterm.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/drivers/xterm.c Tue Jul 16 17:08:05 2002 @@ -17,6 +17,7 @@ #include "helper.h" #include "user_util.h" #include "user.h" +#include "os.h" struct xterm_chan { int pid; @@ -54,8 +55,8 @@ int xterm_open(int input, int output, in return(-ENODEV); } dev[strlen("/dev/")] = 't'; - slave = open(dev, O_RDWR); - if(slave == -1) return(-errno); + slave = os_open_file(dev, of_rdwr(OPENFLAGS()), 0); + if(slave < 0) return(slave); tcgetattr(slave, &data->tt); raw(slave, 0); diff -urNp 36/arch/um/include/kern.h 40/arch/um/include/kern.h --- 36/arch/um/include/kern.h Tue Jul 16 17:07:52 2002 +++ 40/arch/um/include/kern.h Tue Jul 16 17:08:05 2002 @@ -15,7 +15,6 @@ extern int errno; -extern int getpid(void); extern int clone(int (*proc)(void *), void *sp, int flags, void *data); extern int sleep(int); extern int printf(char *fmt, ...); diff -urNp 36/arch/um/include/mconsole.h 40/arch/um/include/mconsole.h --- 36/arch/um/include/mconsole.h Tue Jul 16 17:07:52 2002 +++ 40/arch/um/include/mconsole.h Tue Jul 16 17:08:05 2002 @@ -1,5 +1,6 @@ /* * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -59,6 +60,7 @@ extern char mconsole_socket_name[]; extern int mconsole_unlink_socket(void); extern int mconsole_reply(struct mc_request *req, char *reply, int err, int more); + extern void mconsole_version(struct mc_request *req); extern void mconsole_help(struct mc_request *req); extern void mconsole_halt(struct mc_request *req); @@ -67,6 +69,9 @@ extern void mconsole_config(struct mc_re extern void mconsole_remove(struct mc_request *req); extern void mconsole_sysrq(struct mc_request *req); extern void mconsole_cad(struct mc_request *req); +extern void mconsole_stop(struct mc_request *req); +extern void mconsole_go(struct mc_request *req); + extern int mconsole_create_listening_socket(void); extern int mconsole_get_request(int fd, struct mc_request *req); extern int mconsole_notify(char *sock_name, int type, const void *data, diff -urNp 36/arch/um/include/net_kern.h 40/arch/um/include/net_kern.h --- 36/arch/um/include/net_kern.h Thu Jan 1 01:00:00 1970 +++ 40/arch/um/include/net_kern.h Tue Jul 16 17:08:05 2002 @@ -0,0 +1,75 @@ +#ifndef __UM_NET_KERN_H +#define __UM_NET_KERN_H + +#include "linux/netdevice.h" +#include "linux/skbuff.h" +#include "linux/socket.h" +#include "linux/list.h" + +#define MAX_UML_NETDEV (16) + +struct uml_net { + struct net_device *dev; + struct net_user_info *user; + struct net_kern_info *kern; + int private_size; + int transport_index; + unsigned char mac[ETH_ALEN]; + int have_mac; +}; + +struct uml_net_private { + struct list_head list; + spinlock_t lock; + struct net_device *dev; + struct timer_list tl; + struct net_device_stats stats; + int fd; + unsigned char mac[ETH_ALEN]; + int have_mac; + unsigned short (*protocol)(struct sk_buff *); + int (*open)(void *); + void (*close)(int, void *); + void (*remove)(void *); + int (*read)(int, struct sk_buff **skb, struct uml_net_private *); + int (*write)(int, struct sk_buff **skb, struct uml_net_private *); + + void (*add_address)(unsigned char *, unsigned char *, void *); + void (*delete_address)(unsigned char *, unsigned char *, void *); + int (*set_mtu)(int mtu, void *); + int user[1]; +}; + +struct net_kern_info { + struct net_device *(*init)(int, int); + unsigned short (*protocol)(struct sk_buff *); + int (*read)(int, struct sk_buff **skb, struct uml_net_private *); + int (*write)(int, struct sk_buff **skb, struct uml_net_private *); +}; + +struct transport { + struct list_head list; + char *name; + int (*setup)(char *, struct uml_net *); +}; + +extern struct net_device *ether_init(int); +extern unsigned short ether_protocol(struct sk_buff *); +extern int setup_etheraddr(char *str, unsigned char *addr); +extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra); +extern int tap_setup_common(char *str, char *type, char **dev_name, + char *hw_addr, int *hw_setup, char **gate_addr); +extern void register_transport(struct transport *new); + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -urNp 36/arch/um/include/net_user.h 40/arch/um/include/net_user.h --- 36/arch/um/include/net_user.h Thu Jan 1 01:00:00 1970 +++ 40/arch/um/include/net_user.h Tue Jul 16 17:08:05 2002 @@ -0,0 +1,57 @@ +#ifndef __UM_NET_USER_H__ +#define __UM_NET_USER_H__ + +#define ETH_ADDR_LEN (6) +#define ETH_HEADER_ETHERTAP (16) +#define ETH_HEADER_OTHER (14) +#define ETH_MAX_PACKET (1500) + +#define UML_NET_VERSION (4) + +struct net_user_info { + void (*init)(void *, void *); + int (*open)(void *); + void (*close)(int, void *); + void (*remove)(void *); + int (*set_mtu)(int mtu, void *); + void (*add_address)(unsigned char *, unsigned char *, void *); + void (*delete_address)(unsigned char *, unsigned char *, void *); + int max_packet; +}; + +extern void ether_user_init(void *data, void *dev); +extern void dev_ip_addr(void *d, char *buf, char *bin_buf); +extern void set_ether_mac(void *d, unsigned char *addr); +extern void iter_addresses(void *d, void (*cb)(unsigned char *, + unsigned char *, void *), + void *arg); + +extern void *get_output_buffer(int *len_out); +extern void free_output_buffer(void *buffer); + +extern int tap_open_common(void *dev, char *gate_addr); +extern void tap_check_ips(char *gate_addr, char *eth_addr); + +extern void read_output(int fd, char *output_out, int len); + +extern int net_read(int fd, void *buf, int len); +extern int net_recvfrom(int fd, void *buf, int len); +extern int net_write(int fd, void *buf, int len); +extern int net_send(int fd, void *buf, int len); +extern int net_sendto(int fd, void *buf, int len, void *to, int sock_len); + +extern void open_addr(unsigned char *addr, unsigned char *netmask, void *arg); +extern void close_addr(unsigned char *addr, unsigned char *netmask, void *arg); + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -urNp 36/arch/um/include/os.h 40/arch/um/include/os.h --- 36/arch/um/include/os.h Thu Jan 1 01:00:00 1970 +++ 40/arch/um/include/os.h Tue Jul 16 17:08:05 2002 @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __OS_H__ +#define __OS_H__ + +#include "asm/types.h" +#include "../os/include/file.h" + +struct openflags { + unsigned int r : 1; + unsigned int w : 1; + unsigned int s : 1; /* O_SYNC */ + unsigned int c : 1; /* O_CREAT */ + unsigned int t : 1; /* O_TRUNC */ + unsigned int a : 1; /* O_APPEND */ + unsigned int e : 1; /* O_EXCL */ +}; + +#define OPENFLAGS() ((struct openflags) { r : 0, w : 0, c : 0, s : 0 }) + +static inline struct openflags of_read(struct openflags flags){ + flags.r = 1; + return(flags); +} + +static inline struct openflags of_write(struct openflags flags){ + flags.w = 1; + return(flags); +} + +static inline struct openflags of_rdwr(struct openflags flags){ + return(of_read(of_write(flags))); +} + +static inline struct openflags of_set_rw(struct openflags flags, int r, int w){ + flags.r = r; + flags.w = w; + return(flags); +} + +static inline struct openflags of_sync(struct openflags flags){ + flags.s = 1; + return(flags); +} + +static inline struct openflags of_create(struct openflags flags){ + flags.c = 1; + return(flags); +} + +static inline struct openflags of_trunc(struct openflags flags){ + flags.t = 1; + return(flags); +} + +static inline struct openflags of_append(struct openflags flags){ + flags.a = 1; + return(flags); +} + +static inline struct openflags of_excl(struct openflags flags){ + flags.e = 1; + return(flags); +} + +extern int os_seek_file(int fd, __u64 offset); +extern int os_open_file(char *file, struct openflags flags, int mode); +extern int os_file_size(char *file, long long *size_out); +extern int os_pipe(int *fd, int stream); +extern int os_set_fd_async(int fd, int owner); +extern int os_set_fd_block(int fd, int blocking); +extern int os_accept_connection(int fd); +extern void os_shutdown_socket(int fd); +extern void os_close_file(int fd); + +extern unsigned long os_process_pc(int pid); +extern int os_process_parent(int pid); +extern void os_stop_process(int pid); +extern void os_kill_process(int pid); +extern void os_usr1_process(int pid); +extern int os_getpid(void); + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -urNp 36/arch/um/include/sigio.h 40/arch/um/include/sigio.h --- 36/arch/um/include/sigio.h Tue Jul 16 17:07:52 2002 +++ 40/arch/um/include/sigio.h Tue Jul 16 17:08:05 2002 @@ -9,7 +9,7 @@ extern int write_sigio_irq(int fd); extern int register_sigio_fd(int fd); extern int read_sigio_fd(int fd); -extern int add_sigio_fd(int fd); +extern int add_sigio_fd(int fd, int read); extern int ignore_sigio_fd(int fd); #endif diff -urNp 36/arch/um/include/ubd_user.h 40/arch/um/include/ubd_user.h --- 36/arch/um/include/ubd_user.h Tue Jul 16 17:07:52 2002 +++ 40/arch/um/include/ubd_user.h Tue Jul 16 17:08:05 2002 @@ -7,6 +7,8 @@ #ifndef __UM_UBD_USER_H #define __UM_UBD_USER_H +#include "os.h" + enum ubd_req { UBD_READ, UBD_WRITE }; struct io_thread_req { @@ -23,10 +25,12 @@ struct io_thread_req { int error; }; -extern int open_ubd_file(char *file, int *openflags, char **backing_file_out, - int *bitmap_offset_out, unsigned long *bitmap_len_out, - int *data_offset_out, int *create_cow_out); -extern int create_cow_file(char *cow_file, char *backing_file, int sectorsize, +extern int open_ubd_file(char *file, struct openflags *openflags, + char **backing_file_out, int *bitmap_offset_out, + unsigned long *bitmap_len_out, int *data_offset_out, + int *create_cow_out); +extern int create_cow_file(char *cow_file, char *backing_file, + struct openflags flags, int sectorsize, int *bitmap_offset_out, unsigned long *bitmap_len_out, int *data_offset_out); diff -urNp 36/arch/um/include/user_util.h 40/arch/um/include/user_util.h --- 36/arch/um/include/user_util.h Tue Jul 16 17:07:52 2002 +++ 40/arch/um/include/user_util.h Tue Jul 16 17:08:05 2002 @@ -44,7 +44,8 @@ extern unsigned long _stext, _etext, _sd extern unsigned long _unprotected_end; extern unsigned long brk_start; -extern int pty_sigio_works; +extern int pty_output_sigio; +extern int pty_close_sigio; extern void *open_maps(void); extern void close_maps(void *fd); @@ -55,9 +56,6 @@ extern void stack_protections(unsigned l extern void task_protections(unsigned long address); extern void abandon_proc_space(int (*proc)(void *), unsigned long sp); extern int signals(int (*init_proc)(void *), void *sp); -extern void stop_pid(int pid); -extern void kill_pid(int pid); -extern void usr1_pid(int pid); extern int __personality(int); extern int wait_for_stop(int pid, int sig, int cont_type, void *relay); extern void *add_signal_handler(int sig, void (*handler)(int)); @@ -107,14 +105,12 @@ extern void check_sigio(void); extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr); extern int user_read(int fd, char *buf, int len); extern int user_write(int fd, char *buf, int len); -extern void write_sigio_workaround(int fd); +extern void write_sigio_workaround(void); extern void arch_check_bugs(void); extern int arch_handle_signal(int sig, struct uml_pt_regs *regs); -extern int file_size(char *file, long long *size_out); extern void user_time_init(void); extern unsigned long pid_pc(int pid); extern int arch_fixup(unsigned long address, void *sc_ptr); -extern int user_pipe(int *fds); #endif diff -urNp 36/arch/um/kernel/exec_kern.c 40/arch/um/kernel/exec_kern.c --- 36/arch/um/kernel/exec_kern.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/kernel/exec_kern.c Tue Jul 16 17:08:05 2002 @@ -16,6 +16,7 @@ #include "irq_user.h" #include "tlb.h" #include "2_5compat.h" +#include "os.h" /* See comment above fork_tramp for why sigstop is defined and used like * this @@ -29,7 +30,7 @@ static int exec_tramp(void *sig_stack) block_signals(); init_new_thread(sig_stack, NULL); - kill(getpid(), sig); + kill(os_getpid(), sig); return(0); } @@ -59,7 +60,7 @@ void flush_thread(void) current->thread.request.op = OP_EXEC; current->thread.request.u.exec.pid = new_pid; unprotect_stack((unsigned long) current); - usr1_pid(getpid()); + os_usr1_process(os_getpid()); free_page(stack); protect(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1); diff -urNp 36/arch/um/kernel/frame.c 40/arch/um/kernel/frame.c --- 36/arch/um/kernel/frame.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/kernel/frame.c Tue Jul 16 17:08:05 2002 @@ -21,6 +21,7 @@ #include "frame_user.h" #include "kern_util.h" #include "ptrace_user.h" +#include "os.h" static int capture_stack(int (*child)(void *arg), void *arg, void *sp, unsigned long top, void **data_out) @@ -126,7 +127,7 @@ static void child_common(void *sp, int s _exit(1); } - kill(getpid(), SIGSTOP); + os_stop_process(os_getpid()); } struct sc_frame signal_frame_sc; @@ -150,7 +151,7 @@ static void sc_handler(int sig, struct s raw_sc->sr = frame_restorer(); raw_sc->sp = frame_sp(); setup_arch_frame_raw(&raw_sc->arch, &sc); - kill(getpid(), SIGSTOP); + os_stop_process(os_getpid()); _exit(0); } @@ -183,7 +184,7 @@ static void si_handler(int sig, siginfo_ raw_si->si = (unsigned long) si; raw_si->sr = frame_restorer(); raw_si->sp = frame_sp(); - kill(getpid(), SIGSTOP); + os_stop_process(os_getpid()); _exit(0); } diff -urNp 36/arch/um/kernel/helper.c 40/arch/um/kernel/helper.c --- 36/arch/um/kernel/helper.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/kernel/helper.c Tue Jul 16 17:08:05 2002 @@ -13,6 +13,7 @@ #include #include "user.h" #include "kern_util.h" +#include "os.h" struct helper_data { void (*pre_exec)(void*); @@ -56,9 +57,10 @@ int run_helper(void (*pre_exec)(void *), else stack = alloc_stack(0); if(stack == 0) return(-ENOMEM); - if(pipe(fds) < 0){ - printk("run_helper : pipe failed, errno = %d\n", errno); - return(-errno); + err = os_pipe(fds, 1); + if(err){ + printk("run_helper : pipe failed, errno = %d\n", -err); + return(err); } if(fcntl(fds[1], F_SETFD, 1) != 0){ printk("run_helper : setting FD_CLOEXEC failed, errno = %d\n", diff -urNp 36/arch/um/kernel/initrd_kern.c 40/arch/um/kernel/initrd_kern.c --- 36/arch/um/kernel/initrd_kern.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/kernel/initrd_kern.c Tue Jul 16 17:08:05 2002 @@ -11,6 +11,7 @@ #include "kern_util.h" #include "initrd.h" #include "init.h" +#include "os.h" static char *initrd __initdata = NULL; @@ -21,7 +22,7 @@ static int __init read_initrd(void) int err; if(initrd == NULL) return 0; - err = file_size(initrd, &size); + err = os_file_size(initrd, &size); if(err) return 0; area = alloc_bootmem(size); if(area == NULL) return 0; diff -urNp 36/arch/um/kernel/initrd_user.c 40/arch/um/kernel/initrd_user.c --- 36/arch/um/kernel/initrd_user.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/kernel/initrd_user.c Tue Jul 16 17:08:05 2002 @@ -13,12 +13,13 @@ #include "kern_util.h" #include "user.h" #include "initrd.h" +#include "os.h" int load_initrd(char *filename, void *buf, int size) { int fd, n; - if((fd = open(filename, O_RDONLY)) == -1){ + if((fd = os_open_file(filename, of_read(OPENFLAGS()), 0)) < 0){ printk("Opening '%s' failed - errno = %d\n", filename, errno); return(-1); } diff -urNp 36/arch/um/kernel/irq_user.c 40/arch/um/kernel/irq_user.c --- 36/arch/um/kernel/irq_user.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/kernel/irq_user.c Tue Jul 16 17:08:05 2002 @@ -19,6 +19,7 @@ #include "signal_user.h" #include "sigio.h" #include "irq_user.h" +#include "os.h" struct irq_fd { struct irq_fd *next; @@ -77,29 +78,23 @@ void sigio_handler(int sig, struct uml_p } } -static int prepare_fd_async(int fd, int pid) +int activate_ipi(int fd, int pid) { - int retval; - - if((retval = fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK)) < 0){ - printk("Failed to set O_ASYNC and O_NONBLOCK on fd # %d, " - "errno = %d\n", fd, errno); - return(-retval); - } - - if(((retval = fcntl(fd, F_SETSIG, SIGIO)) < 0) || - ((retval = fcntl(fd, F_SETOWN, pid)) < 0)){ - printk("Failed to fcntl F_SETOWN (or F_SETSIG) " - "fd %d to pid %d, errno = %d\n", fd, pid, errno); - return(-retval); - } - - return(0); + return(os_set_fd_async(fd, pid)); } -int activate_ipi(int fd, int pid) +static void maybe_sigio_broken(int fd, int type) { - return prepare_fd_async(fd, pid); + if(isatty(fd)){ + if((type == IRQ_WRITE) && !pty_output_sigio){ + write_sigio_workaround(); + add_sigio_fd(fd, 0); + } + else if((type == IRQ_READ) && !pty_close_sigio){ + write_sigio_workaround(); + add_sigio_fd(fd, 1); + } + } } int activate_fd(int irq, int fd, int type, void *dev_id) @@ -116,7 +111,7 @@ int activate_fd(int irq, int fd, int typ } } pid = cpu_tasks[0].pid; - if ((retval = prepare_fd_async(fd, pid)) != 0) + if((retval = os_set_fd_async(fd, pid)) != 0) return(retval); new_fd = um_kmalloc(sizeof(*new_fd)); err = -ENOMEM; @@ -159,10 +154,7 @@ int activate_fd(int irq, int fd, int typ events : events, revents : 0 }); - if((type == IRQ_WRITE) && isatty(fd) && (pty_sigio_works == 0)){ - write_sigio_workaround(fd); - add_sigio_fd(fd); - } + maybe_sigio_broken(fd, type); return(0); @@ -253,10 +245,7 @@ void reactivate_fd(int fd, int irqnum) irq = find_irq_by_fd(fd, irqnum, &i); if(irq == NULL) return; pollfds[i].events = irq->events; - if((irq->type == IRQ_WRITE) && isatty(fd) && (pty_sigio_works == 0)){ - write_sigio_workaround(fd); - add_sigio_fd(fd); - } + maybe_sigio_broken(fd, irq->type); } void deactivate_fd(int fd, int irqnum) @@ -276,7 +265,7 @@ void forward_ipi(int fd, int pid) if(fcntl(fd, F_GETOWN, 0) != pid){ printk("forward_ipi: F_SETOWN failed, fd = %d, " "me = %d, target = %d, errno = %d\n", fd, - getpid(), pid, save_errno); + os_getpid(), pid, save_errno); } } } diff -urNp 36/arch/um/kernel/mem_user.c 40/arch/um/kernel/mem_user.c --- 36/arch/um/kernel/mem_user.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/kernel/mem_user.c Tue Jul 16 17:08:05 2002 @@ -45,6 +45,7 @@ #include "user_util.h" #include "mem_user.h" #include "init.h" +#include "os.h" struct mem_region physmem_region; @@ -62,7 +63,7 @@ int create_mem_file(unsigned long len) perror("fchmod"); exit(1); } - if(lseek(fd, len, SEEK_SET) < 0){ + if(os_seek_file(fd, len) < 0){ perror("lseek"); exit(1); } @@ -153,7 +154,7 @@ static int __init parse_iomem(char *str, } *file = '\0'; file++; - fd = open(file, O_RDWR); + fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0); if(fd < 0){ printk("parse_iomem - Couldn't open io file, errno = %d\n", errno); @@ -183,10 +184,13 @@ void log(char *fmt, ...) { va_list ap; struct timeval tv; + struct openflags flags; if(logging == 0) return; - if(logging_fd == -1) - logging_fd = open("log", O_RDWR | O_CREAT | O_TRUNC, 0644); + if(logging_fd < 0){ + flags = of_create(of_trunc(of_rdrw(OPENFLAGS()))); + logging_fd = os_open_file("log", flags, 0644); + } gettimeofday(&tv, NULL); sprintf(logging_buf, "%d\t %u.%u ", logging_line++, tv.tv_sec, tv.tv_usec); diff -urNp 36/arch/um/kernel/process.c 40/arch/um/kernel/process.c --- 36/arch/um/kernel/process.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/kernel/process.c Tue Jul 16 17:08:05 2002 @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -37,21 +36,7 @@ #include "syscall_user.h" #include "ptrace_user.h" #include "init.h" - -void stop_pid(int pid) -{ - kill(pid, SIGSTOP); -} - -void kill_pid(int pid) -{ - kill(pid, SIGKILL); -} - -void usr1_pid(int pid) -{ - kill(pid, SIGUSR1); -} +#include "os.h" void init_new_thread(void *sig_stack, void (*usr1_handler)(int)) { @@ -103,7 +88,7 @@ int outer_tramp(void *arg) t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2, t->flags, t->tramp_data); if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL); - kill(getpid(), sig); + kill(os_getpid(), sig); _exit(0); } @@ -166,7 +151,7 @@ void suspend_new_thread(int fd) { char c; - kill(getpid(), SIGSTOP); + os_stop_process(os_getpid()); if(read(fd, &c, sizeof(c)) != sizeof(c)) panic("read failed in suspend_new_thread"); @@ -174,14 +159,14 @@ void suspend_new_thread(int fd) static int ptrace_child(void *arg) { - int pid = getpid(); + int pid = os_getpid(); if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ perror("ptrace"); _exit(1); } - kill(pid, SIGSTOP); - _exit(getpid() == pid); + os_stop_process(pid); + _exit(os_getpid() == pid); } void __init check_ptrace(void) @@ -248,35 +233,6 @@ int run_kernel_thread(int (*fn)(void *), return(0); } -unsigned long pid_pc(int pid) -{ - char proc_stat[sizeof("/proc/#####/stat\0")], buf[256]; - unsigned long pc; - int fd; - - sprintf(proc_stat, "/proc/%d/stat", pid); - fd = open(proc_stat, O_RDONLY); - if(fd < 0){ - printk("pid_pc - couldn't open '%s', errno = %d\n", proc_stat, - errno); - return(-1); - } - if(read(fd, buf, sizeof(buf)) < 0){ - printk("pid_pc - couldn't read '%s', errno = %d\n", proc_stat, - errno); - close(fd); - return(-1); - } - close(fd); - pc = -1; - if(sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*d %*d %*d " - "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d " - "%*d %*d %*d %*d %ld", &pc) != 1){ - printk("pid_pc - couldn't find pc in '%s'\n", buf); - } - return(pc); -} - /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically diff -urNp 36/arch/um/kernel/process_kern.c 40/arch/um/kernel/process_kern.c --- 36/arch/um/kernel/process_kern.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/kernel/process_kern.c Tue Jul 16 17:08:05 2002 @@ -38,6 +38,7 @@ #include "frame_kern.h" #include "sigcontext.h" #include "2_5compat.h" +#include "os.h" struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } }; @@ -97,9 +98,12 @@ void free_stack(unsigned long stack, int void set_init_pid(int pid) { + int err; + init_task.thread.extern_pid = pid; - if(pipe(init_task.thread.switch_pipe) < 0) - panic("Can't create switch pipe for init_task"); + err = os_pipe(init_task.thread.switch_pipe, 1); + if(err) panic("Can't create switch pipe for init_task, errno = %d", + err); } int set_user_mode(void *t, int protect_mem) @@ -110,7 +114,7 @@ int set_user_mode(void *t, int protect_m if(task->thread.tracing) return(1); task->thread.request.op = OP_TRACE_ON; if(protect_mem) protect_kernel_mem(1); - usr1_pid(getpid()); + os_usr1_process(os_getpid()); return(0); } @@ -162,7 +166,7 @@ static int new_thread_proc(void *stack) { block_signals(); init_new_thread(stack, new_thread_handler); - usr1_pid(getpid()); + os_usr1_process(os_getpid()); } int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) @@ -218,7 +222,7 @@ void *_switch_to(void *prev, void *next) if(err != sizeof(c)) panic("write of switch_pipe failed, errno = %d", -err); - if(from->state == TASK_ZOMBIE) kill_pid(getpid()); + if(from->state == TASK_ZOMBIE) os_kill_process(os_getpid()); err = user_read(from->thread.switch_pipe[0], &c, sizeof(c)); if(err != sizeof(c)) @@ -244,7 +248,7 @@ void ret_from_sys_call(void) void release_thread(struct task_struct *task) { - kill_pid(task->thread.extern_pid); + os_kill_process(task->thread.extern_pid); } void exit_thread(void) @@ -295,7 +299,7 @@ int fork_tramp(void *stack) block_signals(); init_new_thread(stack, finish_fork_handler); - kill(getpid(), sig); + kill(os_getpid(), sig); return(0); } @@ -317,8 +321,8 @@ int copy_thread(int nr, unsigned long cl p->thread.request.u.thread = current->thread.request.u.thread; } - err = user_pipe(p->thread.switch_pipe); - if(err < 0){ + err = os_pipe(p->thread.switch_pipe, 1); + if(err){ printk("copy_thread : pipe failed, errno = %d\n", -err); return(err); } @@ -349,32 +353,32 @@ int copy_thread(int nr, unsigned long cl current->thread.request.op = OP_FORK; current->thread.request.u.fork.pid = new_pid; - usr1_pid(getpid()); + os_usr1_process(os_getpid()); return(0); } void tracing_reboot(void) { current->thread.request.op = OP_REBOOT; - usr1_pid(getpid()); + os_usr1_process(os_getpid()); } void tracing_halt(void) { current->thread.request.op = OP_HALT; - usr1_pid(getpid()); + os_usr1_process(os_getpid()); } void tracing_cb(void (*proc)(void *), void *arg) { - if(getpid() == tracing_pid){ + if(os_getpid() == tracing_pid){ (*proc)(arg); } else { current->thread.request.op = OP_CB; current->thread.request.u.cb.proc = proc; current->thread.request.u.cb.arg = arg; - usr1_pid(getpid()); + os_usr1_process(os_getpid()); } } diff -urNp 36/arch/um/kernel/reboot.c 40/arch/um/kernel/reboot.c --- 36/arch/um/kernel/reboot.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/kernel/reboot.c Tue Jul 16 17:08:05 2002 @@ -7,18 +7,20 @@ #include "user_util.h" #include "kern_util.h" #include "kern.h" +#include "os.h" static void kill_off_processes(void) { struct task_struct *p; int me; - me = getpid(); + me = os_getpid(); for_each_task(p){ - if(p->thread.extern_pid != me) kill_pid(p->thread.extern_pid); + if(p->thread.extern_pid != me) + os_kill_process(p->thread.extern_pid); } if(init_task.thread.extern_pid != me) - kill_pid(init_task.thread.extern_pid); + os_kill_process(init_task.thread.extern_pid); } void uml_cleanup(void) @@ -32,7 +34,7 @@ void machine_restart(char * __unused) do_uml_exitcalls(); kill_off_processes(); tracing_reboot(); - kill_pid(getpid()); + os_kill_process(os_getpid()); } void machine_power_off(void) @@ -40,7 +42,7 @@ void machine_power_off(void) do_uml_exitcalls(); kill_off_processes(); tracing_halt(); - kill_pid(getpid()); + os_kill_process(os_getpid()); } void machine_halt(void) diff -urNp 36/arch/um/kernel/sigio_user.c 40/arch/um/kernel/sigio_user.c --- 36/arch/um/kernel/sigio_user.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/kernel/sigio_user.c Tue Jul 16 17:08:05 2002 @@ -19,8 +19,10 @@ #include "kern_util.h" #include "sigio.h" #include "helper.h" +#include "os.h" -int pty_sigio_works = 0; +int pty_output_sigio = 0; +int pty_close_sigio = 0; static int got_sigio = 0; @@ -45,20 +47,12 @@ static int openpty_cb(void *arg) return(0); } -void __init check_sigio(void) +void __init check_one_sigio(void (*proc)(int, int)) { struct sigaction old, new; struct termios tt; struct openpty_arg pty; - int master, slave, flags, n, err; - char buf[512]; - - if(access("/dev/ptmx", R_OK) && access("/dev/ptyp0", R_OK)){ - printk("No pseudo-terminals available - skipping pty SIGIO " - "check\n"); - return; - } - printk("Checking that host ptys support output SIGIO..."); + int master, slave, flags, err; err = run_helper_thread(openpty_cb, &pty, CLONE_FILES, NULL, 2); if(err < 0){ @@ -83,7 +77,7 @@ void __init check_sigio(void) panic("tty_fds : fcntl F_GETFL failed, errno = %d\n", errno); if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || - (fcntl(master, F_SETOWN, getpid()) < 0)) + (fcntl(master, F_SETOWN, os_getpid()) < 0)) panic("check_sigio : fcntl F_SETFL or F_SETOWN failed, " "errno = %d\n", errno); @@ -97,7 +91,24 @@ void __init check_sigio(void) new.sa_handler = handler; if(sigaction(SIGIO, &new, NULL) < 0) panic("check_sigio : sigaction 2 failed, errno = %d\n", errno); + + got_sigio = 0; + (*proc)(master, slave); + close(master); + close(slave); + + if(sigaction(SIGIO, &old, NULL) < 0) + panic("check_sigio : sigaction 3 failed, errno = %d\n", errno); +} + +static void tty_output(int master, int slave) +{ + int n; + char buf[512]; + + printk("Checking that host ptys support output SIGIO..."); + while(write(master, buf, sizeof(buf)) > 0) ; if(errno != EAGAIN) panic("check_sigio : write failed, errno = %d\n", errno); @@ -106,16 +117,33 @@ void __init check_sigio(void) if(got_sigio){ printk("Yes\n"); - pty_sigio_works = 1; + pty_output_sigio = 1; } else if(errno == EAGAIN) printk("No, enabling workaround\n"); else panic("check_sigio : read failed, errno = %d\n", errno); +} + +static void tty_close(int master, int slave) +{ + printk("Checking that host ptys support SIGIO on close..."); - close(master); close(slave); + if(got_sigio){ + printk("Yes\n"); + pty_close_sigio = 1; + } + else printk("No, enabling workaround\n"); +} - if(sigaction(SIGIO, &old, NULL) < 0) - panic("check_sigio : sigaction 3 failed, errno = %d\n", errno); +void __init check_sigio(void) +{ + if(access("/dev/ptmx", R_OK) && access("/dev/ptyp0", R_OK)){ + printk("No pseudo-terminals available - skipping pty SIGIO " + "check\n"); + return; + } + check_one_sigio(tty_output); + check_one_sigio(tty_close); } static int write_sigio_pid = -1; @@ -236,9 +264,9 @@ static void update_thread(void) set_signals(flags); } -int add_sigio_fd(int fd) +int add_sigio_fd(int fd, int read) { - int err, i, n; + int err, i, n, events; for(i = 0; i < current_poll.used; i++) if(current_poll.poll[i].fd == fd) return(0); @@ -250,8 +278,11 @@ int add_sigio_fd(int fd) for(i = 0; i < current_poll.used; i++) next_poll.poll[i] = current_poll.poll[i]; + if(read) events = POLLIN; + else events = POLLOUT; + next_poll.poll[n - 1] = ((struct pollfd) { fd : fd, - events : POLLOUT, + events : events, revents : 0 }); update_thread(); return(0); @@ -301,21 +332,24 @@ static int setup_initial_poll(int fd) return(0); } -void write_sigio_workaround(int fd) +void write_sigio_workaround(void) { unsigned long stack; + int err; - if((write_sigio_pid != -1) || pty_sigio_works || !isatty(fd)) return; + if(write_sigio_pid != -1) return; /* XXX This needs SMP locking */ - if(socketpair(AF_UNIX, SOCK_STREAM, 0, write_sigio_fds) < 0){ - printk("write_sigio_workaround - socketpair 1 failed, " - "errno = %d\n", errno); + err = os_pipe(write_sigio_fds, 1); + if(err){ + printk("write_sigio_workaround - os_pipe 1 failed, " + "errno = %d\n", -err); return; } - if(socketpair(AF_UNIX, SOCK_STREAM, 0, sigio_private) < 0){ - printk("write_sigio_workaround - socketpair 2 failed, " - "errno = %d\n", errno); + err = os_pipe(sigio_private, 1); + if(err){ + printk("write_sigio_workaround - os_pipe 2 failed, " + "errno = %d\n", -err); goto out_close1; } if(setup_initial_poll(sigio_private[1])) diff -urNp 36/arch/um/kernel/smp.c 40/arch/um/kernel/smp.c --- 36/arch/um/kernel/smp.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/kernel/smp.c Tue Jul 16 17:08:05 2002 @@ -103,15 +103,17 @@ void smp_commence(void) static int idle_proc(void *unused) { - int cpu; + int cpu, err; set_current(current); del_from_runqueue(current); unhash_process(current); cpu = current->processor; - if (socketpair(AF_UNIX, SOCK_STREAM, 0, cpu_data[cpu].ipi_pipe) < 0) - panic("CPU#%d failed to create IPI pipe", cpu); + err = os_pipe(cpu_data[cpu].ipi_pipe, 1); + if(err){ + panic("CPU#%d failed to create IPI pipe, errno = %d", cpu, + -err); activate_ipi(cpu_data[cpu].ipi_pipe[0], current->thread.extern_pid); @@ -156,11 +158,14 @@ static int idle_thread(int (*fn)(void *) void smp_boot_cpus(void) { + int err; + set_bit(0, &cpu_online_map); set_bit(0, &smp_callin_map); - if (socketpair(AF_UNIX, SOCK_STREAM, 0, cpu_data[0].ipi_pipe) < 0) - panic("CPU#0 failed to create IPI pipe"); + err = os_pipe(cpu_data[0].ipi_pipe, 1); + if(err) panic("CPU#0 failed to create IPI pipe, errno = %d", -err); + activate_ipi(cpu_data[0].ipi_pipe[0], current->thread.extern_pid); if(ncpus < 1){ @@ -237,7 +242,7 @@ void IPI_handler(int cpu) int hard_smp_processor_id(void) { - return(pid_to_processor_id(getpid())); + return(pid_to_processor_id(os_getpid())); } static spinlock_t call_lock = SPIN_LOCK_UNLOCKED; diff -urNp 36/arch/um/kernel/tlb.c 40/arch/um/kernel/tlb.c --- 36/arch/um/kernel/tlb.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/kernel/tlb.c Tue Jul 16 17:08:05 2002 @@ -18,6 +18,7 @@ #include "kern_util.h" #include "kern.h" #include "tlb.h" +#include "os.h" static void fix_range(struct mm_struct *mm, unsigned long start_addr, unsigned long end_addr, int force) @@ -29,7 +30,7 @@ static void fix_range(struct mm_struct * int r, w, x, err; if((current->thread.extern_pid != -1) && - (current->thread.extern_pid != getpid())) + (current->thread.extern_pid != os_getpid())) panic("fix_range fixing wrong address space, current = 0x%p", current); if(mm == NULL) return; diff -urNp 36/arch/um/kernel/trap_user.c 40/arch/um/kernel/trap_user.c --- 36/arch/um/kernel/trap_user.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/kernel/trap_user.c Tue Jul 16 17:08:05 2002 @@ -35,6 +35,7 @@ #include "syscall_user.h" #include "ptrace_user.h" #include "task.h" +#include "os.h" static void signal_segv(int sig) { @@ -83,14 +84,14 @@ static int signal_tramp(void *arg) panic("Unmapping stack failed"); if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) panic("ptrace PTRACE_TRACEME failed"); - kill(getpid(), SIGSTOP); + os_stop_process(os_getpid()); change_sig(SIGWINCH, 0); signal(SIGUSR1, SIG_IGN); change_sig(SIGCHLD, 0); signal(SIGSEGV, (__sighandler_t) sig_handler); set_timers(0); set_cmdline("(idle thread)"); - set_init_pid(getpid()); + set_init_pid(os_getpid()); proc = arg; return((*proc)(NULL)); } @@ -140,37 +141,6 @@ static void sleeping_process_signal(int } } -static int parent_pid(int child) -{ - char stat[sizeof("/proc/nnnnn/stat\0")]; - char data[256]; - int pid, n, fd; - - if(child == -1) return(-1); - - snprintf(stat, sizeof(stat), "/proc/%d/stat", child); - fd = open(stat, O_RDONLY); - if(fd < 0){ - printk("Couldn't open '%s', errno = %d\n", stat); - return(-1); - } - - n = read(fd, data, sizeof(data)); - close(fd); - - if(n < 0){ - printk("Couldn't read '%s', errno = %d\n", stat); - return(-1); - } - - pid = -1; - /* XXX This will break if there is a space in the command */ - n = sscanf(data, "%*d %*s %*c %d", &pid); - if(n != 1) printk("Failed to scan '%s'\n", data); - - return(pid); -} - #ifdef CONFIG_SMP #error need to make these arrays #endif @@ -216,7 +186,7 @@ int signals(int (*init_proc)(void *), vo capture_signal_stack(); signal(SIGPIPE, SIG_IGN); setup_tracer_winch(); - tracing_pid = getpid(); + tracing_pid = os_getpid(); printk("tracing thread pid = %d\n", tracing_pid); pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc); @@ -244,7 +214,7 @@ int signals(int (*init_proc)(void *), vo debugger_pid = attach_debugger(pid, gdb_pid, 1); else debugger_pid = init_ptrace_proxy(pid, 1, debug_stop); if(debug_parent){ - debugger_parent = parent_pid(debugger_pid); + debugger_parent = os_process_parent(debugger_pid); init_parent_proxy(debugger_parent); err = attach(debugger_parent); if(err){ @@ -460,7 +430,7 @@ void segv_handler(int sig, struct uml_pt unlock_trap(); nsegfaults++; segfault_record[index].address = SC_FAULT_ADDR(context); - segfault_record[index].pid = getpid(); + segfault_record[index].pid = os_getpid(); segfault_record[index].is_write = SC_FAULT_WRITE(context); segfault_record[index].sp = SC_SP(context); segfault_record[index].is_user = regs->is_user; diff -urNp 36/arch/um/kernel/tty_log.c 40/arch/um/kernel/tty_log.c --- 36/arch/um/kernel/tty_log.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/kernel/tty_log.c Tue Jul 16 17:08:05 2002 @@ -49,10 +49,11 @@ int open_tty_log(void *tty) sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, (unsigned int) tv.tv_usec); - fd = open(buf, O_RDWR | O_APPEND | O_CREAT, 0644); + fd = os_open_file(buf, of_append(of_create(of_rdwr(OPENFLAGS()))), + 0644); if(fd < 0){ printk("open_tty_log : couldn't open '%s', errno = %d\n", - buf, errno); + buf, -fd); } return(fd); } diff -urNp 36/arch/um/kernel/um_arch.c 40/arch/um/kernel/um_arch.c --- 36/arch/um/kernel/um_arch.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/kernel/um_arch.c Tue Jul 16 17:08:05 2002 @@ -32,12 +32,13 @@ #include "umid.h" #include "initrd.h" #include "init.h" +#include "os.h" #define DEFAULT_COMMAND_LINE "root=/dev/ubd0" unsigned long thread_saved_pc(struct thread_struct *thread) { - return(pid_pc(thread->extern_pid)); + return(os_process_pc(thread->extern_pid)); } /* @@ -110,14 +111,14 @@ static int start_kernel_proc(void *unuse int pid; block_signals(); - pid = getpid(); + pid = os_getpid(); cpu_tasks[0].pid = pid; cpu_tasks[0].task = current; #ifdef CONFIG_SMP cpu_online_map = 1; #endif - if(debug) stop_pid(pid); + if(debug) os_stop_process(pid); start_kernel(); return(0); } diff -urNp 36/arch/um/kernel/umid.c 40/arch/um/kernel/umid.c --- 36/arch/um/kernel/umid.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/kernel/umid.c Tue Jul 16 17:08:05 2002 @@ -16,6 +16,7 @@ #include "user.h" #include "umid.h" #include "init.h" +#include "os.h" #define UMID_LEN 64 #define UML_DIR "~/.uml/" @@ -78,13 +79,15 @@ static int __init create_pid_file(void) if(umid_file_name("pid", file, sizeof(file))) return 0; - if((fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644)) < 0){ + fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), + 0644); + if(fd < 0){ printk("Open of machine pid file \"%s\" failed - " - "errno = %d\n", file, errno); + "errno = %d\n", file, -fd); return 0; } - sprintf(pid, "%d\n", (tracing_pid == -1) ? getpid() : tracing_pid); + sprintf(pid, "%d\n", (tracing_pid == -1) ? os_getpid() : tracing_pid); if(write(fd, pid, strlen(pid)) != strlen(pid)) printk("Write of pid file failed - errno = %d\n", errno); close(fd); @@ -151,10 +154,10 @@ int not_dead_yet(char *dir) sprintf(file, "%s/pid", dir); dead = 0; - if((fd = open(file, O_RDONLY)) < 0){ - if(errno != ENOENT){ + if((fd = os_open_file(file, of_read(OPENFLAGS()), 0)) < 0){ + if(fd != -ENOENT){ printk("not_dead_yet : couldn't open pid file '%s', " - "errno = %d\n", file, errno); + "errno = %d\n", file, -fd); return(1); } dead = 1; diff -urNp 36/arch/um/kernel/user_util.c 40/arch/um/kernel/user_util.c --- 36/arch/um/kernel/user_util.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/kernel/user_util.c Tue Jul 16 17:08:05 2002 @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -71,36 +70,6 @@ void remap_data(void *segment_start, voi } } -int file_size(char *file, long long *size_out) -{ - struct stat64 buf; - - if(stat64(file, &buf) == -1){ - printk("Couldn't stat \"%s\" : errno = %d\n", file, errno); - return(-errno); - } - if(S_ISBLK(buf.st_mode)){ - int fd, blocks; - - if((fd = open64(file, O_RDONLY)) < 0){ - printk("Couldn't open \"%s\", errno = %d\n", file, - errno); - return(-errno); - } - if(ioctl(fd, BLKGETSIZE, &blocks) < 0){ - printk("Couldn't get the block size of \"%s\", " - "errno = %d\n", file, errno); - close(fd); - return(-errno); - } - *size_out = ((long long) blocks) * 512; - close(fd); - return(0); - } - *size_out = buf.st_size; - return(0); -} - void stop(void) { while(1) sleep(1000000); @@ -181,46 +150,6 @@ int clone_and_wait(int (*fn)(void *), vo return(pid); } -struct grantpt_info { - int fd; - int res; - int err; -}; - -static void grantpt_cb(void *arg) -{ - struct grantpt_info *info = arg; - - info->res = grantpt(info->fd); - info->err = errno; -} - -int get_pty(void) -{ - struct grantpt_info info; - int fd; - - if((fd = open("/dev/ptmx", O_RDWR)) < 0){ - printk("get_pty : Couldn't open /dev/ptmx - errno = %d\n", - errno); - return(-1); - } - - info.fd = fd; - tracing_cb(grantpt_cb, &info); - - if(info.res < 0){ - printk("get_pty : Couldn't grant pty - errno = %d\n", - info.err); - return(-1); - } - if(unlockpt(fd) < 0){ - printk("get_pty : Couldn't unlock pty - errno = %d\n", errno); - return(-1); - } - return(fd); -} - int raw(int fd, int complain) { struct termios tt; @@ -334,15 +263,6 @@ int user_write(int fd, char *buf, int le else return(err); } -int user_pipe(int *fds) -{ - int err; - - err = pipe(fds); - if(err < 0) return(-errno); - return(0); -} - /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically diff -urNp 36/arch/um/os-Linux/Makefile 40/arch/um/os-Linux/Makefile --- 36/arch/um/os-Linux/Makefile Thu Jan 1 01:00:00 1970 +++ 40/arch/um/os-Linux/Makefile Tue Jul 16 17:08:05 2002 @@ -0,0 +1,17 @@ +# +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com) +# Licensed under the GPL +# + +O_TARGET = os.o + +obj-y = file.o process.o tty.o + +include $(TOPDIR)/Rules.make + +$(obj-y) : %.o: %.c + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $< + +clean : + +archmrproper: diff -urNp 36/arch/um/os-Linux/drivers/Makefile 40/arch/um/os-Linux/drivers/Makefile --- 36/arch/um/os-Linux/drivers/Makefile Thu Jan 1 01:00:00 1970 +++ 40/arch/um/os-Linux/drivers/Makefile Tue Jul 16 17:08:05 2002 @@ -0,0 +1,17 @@ +# +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com) +# Licensed under the GPL +# + +O_TARGET := drivers.o + +obj-y = +obj-$(CONFIG_UML_NET_ETHERTAP) += ethertap_kern.o ethertap_user.o +obj-$(CONFIG_UML_NET_TUNTAP) += tuntap_kern.o tuntap_user.o + +include $(TOPDIR)/Rules.make + +USER_OBJS = $(filter %_user.o,$(obj-y)) + +$(USER_OBJS) : %.o: %.c + $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $< diff -urNp 36/arch/um/os-Linux/drivers/etap.h 40/arch/um/os-Linux/drivers/etap.h --- 36/arch/um/os-Linux/drivers/etap.h Thu Jan 1 01:00:00 1970 +++ 40/arch/um/os-Linux/drivers/etap.h Tue Jul 16 17:08:05 2002 @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#include "net_user.h" + +struct ethertap_data { + char *dev_name; + char *gate_addr; + int data_fd; + int control_fd; + void *dev; +}; + +extern struct net_user_info ethertap_user_info; + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -urNp 36/arch/um/os-Linux/drivers/etap_kern.h 40/arch/um/os-Linux/drivers/etap_kern.h --- 36/arch/um/os-Linux/drivers/etap_kern.h Thu Jan 1 01:00:00 1970 +++ 40/arch/um/os-Linux/drivers/etap_kern.h Tue Jul 16 17:08:05 2002 @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __UM_ETHERTAP_KERN_H +#define __UM_ETHERTAP_KERN_H + +#include "net_kern.h" + +extern int ethertap_setup(char *arg, struct uml_net *dev); + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -urNp 36/arch/um/os-Linux/drivers/ethertap_kern.c 40/arch/um/os-Linux/drivers/ethertap_kern.c --- 36/arch/um/os-Linux/drivers/ethertap_kern.c Thu Jan 1 01:00:00 1970 +++ 40/arch/um/os-Linux/drivers/ethertap_kern.c Tue Jul 16 17:08:05 2002 @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and + * James Leu (jleu@mindspring.net). + * Copyright (C) 2001 by various other people who didn't put their name here. + * Licensed under the GPL. + */ + +#include "linux/init.h" +#include "linux/netdevice.h" +#include "linux/etherdevice.h" +#include "linux/init.h" +#include "net_kern.h" +#include "net_user.h" +#include "etap.h" +#include "etap_kern.h" + +struct ethertap_setup { + char *dev_name; + char *gate_addr; +}; + +struct ethertap_setup ethertap_priv[MAX_UML_NETDEV] = { + [ 0 ... MAX_UML_NETDEV - 1 ] = + { + dev_name: NULL, + gate_addr: NULL, + } +}; + +struct net_device *etap_init(int private_size, int index) +{ + struct net_device *dev; + struct uml_net_private *pri; + struct ethertap_data *epri; + + dev = init_etherdev(NULL, private_size); + if(dev == NULL) return(NULL); + pri = dev->priv; + epri = (struct ethertap_data *) pri->user; + epri->dev_name = ethertap_priv[index].dev_name; + epri->gate_addr = ethertap_priv[index].gate_addr; + printk("ethertap backend - %s", epri->dev_name); + if(epri->gate_addr != NULL) + printk(", IP = %s", epri->gate_addr); + printk("\n"); + epri->data_fd = -1; + epri->control_fd = -1; + return(dev); +} + +static unsigned short etap_protocol(struct sk_buff *skb) +{ + return(eth_type_trans(skb, skb->dev)); +} + +static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) +{ + int len; + + *skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP); + if(*skb == NULL) return(-ENOMEM); + len = net_recvfrom(fd, (*skb)->mac.raw, + (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP); + if(len <= 0) return(len); + skb_pull(*skb, 2); + len -= 2; + return(len); +} + +static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) +{ + if(skb_headroom(*skb) < 2){ + struct sk_buff *skb2; + + skb2 = skb_realloc_headroom(*skb, 2); + dev_kfree_skb(*skb); + if (skb2 == NULL) return(-ENOMEM); + *skb = skb2; + } + skb_push(*skb, 2); + return(net_send(fd, (*skb)->data, (*skb)->len)); +} + +struct net_kern_info ethertap_kern_info = { + init: etap_init, + protocol: etap_protocol, + read: etap_read, + write: etap_write, +}; + +static int ethertap_count = 0; + +int ethertap_setup(char *str, struct uml_net *dev) +{ + struct ethertap_setup *pri; + int err; + + pri = ðertap_priv[ethertap_count]; + err = tap_setup_common(str, "ethertap", &pri->dev_name, dev->mac, + &dev->have_mac, &pri->gate_addr); + if(err) return(err); + if(pri->dev_name == NULL){ + printk("ethertap_setup : Missing tap device name\n"); + return(1); + } + + dev->user = ðertap_user_info; + dev->kern = ðertap_kern_info; + dev->private_size = sizeof(struct ethertap_data); + dev->transport_index = ethertap_count++; + return(0); +} + +static struct transport ethertap_transport = { + list : LIST_HEAD_INIT(ethertap_transport.list), + name : "ethertap", + setup : ethertap_setup +}; + +static int register_ethertap(void) +{ + register_transport(ðertap_transport); + return(1); +} + +__initcall(register_ethertap); + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -urNp 36/arch/um/os-Linux/drivers/ethertap_user.c 40/arch/um/os-Linux/drivers/ethertap_user.c --- 36/arch/um/os-Linux/drivers/ethertap_user.c Thu Jan 1 01:00:00 1970 +++ 40/arch/um/os-Linux/drivers/ethertap_user.c Tue Jul 16 17:08:05 2002 @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and + * James Leu (jleu@mindspring.net). + * Copyright (C) 2001 by various other people who didn't put their name here. + * Licensed under the GPL. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "user.h" +#include "kern_util.h" +#include "net_user.h" +#include "etap.h" +#include "helper.h" +#include "os.h" + +#define MAX_PACKET ETH_MAX_PACKET + +void etap_user_init(void *data, void *dev) +{ + struct ethertap_data *pri = data; + + pri->dev = dev; +} + +struct addr_change { + enum { ADD_ADDR, DEL_ADDR } what; + unsigned char addr[4]; + unsigned char netmask[4]; +}; + +static void etap_change(int op, unsigned char *addr, unsigned char *netmask, + int fd) +{ + struct addr_change change; + void *output; + + change.what = op; + memcpy(change.addr, addr, sizeof(change.addr)); + memcpy(change.netmask, netmask, sizeof(change.netmask)); + if(write(fd, &change, sizeof(change)) != sizeof(change)) + printk("etap_change - request failed, errno = %d\n", + errno); + output = um_kmalloc(page_size()); + if(output == NULL) + printk("etap_change : Failed to allocate output buffer\n"); + read_output(fd, output, page_size()); + if(output != NULL){ + printk("%s", output); + kfree(output); + } +} + +static void etap_open_addr(unsigned char *addr, unsigned char *netmask, + void *arg) +{ + etap_change(ADD_ADDR, addr, netmask, *((int *) arg)); +} + +static void etap_close_addr(unsigned char *addr, unsigned char *netmask, + void *arg) +{ + etap_change(DEL_ADDR, addr, netmask, *((int *) arg)); +} + +struct etap_pre_exec_data { + int control_remote; + int control_me; + int data_me; +}; + +static void etap_pre_exec(void *arg) +{ + struct etap_pre_exec_data *data = arg; + + dup2(data->control_remote, 1); + close(data->data_me); + close(data->control_me); +} + +static int etap_tramp(char *dev, char *gate, int control_me, + int control_remote, int data_me, int data_remote) +{ + struct etap_pre_exec_data pe_data; + int pid, status, err; + char version_buf[sizeof("nnnnn\0")]; + char data_fd_buf[sizeof("nnnnnn\0")]; + char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")]; + char *setup_args[] = { "uml_net", version_buf, "ethertap", dev, + data_fd_buf, gate_buf, NULL }; + char *nosetup_args[] = { "uml_net", version_buf, "ethertap", + dev, data_fd_buf, NULL }; + char **args, c; + + sprintf(data_fd_buf, "%d", data_remote); + sprintf(version_buf, "%d", UML_NET_VERSION); + if(gate != NULL){ + strcpy(gate_buf, gate); + args = setup_args; + } + else args = nosetup_args; + + err = 0; + pe_data.control_remote = control_remote; + pe_data.control_me = control_me; + pe_data.data_me = data_me; + pid = run_helper(etap_pre_exec, &pe_data, args, NULL); + + if(pid < 0) err = errno; + close(data_remote); + close(control_remote); + if(read(control_me, &c, sizeof(c)) != sizeof(c)){ + printk("etap_tramp : read of status failed, errno = %d\n", + errno); + return(EINVAL); + } + if(c != 1){ + printk("etap_tramp : uml_net failed\n"); + err = EINVAL; + if(waitpid(pid, &status, 0) < 0) err = errno; + else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)){ + printk("uml_net didn't exit with status 1\n"); + } + } + return(err); +} + +static int etap_open(void *data) +{ + struct ethertap_data *pri = data; + char *output; + int data_fds[2], control_fds[2], err, output_len; + + err = tap_open_common(pri->dev, pri->gate_addr); + if(err) return(err); + + err = os_pipe(data_fds, 0); + if(err){ + printk("data os_pipe failed - errno = %d\n", -err); + return(err); + } + + err = os_pipe(control_fds, 1); + if(err){ + printk("control os_pipe failed - errno = %d\n", -err); + return(err); + } + + err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], + control_fds[1], data_fds[0], data_fds[1]); + output_len = page_size(); + output = um_kmalloc(output_len); + read_output(control_fds[0], output, output_len); + + if(output == NULL) + printk("etap_open : failed to allocate output buffer\n"); + else { + printk("%s", output); + kfree(output); + } + + if(err != 0){ + printk("etap_tramp failed - errno = %d\n", err); + return(-err); + } + + pri->data_fd = data_fds[0]; + pri->control_fd = control_fds[0]; + iter_addresses(pri->dev, etap_open_addr, &pri->control_fd); + return(data_fds[0]); +} + +static void etap_close(int fd, void *data) +{ + struct ethertap_data *pri = data; + + iter_addresses(pri->dev, etap_close_addr, &pri->control_fd); + close(fd); + shutdown(pri->data_fd, SHUT_RDWR); + close(pri->data_fd); + pri->data_fd = -1; + close(pri->control_fd); + pri->control_fd = -1; +} + +static int etap_set_mtu(int mtu, void *data) +{ + return(mtu); +} + +static void etap_add_addr(unsigned char *addr, unsigned char *netmask, + void *data) +{ + struct ethertap_data *pri = data; + + tap_check_ips(pri->gate_addr, addr); + if(pri->control_fd == -1) return; + etap_open_addr(addr, netmask, &pri->control_fd); +} + +static void etap_del_addr(unsigned char *addr, unsigned char *netmask, + void *data) +{ + struct ethertap_data *pri = data; + + if(pri->control_fd == -1) return; + etap_close_addr(addr, netmask, &pri->control_fd); +} + +struct net_user_info ethertap_user_info = { + init: etap_user_init, + open: etap_open, + close: etap_close, + remove: NULL, + set_mtu: etap_set_mtu, + add_address: etap_add_addr, + delete_address: etap_del_addr, + max_packet: MAX_PACKET - ETH_HEADER_ETHERTAP +}; + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -urNp 36/arch/um/os-Linux/drivers/tuntap.h 40/arch/um/os-Linux/drivers/tuntap.h --- 36/arch/um/os-Linux/drivers/tuntap.h Thu Jan 1 01:00:00 1970 +++ 40/arch/um/os-Linux/drivers/tuntap.h Tue Jul 16 17:08:05 2002 @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __UM_TUNTAP_H +#define __UM_TUNTAP_H + +#include "net_user.h" + +struct tuntap_data { + char *dev_name; + int fixed_config; + char *gate_addr; + int fd; + void *dev; + unsigned char hw_addr[ETH_ADDR_LEN]; + int hw_setup; +}; + +extern struct net_user_info tuntap_user_info; + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -urNp 36/arch/um/os-Linux/drivers/tuntap_kern.c 40/arch/um/os-Linux/drivers/tuntap_kern.c --- 36/arch/um/os-Linux/drivers/tuntap_kern.c Thu Jan 1 01:00:00 1970 +++ 40/arch/um/os-Linux/drivers/tuntap_kern.c Tue Jul 16 17:08:05 2002 @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#include "linux/stddef.h" +#include "linux/netdevice.h" +#include "linux/etherdevice.h" +#include "linux/skbuff.h" +#include "linux/init.h" +#include "asm/errno.h" +#include "net_kern.h" +#include "net_user.h" +#include "tuntap.h" + +struct tuntap_setup { + char *dev_name; + char *gate_addr; +}; + +struct tuntap_setup tuntap_priv[MAX_UML_NETDEV] = { + [ 0 ... MAX_UML_NETDEV - 1 ] = + { + dev_name: NULL, + gate_addr: NULL, + } +}; + +struct net_device *tuntap_init(int private_size, int index) +{ + struct net_device *dev; + struct uml_net_private *pri; + struct tuntap_data *tpri; + + dev = init_etherdev(NULL, private_size); + if(dev == NULL) return(NULL); + pri = dev->priv; + tpri = (struct tuntap_data *) pri->user; + tpri->dev_name = tuntap_priv[index].dev_name; + tpri->fixed_config = (tpri->dev_name != NULL); + tpri->gate_addr = tuntap_priv[index].gate_addr; + printk("TUN/TAP backend - "); + if(tpri->gate_addr != NULL) + printk("IP = %s", tpri->gate_addr); + printk("\n"); + tpri->fd = -1; + return(dev); +} + +static unsigned short tuntap_protocol(struct sk_buff *skb) +{ + return(eth_type_trans(skb, skb->dev)); +} + +static int tuntap_read(int fd, struct sk_buff **skb, + struct uml_net_private *lp) +{ + *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); + if(*skb == NULL) return(-ENOMEM); + return(net_read(fd, (*skb)->mac.raw, + (*skb)->dev->mtu + ETH_HEADER_OTHER)); +} + +static int tuntap_write(int fd, struct sk_buff **skb, + struct uml_net_private *lp) +{ + return(net_write(fd, (*skb)->data, (*skb)->len)); +} + +struct net_kern_info tuntap_kern_info = { + init: tuntap_init, + protocol: tuntap_protocol, + read: tuntap_read, + write: tuntap_write, +}; + +static int tuntap_count = 0; + +int tuntap_setup(char *str, struct uml_net *dev) +{ + struct tuntap_setup *pri; + int err; + + pri = &tuntap_priv[tuntap_count]; + err = tap_setup_common(str, "tuntap", &pri->dev_name, dev->mac, + &dev->have_mac, &pri->gate_addr); + if(err) return(err); + + dev->user = &tuntap_user_info; + dev->kern = &tuntap_kern_info; + dev->private_size = sizeof(struct tuntap_data); + dev->transport_index = tuntap_count++; + return(0); +} + +static struct transport tuntap_transport = { + list : LIST_HEAD_INIT(tuntap_transport.list), + name : "tuntap", + setup : tuntap_setup +}; + +static int register_tuntap(void) +{ + register_transport(&tuntap_transport); + return(1); +} + +__initcall(register_tuntap); + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -urNp 36/arch/um/os-Linux/drivers/tuntap_kern.h 40/arch/um/os-Linux/drivers/tuntap_kern.h --- 36/arch/um/os-Linux/drivers/tuntap_kern.h Thu Jan 1 01:00:00 1970 +++ 40/arch/um/os-Linux/drivers/tuntap_kern.h Tue Jul 16 17:08:05 2002 @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __UM_TUNTAP_KERN_H +#define __UM_TUNTAP_KERN_H + +#include "net_kern.h" + +extern int tuntap_setup(char *arg, struct uml_net *dev); + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -urNp 36/arch/um/os-Linux/drivers/tuntap_user.c 40/arch/um/os-Linux/drivers/tuntap_user.c --- 36/arch/um/os-Linux/drivers/tuntap_user.c Thu Jan 1 01:00:00 1970 +++ 40/arch/um/os-Linux/drivers/tuntap_user.c Tue Jul 16 17:08:05 2002 @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "net_user.h" +#include "tuntap.h" +#include "kern_util.h" +#include "user.h" +#include "helper.h" +#include "os.h" + +#define MAX_PACKET ETH_MAX_PACKET + +void tuntap_user_init(void *data, void *dev) +{ + struct tuntap_data *pri = data; + + pri->dev = dev; +} + +static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask, + void *data) +{ + struct tuntap_data *pri = data; + + tap_check_ips(pri->gate_addr, addr); + if((pri->fd == -1) || pri->fixed_config) return; + open_addr(addr, netmask, pri->dev_name); +} + +static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask, + void *data) +{ + struct tuntap_data *pri = data; + + if((pri->fd == -1) || pri->fixed_config) return; + close_addr(addr, netmask, pri->dev_name); +} + +struct tuntap_pre_exec_data { + int stdout; + int close_me; +}; + +static void tuntap_pre_exec(void *arg) +{ + struct tuntap_pre_exec_data *data = arg; + + dup2(data->stdout, 1); + close(data->close_me); +} + +static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, + char *buffer, int buffer_len, int *used_out) +{ + struct tuntap_pre_exec_data data; + char version_buf[sizeof("nnnnn\0")]; + char *argv[] = { "uml_net", version_buf, "tuntap", "up", gate, + NULL }; + char buf[CMSG_SPACE(sizeof(*fd_out))]; + struct msghdr msg; + struct cmsghdr *cmsg; + struct iovec iov; + int pid, n; + + sprintf(version_buf, "%d", UML_NET_VERSION); + + data.stdout = remote; + data.close_me = me; + + pid = run_helper(tuntap_pre_exec, &data, argv, NULL); + + if(pid < 0) return(-pid); + + close(remote); + + msg.msg_name = NULL; + msg.msg_namelen = 0; + if(buffer != NULL){ + iov = ((struct iovec) { buffer, buffer_len }); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + } + else { + msg.msg_iov = NULL; + msg.msg_iovlen = 0; + } + msg.msg_control = buf; + msg.msg_controllen = sizeof(buf); + msg.msg_flags = 0; + n = recvmsg(me, &msg, 0); + *used_out = n; + if(n < 0){ + printk("tuntap_open_tramp : recvmsg failed - errno = %d\n", + errno); + return(errno); + } + waitpid(pid, NULL, 0); + + cmsg = CMSG_FIRSTHDR(&msg); + if(cmsg == NULL){ + printk("tuntap_open_tramp : didn't receive a message\n"); + return(EINVAL); + } + if((cmsg->cmsg_level != SOL_SOCKET) || + (cmsg->cmsg_type != SCM_RIGHTS)){ + printk("tuntap_open_tramp : didn't receive a descriptor\n"); + return(EINVAL); + } + *fd_out = ((int *) CMSG_DATA(cmsg))[0]; + return(0); +} + +static int tuntap_open(void *data) +{ + struct ifreq ifr; + struct tuntap_data *pri = data; + char *output, *buffer; + int err, fds[2], len, used; + + err = tap_open_common(pri->dev, pri->gate_addr); + if(err) return(err); + + if(pri->fixed_config){ + if((pri->fd = open("/dev/net/tun", O_RDWR)) < 0){ + printk("Failed to open /dev/net/tun, errno = %d\n", + errno); + return(-errno); + } + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP; + strncpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name) - 1); + if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){ + printk("TUNSETIFF failed, errno = %d", errno); + close(pri->fd); + return(-errno); + } + } + else { + err = os_pipe(fds, 0); + if(err){ + printk("tuntap_open : os_pipe failed - errno = %d\n", + -err); + return(err); + } + + buffer = get_output_buffer(&len); + if(buffer != NULL) len--; + used = 0; + + err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0], + fds[1], buffer, len, &used); + + output = buffer; + if(err == 0){ + pri->dev_name = uml_strdup(buffer); + output += IFNAMSIZ; + printk(output); + free_output_buffer(buffer); + } + else { + printk(output); + free_output_buffer(buffer); + printk("tuntap_open_tramp failed - errno = %d\n", err); + return(-err); + } + close(fds[0]); + iter_addresses(pri->dev, open_addr, pri->dev_name); + } + + return(pri->fd); +} + +static void tuntap_close(int fd, void *data) +{ + struct tuntap_data *pri = data; + + if(!pri->fixed_config) + iter_addresses(pri->dev, close_addr, pri->dev_name); + close(fd); + pri->fd = -1; +} + +static int tuntap_set_mtu(int mtu, void *data) +{ + return(mtu); +} + +struct net_user_info tuntap_user_info = { + init: tuntap_user_init, + open: tuntap_open, + close: tuntap_close, + remove: NULL, + set_mtu: tuntap_set_mtu, + add_address: tuntap_add_addr, + delete_address: tuntap_del_addr, + max_packet: MAX_PACKET +}; + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -urNp 36/arch/um/os-Linux/file.c 40/arch/um/os-Linux/file.c --- 36/arch/um/os-Linux/file.c Thu Jan 1 01:00:00 1970 +++ 40/arch/um/os-Linux/file.c Tue Jul 16 17:08:05 2002 @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#include +#include +#include +#include +#include +#include +#include +#include "os.h" +#include "user.h" + +int os_open_file(char *file, struct openflags flags, int mode) +{ + int fd, f = 0; + + if(flags.r && flags.w) f = O_RDWR; + else if(flags.r) f = O_RDONLY; + else if(flags.w) f = O_WRONLY; + else f = 0; + + if(flags.s) f |= O_SYNC; + if(flags.c) f |= O_CREAT; + if(flags.t) f |= O_TRUNC; + if(flags.e) f |= O_EXCL; + + fd = open64(file, f, mode); + if(fd < 0) return(-errno); + return(fd); +} + +void os_close_file(int fd) +{ + close(fd); +} + +int os_seek_file(int fd, __u64 offset) +{ + __u64 actual; + + actual = lseek64(fd, offset, SEEK_SET); + if(actual != offset) return(-errno); + return(0); +} + +int os_file_size(char *file, long long *size_out) +{ + struct stat64 buf; + + if(stat64(file, &buf) == -1){ + printk("Couldn't stat \"%s\" : errno = %d\n", file, errno); + return(-errno); + } + if(S_ISBLK(buf.st_mode)){ + int fd, blocks; + + if((fd = open64(file, O_RDONLY)) < 0){ + printk("Couldn't open \"%s\", errno = %d\n", file, + errno); + return(-errno); + } + if(ioctl(fd, BLKGETSIZE, &blocks) < 0){ + printk("Couldn't get the block size of \"%s\", " + "errno = %d\n", file, errno); + close(fd); + return(-errno); + } + *size_out = ((long long) blocks) * 512; + close(fd); + return(0); + } + *size_out = buf.st_size; + return(0); +} + +int os_pipe(int *fds, int stream) +{ + int err, type = stream ? SOCK_STREAM : SOCK_DGRAM; + + err = socketpair(AF_UNIX, type, 0, fds); + if(err) return(-errno); + + if((fcntl(fds[0], F_SETFD, 1) < 0) || (fcntl(fds[1], F_SETFD, 1) < 0)) + printk("os_pipe : Setting FD_CLOEXEC failed, errno = %d", + errno); + + return(0); +} + +int os_set_fd_async(int fd, int owner) +{ + if(fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK) < 0){ + printk("os_set_fd_async : failed to set O_ASYNC and " + "O_NONBLOCK on fd # %d, errno = %d\n", fd, errno); + return(-errno); + } +#ifdef notdef + if(fcntl(fd, F_SETFD, 1) < 0){ + printk("os_set_fd_async : Setting FD_CLOEXEC failed, " + "errno = %d\n", errno); + } +#endif + + if((fcntl(fd, F_SETSIG, SIGIO) < 0) || + (fcntl(fd, F_SETOWN, owner) < 0)){ + printk("os_set_fd_async : Failed to fcntl F_SETOWN " + "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd, + owner, errno); + return(-errno); + } + + return(0); +} + +int os_set_fd_block(int fd, int blocking) +{ + int flags; + + flags = fcntl(fd, F_GETFL); + + if(blocking) flags &= ~O_NONBLOCK; + else flags |= O_NONBLOCK; + + if(fcntl(fd, F_SETFL, flags) < 0){ + printk("Failed to change blocking on fd # %d, errno = %d\n", + fd, errno); + return(-errno); + } + return(0); +} + +int os_accept_connection(int fd) +{ + int err; + + err = accept(fd, NULL, 0); + if(err) return(-errno); + return(0); +} + +void os_shutdown_socket(int fd) +{ + shutdown(fd, SHUT_RDWR); +} + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -urNp 36/arch/um/os-Linux/include/file.h 40/arch/um/os-Linux/include/file.h --- 36/arch/um/os-Linux/include/file.h Thu Jan 1 01:00:00 1970 +++ 40/arch/um/os-Linux/include/file.h Tue Jul 16 17:08:05 2002 @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __OS_FILE_H__ +#define __OS_FILE_H__ + +#define DEV_NULL "/dev/null" + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -urNp 36/arch/um/os-Linux/process.c 40/arch/um/os-Linux/process.c --- 36/arch/um/os-Linux/process.c Thu Jan 1 01:00:00 1970 +++ 40/arch/um/os-Linux/process.c Tue Jul 16 17:08:05 2002 @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#include +#include +#include +#include +#include "os.h" +#include "user.h" + +unsigned long os_process_pc(int pid) +{ + char proc_stat[sizeof("/proc/#####/stat\0")], buf[256]; + unsigned long pc; + int fd; + + sprintf(proc_stat, "/proc/%d/stat", pid); + fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0); + if(fd < 0){ + printk("os_process_pc - couldn't open '%s', errno = %d\n", + proc_stat, errno); + return(-1); + } + if(read(fd, buf, sizeof(buf)) < 0){ + printk("os_process_pc - couldn't read '%s', errno = %d\n", + proc_stat, errno); + close(fd); + return(-1); + } + close(fd); + pc = -1; + if(sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*d %*d %*d " + "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d " + "%*d %*d %*d %*d %ld", &pc) != 1){ + printk("os_process_pc - couldn't find pc in '%s'\n", buf); + } + return(pc); +} + +int os_process_parent(int pid) +{ + char stat[sizeof("/proc/nnnnn/stat\0")]; + char data[256]; + int parent, n, fd; + + if(pid == -1) return(-1); + + snprintf(stat, sizeof(stat), "/proc/%d/stat", pid); + fd = os_open_file(stat, of_read(OPENFLAGS()), 0); + if(fd < 0){ + printk("Couldn't open '%s', errno = %d\n", stat, -fd); + return(-1); + } + + n = read(fd, data, sizeof(data)); + close(fd); + + if(n < 0){ + printk("Couldn't read '%s', errno = %d\n", stat); + return(-1); + } + + parent = -1; + /* XXX This will break if there is a space in the command */ + n = sscanf(data, "%*d %*s %*c %d", &parent); + if(n != 1) printk("Failed to scan '%s'\n", data); + + return(parent); +} + +void os_stop_process(int pid) +{ + kill(pid, SIGSTOP); +} + +void os_kill_process(int pid) +{ + kill(pid, SIGKILL); +} + +void os_usr1_process(int pid) +{ + kill(pid, SIGUSR1); +} + +int os_getpid(void) +{ + return(getpid()); +} + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -urNp 36/arch/um/os-Linux/tty.c 40/arch/um/os-Linux/tty.c --- 36/arch/um/os-Linux/tty.c Thu Jan 1 01:00:00 1970 +++ 40/arch/um/os-Linux/tty.c Tue Jul 16 17:08:05 2002 @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#include +#include +#include "os.h" +#include "user.h" +#include "kern_util.h" + +struct grantpt_info { + int fd; + int res; + int err; +}; + +static void grantpt_cb(void *arg) +{ + struct grantpt_info *info = arg; + + info->res = grantpt(info->fd); + info->err = errno; +} + +int get_pty(void) +{ + struct grantpt_info info; + int fd; + + if((fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0)) < 0){ + printk("get_pty : Couldn't open /dev/ptmx - errno = %d\n", + errno); + return(-1); + } + + info.fd = fd; + tracing_cb(grantpt_cb, &info); + + if(info.res < 0){ + printk("get_pty : Couldn't grant pty - errno = %d\n", + info.err); + return(-1); + } + if(unlockpt(fd) < 0){ + printk("get_pty : Couldn't unlock pty - errno = %d\n", errno); + return(-1); + } + return(fd); +} + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff -urNp 36/arch/um/ptproxy/proxy.c 40/arch/um/ptproxy/proxy.c --- 36/arch/um/ptproxy/proxy.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/ptproxy/proxy.c Tue Jul 16 17:08:05 2002 @@ -29,6 +29,7 @@ Jeff Dike (jdike@karaya.com) : Modified #include "user_util.h" #include "user.h" +#include "os.h" static int debugger_wait(debugger_state *debugger, int *status, int options, int (*syscall)(debugger_state *debugger, pid_t child), @@ -196,7 +197,7 @@ void init_proxy (pid_t debugger_pid, int debugee.zombie = 0; debugee.died = 0; debugee.wait_status = status; - debugee.in_context = 0; + debugee.in_context = 1; } int debugger_proxy(int status, int pid) @@ -320,7 +321,7 @@ int start_debugger(char *prog, int start "errno = %d\n", errno); exit(1); } - if(tcsetpgrp (1, getpid()) < 0){ + if(tcsetpgrp (1, os_getpid()) < 0){ printk("start_debugger : tcsetpgrp failed, " "errno = %d\n", errno); #ifdef notdef diff -urNp 36/arch/um/ptproxy/ptrace.c 40/arch/um/ptproxy/ptrace.c --- 36/arch/um/ptproxy/ptrace.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/ptproxy/ptrace.c Tue Jul 16 17:08:05 2002 @@ -58,6 +58,7 @@ long proxy_ptrace(struct debugger *debug if(!debugger->debugee->traced) return(-EPERM); debugger->debugee->traced = 0; + debugger->debugee->pid = 0; if(!debugger->debugee->in_context) kill(child, SIGCONT); diff -urNp 36/arch/um/sys-i386/Makefile 40/arch/um/sys-i386/Makefile --- 36/arch/um/sys-i386/Makefile Tue Jul 16 17:07:52 2002 +++ 40/arch/um/sys-i386/Makefile Tue Jul 16 17:08:05 2002 @@ -4,7 +4,7 @@ OBJS = bugs.o checksum.o extable.o fault ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o export-objs = ksyms.o -USER_OBJS = bugs.o ldt.o ptrace_user.o sigcontext.o fault.o +USER_OBJS = bugs.o ptrace_user.o sigcontext.o fault.o SYMLINKS = semaphore.c old-checksum.c checksum.S extable.c diff -urNp 36/arch/um/sys-i386/ldt.c 40/arch/um/sys-i386/ldt.c --- 36/arch/um/sys-i386/ldt.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/sys-i386/ldt.c Tue Jul 16 17:08:05 2002 @@ -1,13 +1,16 @@ /* - * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ +#include "asm/uaccess.h" + extern int modify_ldt(int func, void *ptr, unsigned long bytecount); int sys_modify_ldt(int func, void *ptr, unsigned long bytecount) { - return modify_ldt(func, ptr, bytecount); + if(verify_area(VERIFY_READ, ptr, bytecount)) return(-EFAULT); + return(modify_ldt(func, ptr, bytecount)); } /* diff -urNp 36/arch/um/sys-i386/ptrace_user.c 40/arch/um/sys-i386/ptrace_user.c --- 36/arch/um/sys-i386/ptrace_user.c Tue Jul 16 17:07:52 2002 +++ 40/arch/um/sys-i386/ptrace_user.c Tue Jul 16 17:08:05 2002 @@ -13,6 +13,7 @@ #include "kern_util.h" #include "sysdep/thread.h" #include "user.h" +#include "os.h" int ptrace_getregs(long pid, unsigned long *regs_out) { @@ -99,7 +100,7 @@ void update_debugregs(int seq) if(seq == debugregs_seq) return; - me = getpid(); + me = os_getpid(); tracing_cb(update_debugregs_cb, &me); } diff -urNp 36/drivers/net/setup.c 40/drivers/net/setup.c --- 36/drivers/net/setup.c Tue Jan 22 18:52:09 2002 +++ 40/drivers/net/setup.c Tue Jul 16 17:08:05 2002 @@ -28,7 +28,6 @@ extern int comx_init(void); extern int lmc_setup(void); extern int madgemc_probe(void); -extern int uml_net_probe(void); /* Pad device name to IFNAMSIZ=16. F.e. __PAD6 is string of 9 zeros. */ #define __PAD6 "\0\0\0\0\0\0\0\0\0" @@ -103,9 +102,6 @@ static struct net_probe pci_probes[] __i #ifdef CONFIG_MADGEMC {madgemc_probe, 0}, #endif -#ifdef CONFIG_UML_NET - {uml_net_probe, 0}, -#endif {NULL, 0}, }; diff -urNp 36/include/asm-um/irq.h 40/include/asm-um/irq.h --- 36/include/asm-um/irq.h Tue Jul 16 17:07:52 2002 +++ 40/include/asm-um/irq.h Tue Jul 16 17:08:05 2002 @@ -23,8 +23,9 @@ struct task_struct; #define MCONSOLE_IRQ 9 #define WINCH_IRQ 10 #define SIGIO_WRITE_IRQ 11 +#define TELNETD_IRQ 12 -#define LAST_IRQ SIGIO_WRITE_IRQ +#define LAST_IRQ TELNETD_IRQ #define NR_IRQS (LAST_IRQ + 1) extern int um_request_irq(unsigned int irq, int fd, int type, diff -urNp 36/include/linux/raid/md_compatible.h 40/include/linux/raid/md_compatible.h --- 36/include/linux/raid/md_compatible.h Tue Jul 16 16:47:30 2002 +++ 40/include/linux/raid/md_compatible.h Tue Jul 16 17:08:05 2002 @@ -34,7 +34,7 @@ static __inline__ int md_cpu_has_mmx(voi return test_bit(X86_FEATURE_MMX, &boot_cpu_data.x86_capability); } #else -#define md_cpu_has_mmx(x) (0) +#define md_cpu_has_mmx() (0) #endif /* 002 */