Commit 26a34b16 authored by Linus Torvalds's avatar Linus Torvalds

[PATCH] Linux-0.99.1 (December 21, 1992)

Patch 1 addresses the following problems:
 - configuration. Hope there are no silly problems left..
 - inode.c: initialization changes (the missing NULL and some other
   minor fixes).
 - some SCSI tape driver patches (Kai M{kisara)
 - tcp/ip patches (Ross Biro, some code by me)
 - keyboard patches (mainly changed initialization - hope the keyboard
   lockups are gone).
 - completed /proc-fs: it should now contain all info needed by 'ps'
   (Micheal K Johnson).
 - various minor fixes (the minix-fs link overflow checking etc)

Patch1 also contains support for extended VC switching - this is for the
upcoming X11 that understands VC's.  One result of this is that console
redirection now redirects *only* messages actually sent to /dev/console
(aka /dev/tty0), not just to any foreground VC.  Wait for Xfree-1.2 to
be able to switch VC's while under X (yes, including several X-sessions
active at the same time..).

I hope there are still people out there that aren't too busy stuffing
themself with turkey to try out a new kernel release.  There is just
over a week left of this year, and I need feedback in order to be able
to release 1.0.

                Linus

PS.  Thanks to everybody who has sent me Christmas/New Year/Birthday
cards.  Some contained money, some didn't, and I enjoyed them all.
Thanks.
parent ad094925
......@@ -7,8 +7,8 @@
#
CONFIG_BLK_DEV_HD = CONFIG_BLK_DEV_HD
CONFIG_TCPIP = CONFIG_TCPIP
CONFIG_PROFILE = CONFIG_PROFILE
CONFIG_MAX_16M = CONFIG_MAX_16M
CONFIG_M486 = CONFIG_M486
#
# SCSI support
......
#
# Make "config" the default target if there is no configuration file
#
ifeq (.config,$(wildcard .config))
include .config
else
CONFIGURATION = config
endif
#
# ROOT_DEV specifies the default root-device when making the image.
......@@ -69,6 +76,10 @@ SOUND_SUPPORT = -DKERNEL_SOUNDCARD -DDSP_BUFFSIZE=16384 -DSBC_IRQ=7 -DPAS_IRQ=5
CFLAGS = -Wall -O6 -fomit-frame-pointer
ifdef CONFIG_M486
CFLAGS := $(CFLAGS) -m486
endif
#
# if you want the ram-disk device, define this to be the
# size in blocks.
......@@ -112,20 +123,31 @@ lilo: Image
/etc/lilo/install
config:
ifdef CONFIGURATION
@echo
@echo "You have no .config: running Configure"
@echo
endif
sh Configure < config.in
ifdef CONFIGURATION
@echo
@echo "Configure successful. Try re-making (ignore the error that follows)"
@echo
exit 1
endif
linuxsubdirs: dummy
@for i in $(SUBDIRS); do (cd $$i && echo $$i && $(MAKE)) || exit; done
Version:
Version: dummy
@./makever.sh
@echo \#define UTS_RELEASE \"0.99-`cat .version`\" > tools/version.h
@echo \#define UTS_RELEASE \"0.99.pl1-`cat .version`\" > tools/version.h
@echo \#define UTS_VERSION \"`date +%D`\" >> tools/version.h
@echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> tools/version.h
@echo \#define LINUX_COMPILE_BY \"`whoami`\" >> tools/version.h
@echo \#define LINUX_COMPILE_HOST \"`hostname`\" >> tools/version.h
Image: boot/bootsect boot/setup tools/system tools/build
Image: $(CONFIGURATION) boot/bootsect boot/setup tools/system tools/build
cp tools/system system.tmp
strip system.tmp
tools/build boot/bootsect boot/setup system.tmp $(ROOT_DEV) > Image
......@@ -162,8 +184,8 @@ boot/setup: boot/setup.s
$(AS86) -o boot/setup.o boot/setup.s
$(LD86) -s -o boot/setup boot/setup.o
boot/setup.s: boot/setup.S include/linux/config.h
$(CPP) -traditional boot/setup.S -o boot/setup.s
boot/setup.s: boot/setup.S include/linux/config.h Makefile
$(CPP) -traditional $(SVGA_MODE) $(RAMDISK) boot/setup.S -o boot/setup.s
boot/bootsect.s: boot/bootsect.S include/linux/config.h Makefile
$(CPP) -traditional $(SVGA_MODE) $(RAMDISK) boot/bootsect.S -o boot/bootsect.s
......@@ -195,7 +217,7 @@ depend dep:
for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done > .depend
for i in $(SUBDIRS); do (cd $$i && $(MAKE) dep) || exit; done
dummy:
dummy: $(CONFIGURATION)
#
# include a dependency file if one exists
......@@ -203,3 +225,4 @@ dummy:
ifeq (.depend,$(wildcard .depend))
include .depend
endif
......@@ -78,8 +78,6 @@ go: mov ax,cs
mov ds,ax
mov es,ax
push ax
mov ss,ax ! put stack at INITSEG:0x4000-12.
mov sp,dx
/*
......@@ -121,7 +119,7 @@ go: mov ax,cs
seg fs
mov 2(bx),es
pop ax
mov ax,cs
mov fs,ax
mov gs,ax
......
......@@ -10,6 +10,8 @@ Kernel profiling support
CONFIG_PROFILE y/n n
Limit to memory to low 16MB
CONFIG_MAX_16M y/n y
Use -m486 flag for 486-specific optimizations
CONFIG_M486 y/n y
:
SCSI support
.
......@@ -27,9 +29,9 @@ CONFIG_BLK_DEV_SR y/n y
.
SCSI low-level drivers
.
Adaptek AHA1542 support
Adaptec AHA1542 support
CONFIG_SCSI_AHA1542 y/n y
Adaptek AHA1740 support
Adaptec AHA1740 support
CONFIG_SCSI_AHA1740 y/n y
Always IN support
CONFIG_SCSI_ALWAYS y/n y
......@@ -67,7 +69,7 @@ Accent Async 4 serial support
CONFIG_ACCENT_ASYNC y/n n
Logitech busmouse support
CONFIG_BUSMOUSE y/n n
PS/2 mouse (aka 'auxilliary device') support
PS/2 mouse (aka 'auxiliary device') support
CONFIG_PSMOUSE y/n n
MicroSoft busmouse support
CONFIG_MS_BUSMOUSE y/n n
......
......@@ -376,17 +376,18 @@ static void read_omagic(struct inode *inode, int bytes)
if (inode->i_sb)
block_size = inode->i_sb->s_blocksize;
while (bytes > 0) {
if (!(blkno = bmap(inode, blk)))
sys_exit(-1);
if (!(bh = bread(inode->i_dev, blkno, block_size)))
sys_exit(-1);
n = (blk ? block_size : block_size - sizeof(struct exec));
if (bytes < n)
n = bytes;
memcpy_tofs(dest, (blk ? bh->b_data :
blkno = bmap(inode, blk);
if (blkno) {
bh = bread(inode->i_dev, blkno, block_size);
if (!bh)
sys_exit(-1);
memcpy_tofs(dest, (blk ? bh->b_data :
bh->b_data + sizeof(struct exec)), n);
brelse(bh);
brelse(bh);
}
++blk;
dest += n;
bytes -= n;
......
......@@ -12,13 +12,19 @@
#include <asm/system.h>
static struct inode inode_table[NR_INODE];
static struct inode * last_inode = inode_table;
static struct wait_queue * inode_wait;
static struct inode * inode_table;
static struct inode * last_inode;
static struct wait_queue * inode_wait = NULL;
void inode_init(void)
unsigned long inode_init(unsigned long start, unsigned long end)
{
memset(inode_table,0,sizeof(inode_table));
start += 0x0000000f;
start &= 0xfffffff0;
inode_table = (struct inode *) start;
last_inode = inode_table;
start = (unsigned long) (inode_table + NR_INODE);
memset(inode_table,0,NR_INODE*sizeof(struct inode));
return start;
}
static void __wait_on_inode(struct inode *);
......
......@@ -53,6 +53,19 @@ file.o : file.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/includ
/usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
/usr/include/linux/iso_fs.h /usr/include/linux/fcntl.h /usr/include/linux/errno.h \
/usr/include/linux/stat.h /usr/include/linux/locks.h
inode.o : inode.c /usr/include/linux/config.h /usr/include/linux/autoconf.h \
/usr/include/linux/stat.h /usr/include/linux/sched.h /usr/include/linux/head.h \
/usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
/usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
/usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
/usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/nfs_fs_i.h \
/usr/include/linux/nfs.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
/usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/nfs_fs_sb.h \
/usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
/usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
/usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/iso_fs.h \
/usr/include/linux/string.h /usr/include/linux/locks.h /usr/include/asm/system.h \
/usr/include/asm/segment.h /usr/include/linux/errno.h
namei.o : namei.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
/usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
/usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
......
......@@ -18,10 +18,6 @@
#include <asm/segment.h>
#include <linux/errno.h>
#ifndef CONFIG_BLK_DEV_SR
#error The iso9660 filesystem can only be used with CDROM.
#endif
extern int check_cdrom_media_change(int, int);
#ifdef LEAK_CHECK
......
......@@ -304,6 +304,10 @@ int minix_mkdir(struct inode * dir, const char * name, int len, int mode)
iput(dir);
return -EEXIST;
}
if (dir->i_nlink > 250) {
iput(dir);
return -EMLINK;
}
inode = minix_new_inode(dir);
if (!inode) {
iput(dir);
......@@ -695,6 +699,9 @@ static int do_minix_rename(struct inode * old_dir, const char * old_name, int ol
goto end_rename;
if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino)
goto end_rename;
retval = -EMLINK;
if (new_dir->i_nlink > 250)
goto end_rename;
}
if (!new_bh)
new_bh = minix_add_entry(new_dir,new_name,new_len,&new_de);
......
......@@ -7,7 +7,8 @@ array.o : array.c /usr/include/linux/types.h /usr/include/linux/errno.h /usr/inc
/usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/nfs_fs_sb.h \
/usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
/usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
/usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/asm/segment.h \
/usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/tty.h \
/usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/asm/segment.h \
/usr/include/asm/io.h
base.o : base.c /usr/include/asm/segment.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
/usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
......
......@@ -3,12 +3,15 @@
*
* Copyright (C) 1992 by Linus Torvalds
* based on ideas by Darren Senn
*
* stat,statm extensions by Michael K. Johnson, johnsonm@stolaf.edu
*/
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/tty.h>
#include <asm/segment.h>
#include <asm/io.h>
......@@ -16,6 +19,17 @@
#define LOAD_INT(x) ((x) >> FSHIFT)
#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
#define KSTK_EIP(stack) (((char *)stack)[1019])
#define KSTK_ESP(stack) (((char *)stack)[1022])
#define _SSIZE(stack) (TASK_SIZE - KSTK_ESP(stack))
#define SSIZE(stack) (KSTK_ESP(stack) ? _SSIZE(stack) : 0)
#define VSIZE(task,stack) ((task)->brk + 1023 + SSIZE(stack))
#define SIZE(task,stack) (((task)->brk - (task)->end_code + 1023 + \
SSIZE(stack)) / 1024)
static int get_loadavg(char * buffer)
{
int a, b, c;
......@@ -129,6 +143,8 @@ static int get_arg(int pid, char * buffer)
static int get_stat(int pid, char * buffer)
{
struct task_struct ** p = get_task(pid);
unsigned long sigignore=0, sigcatch=0, bit=1;
int i;
char state;
if (!p || !*p)
......@@ -137,14 +153,101 @@ static int get_stat(int pid, char * buffer)
state = '.';
else
state = "RSDZTD"[(*p)->state];
return sprintf(buffer,"%d (%s) %c %d %d %d %d\n",
for(i=0; i<32; ++i) {
switch((int) (*p)->sigaction[i].sa_handler) {
case 1: sigignore |= bit; break;
case 0: break;
default: sigcatch |= bit;
} bit <<= 1;
}
return sprintf(buffer,"%d (%s) %c %d %d %d %d %d %u %u \
%u %u %u %d %d %d %d %d %d %u %u %d %u %u %u %u %u %u %u %u %d \
%d %d %d %u\n",
pid,
(*p)->comm,
state,
(*p)->p_pptr->pid,
(*p)->pgrp,
(*p)->session,
(*p)->tty);
(*p)->tty,
((*p)->tty == -1) ? -1 :
tty_table[(*p)->tty]->pgrp,
(*p)->flags,
(*p)->min_flt,
(*p)->cmin_flt,
(*p)->maj_flt,
(*p)->cmaj_flt,
(*p)->utime,
(*p)->stime,
(*p)->cutime,
(*p)->cstime,
(*p)->counter, /* this is the kernel priority ---
subtract 30 in your user-level program. */
(*p)->priority, /* this is the nice value ---
subtract 15 in your user-level program. */
(*p)->timeout,
(*p)->it_real_value,
(*p)->start_time,
VSIZE((*p),(*p)->kernel_stack_page),
(*p)->rss, /* you might want to shift this left 3 */
(*p)->rlim[RLIMIT_RSS].rlim_cur,
(*p)->start_code,
(*p)->end_code,
(*p)->start_stack,
KSTK_ESP((*p)->kernel_stack_page),
KSTK_EIP((*p)->kernel_stack_page),
(*p)->signal,
(*p)->blocked,
sigignore,
sigcatch,
(*p)->tss.eip);
}
static int get_statm(int pid, char * buffer)
{
struct task_struct ** p = get_task(pid);
int i, tpag;
int size=0, resident=0, share=0, trs=0, lrs=0, drs=0, dt=0;
unsigned long ptbl, *buf, *pte, *pagedir, map_nr;
if (!p || !*p)
return 0;
tpag = (*p)->end_code / PAGE_SIZE;
if ((*p)->state != TASK_ZOMBIE) {
pagedir = (void *)((*p)->tss.cr3 + ((*p)->start_code >> 20));
for (i = 0; i < 0x300; ++i) {
if ((ptbl = pagedir[i]) == 0) {
tpag -= 1024;
continue;
}
buf = (void *)(ptbl & 0xfffff000);
for (pte = buf; pte < (buf + 1024); ++pte) {
if (*pte != 0) {
++size;
if (*pte & 1) {
++resident;
if (tpag > 0)
++trs;
else
++drs;
if (i >= 15 && i < 0x2f0) {
++lrs;
if (*pte & 0x40)
++dt;
else
--drs;
}
map_nr = MAP_NR(*pte);
if (map_nr < (high_memory / 4096) && mem_map[map_nr] > 1)
++share;
}
}
--tpag;
}
}
}
return sprintf(buffer,"%d %d %d %d %d %d %d\n",
size, resident, share, trs, lrs, drs, dt);
}
static int array_read(struct inode * inode, struct file * file,char * buf, int count)
......@@ -181,6 +284,9 @@ static int array_read(struct inode * inode, struct file * file,char * buf, int c
case 11:
length = get_stat(pid, page);
break;
case 12:
length = get_statm(pid, page);
break;
default:
free_page((unsigned long) page);
return -EBADF;
......
......@@ -59,7 +59,8 @@ static struct proc_dir_entry base_dir[] = {
{ 8,3,"lib" },
{ 9,7,"environ" },
{ 10,7,"cmdline" },
{ 11,4,"stat" }
{ 11,4,"stat" },
{ 12,5,"statm" }
};
#define NR_BASE_DIRENTRY ((sizeof (base_dir))/(sizeof (base_dir[0])))
......
......@@ -143,6 +143,7 @@ void proc_read_inode(struct inode * inode)
case 9:
case 10:
case 11:
case 12:
inode->i_mode = S_IFREG | 0444;
inode->i_op = &proc_array_inode_operations;
return;
......
......@@ -7,8 +7,8 @@
*/
#define CONFIG_BLK_DEV_HD 1
#define CONFIG_TCPIP 1
#define CONFIG_PROFILE 1
#define CONFIG_MAX_16M 1
#define CONFIG_M486 1
/*
* SCSI support
......
......@@ -23,7 +23,7 @@
#undef NR_OPEN
#define NR_OPEN 256
#define NR_INODE 128
#define NR_INODE 256
#define NR_FILE 128
#define NR_SUPER 16
#define NR_HASH 997
......@@ -66,7 +66,7 @@
#define WRITEA 3 /* "write-ahead" - silly, but somewhat useful */
extern void buffer_init(void);
extern void inode_init(void);
extern unsigned long inode_init(unsigned long start, unsigned long end);
#define MAJOR(a) (((unsigned)(a))>>8)
#define MINOR(a) ((a)&0xff)
......
......@@ -23,8 +23,19 @@ extern unsigned long kbd_flags;
#define KG_ALT 4
#define KG_ALTGR 5
#define KG_CAPSLOCK 6
#define KG_E0 7
#define KG_E1 8
/*
* "dead" keys - prefix key values that are valid only for the next
* character code (sticky shift, E0/E1 special scancodes, diacriticals)
*/
extern unsigned long kbd_dead_keys;
extern unsigned long kbd_prev_dead_keys;
/*
* these are the hardcoded dead key flags
*/
#define KGD_E0 0
#define KGD_E1 1
/*
* kbd->xxx contains the VC-local things (flag settings etc..)
......@@ -80,6 +91,26 @@ extern inline void chg_kbd_flag(int flag)
kbd_flags ^= 1 << flag;
}
extern inline int kbd_dead(int flag)
{
return kbd_prev_dead_keys & (1 << flag);
}
extern inline void set_kbd_dead(int flag)
{
kbd_dead_keys |= 1 << flag;
}
extern inline void clr_kbd_dead(int flag)
{
kbd_dead_keys &= ~(1 << flag);
}
extern inline void chg_kbd_dead(int flag)
{
kbd_dead_keys ^= 1 << flag;
}
extern inline int vc_kbd_flag(struct kbd_struct * kbd, int flag)
{
return ((kbd->flags >> flag) & 1);
......
......@@ -134,14 +134,14 @@ sys_uname, sys_umask, sys_chroot, sys_ustat, sys_dup2, sys_getppid,
sys_getpgrp, sys_setsid, sys_sigaction, sys_sgetmask, sys_ssetmask,
sys_setreuid,sys_setregid, sys_sigsuspend, sys_sigpending,
sys_sethostname, sys_setrlimit, sys_getrlimit, sys_getrusage,
sys_gettimeofday, sys_settimeofday, sys_getgroups, sys_setgroups,
sys_gettimeofday, sys_settimeofday, sys_getgroups, sys_setgroups,
sys_select, sys_symlink, sys_lstat, sys_readlink, sys_uselib,
sys_swapon, sys_reboot, sys_readdir, sys_mmap, sys_munmap,
sys_truncate, sys_ftruncate, sys_fchmod, sys_fchown, sys_getpriority,
sys_setpriority, sys_profil, sys_statfs, sys_fstatfs, sys_ioperm,
sys_socketcall, sys_syslog, sys_setitimer, sys_getitimer, sys_newstat,
sys_newlstat, sys_newfstat, sys_newuname, sys_iopl, sys_vhangup,
sys_idle, sys_vm86, sys_wait4, sys_swapoff, sys_sysinfo };
sys_swapon, sys_reboot, sys_readdir, sys_mmap, sys_munmap, sys_truncate,
sys_ftruncate, sys_fchmod, sys_fchown, sys_getpriority, sys_setpriority,
sys_profil, sys_statfs, sys_fstatfs, sys_ioperm, sys_socketcall,
sys_syslog, sys_setitimer, sys_getitimer, sys_newstat, sys_newlstat,
sys_newfstat, sys_newuname, sys_iopl, sys_vhangup, sys_idle, sys_vm86,
sys_wait4, sys_swapoff, sys_sysinfo };
/* So we don't have to do any more manual updating.... */
int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr);
......@@ -285,6 +285,7 @@ extern int is_ignored(int sig);
extern int tty_signal(int sig, struct tty_struct *tty);
extern int kill_pg(int pgrp, int sig, int priv);
extern int kill_sl(int sess, int sig, int priv);
extern void tty_hangup(struct tty_struct * tty);
extern void do_SAK(struct tty_struct *tty);
/* tty write functions */
......
......@@ -133,7 +133,7 @@ static unsigned long memory_start = 0; /* After mem_init, stores the */
static unsigned long memory_end = 0;
static unsigned long low_memory_start = 0;
static char * argv_init[MAX_INIT_ARGS+2] = { "/bin/init", NULL, };
static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
static char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=console", NULL, };
static char * argv_rc[] = { "/bin/sh", NULL };
......@@ -238,9 +238,9 @@ void start_kernel(void)
#ifdef CONFIG_SCSI
memory_start = scsi_dev_init(memory_start,memory_end);
#endif
memory_start = inode_init(memory_start,memory_end);
mem_init(low_memory_start,memory_start,memory_end);
buffer_init();
inode_init();
time_init();
floppy_init();
sock_init();
......
......@@ -288,6 +288,8 @@ void __math_abort(struct info * info, unsigned int signal)
void math_emulate(long arg)
{
printk("math-meulation not enabled and no coprocessor found.\n");
printk("killing %s.\n",current->comm);
send_sig(SIGFPE,current,1);
schedule();
}
......
......@@ -152,6 +152,8 @@ extern int ramdisk_size;
#endif
#if (MAJOR_NR != 9)
#ifndef CURRENT
#define CURRENT (blk_dev[MAJOR_NR].current_request)
#endif
......@@ -259,3 +261,4 @@ static void end_request(int uptodate)
#endif
#endif
#endif
......@@ -216,7 +216,7 @@ int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg)
{
char scsi_cmd[10];
if ((cmd != 0 && dev->id > NR_SCSI_DEVICES))
if ((cmd != 0 && dev->index > NR_SCSI_DEVICES))
return -ENODEV;
if ((cmd == 0 && dev->host_no > max_scsi_hosts))
return -ENODEV;
......
......@@ -97,6 +97,7 @@ int sr_ioctl(struct inode * inode, struct file * file, unsigned long cmd, unsign
int result, target;
target = MINOR(dev);
if (target >= NR_SR) return -ENODEV;
switch (cmd)
{
......
......@@ -30,7 +30,7 @@
Kai Makisara, Nov 9, 1992 email makisara@vtinsx.ins.vtt.fi or
Kai.Makisara@vtt.fi
Last changes Dec 6, 1992.
Last changes Dec 19, 1992.
*/
#include <linux/fs.h>
......@@ -56,9 +56,14 @@
before command completion. */
/* #define ST_NOWAIT */
/* Uncomment the following if you want the tape to be positioned correctly
within file after close (the tape is positioned correctly with respect
to the filemarks even wihout ST_IN_FILE_POS defined */
/* #define ST_IN_FILE_POS */
/* #define DEBUG */
#define ST_TIMEOUT 2000
#define ST_TIMEOUT 6000
#define ST_LONG_TIMEOUT 200000
/* Number of ST_BLOCK_SIZE blocks in the buffers */
......@@ -519,9 +524,13 @@ static void scsi_tape_close(struct inode * inode, struct file * filp)
printk("st%d: Buffer flushed, EOF written\n", dev);
#endif
}
else if (!rewind && scsi_tapes[dev].eof && !scsi_tapes[dev].eof_hit)
st_int_ioctl(inode, filp, MTBSF, 1);
/* Back over the EOF hit inadvertently */
else if (!rewind) {
if ((scsi_tapes[dev].eof == 1) && !scsi_tapes[dev].eof_hit)
st_int_ioctl(inode, filp, MTBSF, 1); /* Back over the EOF hit */
#ifdef ST_IN_FILE_POS
flush_buffer(inode, filp, 0);
#endif
}
if (rewind)
st_int_ioctl(inode, filp, MTREW, 1);
......@@ -701,12 +710,9 @@ int st_read(struct inode * inode, struct file * filp, char * buf, int count)
printk("st%d: EOF flag up. Bytes %d\n", dev,
scsi_tapes[dev].buffer->buffer_bytes);
#endif
if ((scsi_tapes[dev].buffer->buffer_bytes == 0) && scsi_tapes[dev].eof) {
if (scsi_tapes[dev].eof == 1)
return 0;
else /* EOM or blank check */
return (-EIO);
}
if ((scsi_tapes[dev].buffer->buffer_bytes == 0) &&
scsi_tapes[dev].eof == 2) /* EOM or Blank Check */
return (-EIO);
scsi_tapes[dev].rw = 1;
......@@ -714,7 +720,8 @@ int st_read(struct inode * inode, struct file * filp, char * buf, int count)
for (total = 0; total < count; ) {
if (scsi_tapes[dev].buffer->buffer_bytes == 0 && scsi_tapes[dev].eof == 0) {
if (scsi_tapes[dev].buffer->buffer_bytes == 0 &&
scsi_tapes[dev].eof == 0) {
memset(cmd, 0, 10);
cmd[0] = READ_6;
......@@ -734,6 +741,7 @@ int st_read(struct inode * inode, struct file * filp, char * buf, int count)
if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );
scsi_tapes[dev].buffer->read_pointer = 0;
scsi_tapes[dev].eof_hit = 0;
if (SCpnt->result != 0 || SCpnt->sense_buffer[0] != 0) {
#ifdef DEBUG
......@@ -796,8 +804,10 @@ int st_read(struct inode * inode, struct file * filp, char * buf, int count)
}
}
else
scsi_tapes[dev].buffer->buffer_bytes = scsi_tapes[dev].buffer->buffer_size;
} /* if (SCpnt->result != 0 || SCpnt->sense_buffer[0] != 0) */
scsi_tapes[dev].buffer->buffer_bytes =
scsi_tapes[dev].buffer->buffer_size;
} /* if (scsi_tapes[dev].buffer->buffer_bytes == 0 &&
scsi_tapes[dev].eof == 0) */
if (scsi_tapes[dev].buffer->buffer_bytes > 0) {
#ifdef DEBUG
......@@ -818,10 +828,11 @@ int st_read(struct inode * inode, struct file * filp, char * buf, int count)
else if (scsi_tapes[dev].eof) {
scsi_tapes[dev].eof_hit = 1;
SCpnt->request.dev = -1; /* Mark as not busy */
if (total)
return total;
else
if (total == 0 && scsi_tapes[dev].eof == 1)
scsi_tapes[dev].eof = 0;
if (total == 0 && scsi_tapes[dev].eof == 2)
return (-EIO);
return total;
}
} /* for (total = 0; total < count; ) */
......@@ -956,7 +967,7 @@ static int st_int_ioctl(struct inode * inode,struct file * file,
cmd[0] = SPACE;
cmd[1] = 3;
#ifdef DEBUG
printk("st%d: Spacing to end of tape media.\n", dev);
printk("st%d: Spacing to end of recorded medium.\n", dev);
#endif
break;
case MTERASE:
......@@ -1050,6 +1061,8 @@ static int st_int_ioctl(struct inode * inode,struct file * file,
if (!ioctl_result) {
if (cmd_in == MTBSFM)
ioctl_result = st_int_ioctl(inode, file, MTFSF, 1);
else if (cmd_in == MTFSFM)
ioctl_result = st_int_ioctl(inode, file, MTBSF, 1);
else if (cmd_in == MTSETBLK) {
scsi_tapes[dev].block_size = arg;
scsi_tapes[dev].buffer->buffer_blocks =
......
......@@ -27,10 +27,10 @@ typedef struct {
Scsi_Device* device;
unsigned dirty:1;
unsigned rw:2;
unsigned eof:1;
unsigned eof:2;
unsigned write_prot:1;
unsigned in_use:1;
unsigned eof_hit:2;
unsigned eof_hit:1;
ST_buffer * buffer;
int block_size;
int min_block;
......
......@@ -36,7 +36,7 @@ console.o : console.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/
/usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/linux/config.h \
/usr/include/linux/autoconf.h /usr/include/linux/string.h /usr/include/linux/errno.h \
/usr/include/linux/kd.h /usr/include/linux/keyboard.h /usr/include/asm/io.h \
/usr/include/asm/segment.h vt_kern.h
/usr/include/asm/segment.h vt_kern.h /usr/include/linux/vt.h
keyboard.o : keyboard.c /usr/include/linux/sched.h /usr/include/linux/head.h \
/usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
/usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
......@@ -143,9 +143,9 @@ tty_io.o : tty_io.c /usr/include/linux/types.h /usr/include/linux/errno.h /usr/i
/usr/include/linux/kernel.h /usr/include/linux/time.h /usr/include/linux/param.h \
/usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
/usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
/usr/include/linux/ctype.h /usr/include/linux/kd.h /usr/include/linux/string.h \
/usr/include/linux/keyboard.h /usr/include/asm/segment.h /usr/include/asm/bitops.h \
vt_kern.h
/usr/include/linux/timer.h /usr/include/linux/ctype.h /usr/include/linux/kd.h \
/usr/include/linux/string.h /usr/include/linux/keyboard.h /usr/include/asm/segment.h \
/usr/include/asm/bitops.h vt_kern.h /usr/include/linux/vt.h
tty_ioctl.o : tty_ioctl.c /usr/include/linux/types.h /usr/include/linux/termios.h \
/usr/include/linux/errno.h /usr/include/linux/sched.h /usr/include/linux/head.h \
/usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
......
......@@ -170,7 +170,10 @@ static int console_blanked = 0;
#define halfcolor (vc_cons[currcons].vc_halfcolor)
#define kbdmode (vc_cons[currcons].vc_kbdmode)
#define tab_stop (vc_cons[currcons].vc_tab_stop)
#define vcmode (vt_cons[currcons].vc_mode)
#define vtmode (vt_cons[currcons].vt_mode)
#define vtpid (vt_cons[currcons].vt_pid)
#define vtnewvt (vt_cons[currcons].vt_newvt)
#define set_kbd(x) set_vc_kbd_flag(kbd_table+currcons,x)
#define clr_kbd(x) clr_vc_kbd_flag(kbd_table+currcons,x)
......@@ -285,7 +288,7 @@ static void set_origin(int currcons)
{
if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM)
return;
if (currcons != fg_console || console_blanked || vtmode == KD_GRAPHICS)
if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
return;
cli();
outb_p(12, video_port_reg);
......@@ -1194,7 +1197,7 @@ void con_write(struct tty_struct * tty)
state = ESnormal;
}
}
if (vtmode == KD_GRAPHICS)
if (vcmode == KD_GRAPHICS)
return;
set_cursor(currcons);
}
......@@ -1203,7 +1206,7 @@ void do_keyboard_interrupt(void)
{
TTY_READ_FLUSH(TTY_TABLE(0));
timer_active &= ~(1<<BLANK_TIMER);
if (vt_cons[fg_console].vt_mode == KD_GRAPHICS)
if (vt_cons[fg_console].vc_mode == KD_GRAPHICS)
return;
if (console_blanked) {
timer_table[BLANK_TIMER].expires = 0;
......@@ -1311,7 +1314,14 @@ long con_init(long kmem_start)
pos = origin = video_mem_start = base;
scr_end = video_mem_end = (base += screen_size);
vc_scrbuf[currcons] = (unsigned short *) origin;
vtmode = KD_TEXT;
vcmode = KD_TEXT;
vtmode.mode = VT_AUTO;
vtmode.waitv = 0;
vtmode.relsig = 0;
vtmode.acqsig = 0;
vtmode.frsig = 0;
vtpid = -1;
vtnewvt = -1;
clr_kbd(kbdraw);
def_color = 0x07; /* white */
ulcolor = 0x0f; /* bold white */
......@@ -1360,6 +1370,8 @@ static void set_scrmem(int currcons)
void blank_screen(void)
{
if (console_blanked)
return;
timer_table[BLANK_TIMER].fn = unblank_screen;
get_scrmem(fg_console);
hide_cursor(fg_console);
......@@ -1369,6 +1381,8 @@ void blank_screen(void)
void unblank_screen(void)
{
if (!console_blanked)
return;
timer_table[BLANK_TIMER].fn = blank_screen;
if (blankinterval) {
timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
......@@ -1463,7 +1477,7 @@ void console_print(const char * b)
pos+=2;
}
set_cursor(currcons);
if (vt_cons[fg_console].vt_mode == KD_GRAPHICS)
if (vt_cons[fg_console].vc_mode == KD_GRAPHICS)
return;
timer_active &= ~(1<<BLANK_TIMER);
if (console_blanked) {
......@@ -1483,5 +1497,7 @@ int con_open(struct tty_struct *tty, struct file * filp)
{
tty->write = con_write;
tty->ioctl = vt_ioctl;
if (tty->line > NR_CONSOLES)
return -ENODEV;
return 0;
}
......@@ -32,6 +32,8 @@ extern void ctrl_alt_del(void);
extern void change_console(unsigned int new_console);
unsigned long kbd_flags = 0;
unsigned long kbd_dead_keys = 0;
unsigned long kbd_prev_dead_keys = 0;
struct kbd_struct kbd_table[NR_CONSOLES];
static struct kbd_struct * kbd = kbd_table;
......@@ -54,59 +56,54 @@ static struct pt_regs * pt_regs;
static void keyboard_interrupt(int int_pt_regs)
{
static unsigned char rep = 0xff;
unsigned char scancode, x;
unsigned char scancode;
pt_regs = (struct pt_regs *) int_pt_regs;
scancode=inb_p(0x60);
x=inb_p(0x61);
outb_p(x|0x80, 0x61);
outb_p(x&0x7f, 0x61);
if (scancode == 0xe0)
set_kbd_flag(KG_E0);
else if (scancode == 0xe1)
set_kbd_flag(KG_E1);
tty = TTY_TABLE(0);
kbd = kbd_table + fg_console;
if (vc_kbd_flag(kbd,VC_RAW)) {
kbd_flags = 0;
put_queue(scancode);
do_keyboard_interrupt();
return;
}
if (scancode == 0xe0 || scancode == 0xe1)
return;
/*
* The keyboard maintains its own internal caps lock and num lock
* statuses. In caps lock mode E0 AA precedes make code and E0 2A
* follows break code. In num lock mode, E0 2A precedes make
* code and E0 AA follows break code. We do our own book-keeping,
* so we will just ignore these.
*/
if (kbd_flag(KG_E0) && (scancode == 0x2a || scancode == 0xaa)) {
clr_kbd_flag(KG_E0);
clr_kbd_flag(KG_E1);
return;
}
/*
* Repeat a key only if the input buffers are empty or the
* characters get echoed locally. This makes key repeat usable
* with slow applications and unders heavy loads.
*/
if (scancode == rep) {
if (!(vc_kbd_flag(kbd,VC_REPEAT) && tty &&
(L_ECHO(tty) ||
(EMPTY(&tty->secondary) &&
EMPTY(&tty->read_q))))) {
clr_kbd_flag(KG_E0);
clr_kbd_flag(KG_E1);
return;
while (inb_p(0x64) & 1) {
kbd_prev_dead_keys |= kbd_dead_keys;
if (!kbd_dead_keys)
kbd_prev_dead_keys = 0;
kbd_dead_keys = 0;
scancode = inb_p(0x60);
tty = TTY_TABLE(0);
kbd = kbd_table + fg_console;
if (vc_kbd_flag(kbd,VC_RAW)) {
kbd_flags = 0;
put_queue(scancode);
continue;
}
if (scancode == 0xe0) {
set_kbd_dead(KGD_E0);
continue;
} else if (scancode == 0xe1) {
set_kbd_dead(KGD_E1);
continue;
}
/*
* The keyboard maintains its own internal caps lock and num lock
* statuses. In caps lock mode E0 AA precedes make code and E0 2A
* follows break code. In num lock mode, E0 2A precedes make
* code and E0 AA follows break code. We do our own book-keeping,
* so we will just ignore these.
*/
if (kbd_dead(KGD_E0) && (scancode == 0x2a || scancode == 0xaa))
continue;
/*
* Repeat a key only if the input buffers are empty or the
* characters get echoed locally. This makes key repeat usable
* with slow applications and unders heavy loads.
*/
if (scancode == rep) {
if (!(vc_kbd_flag(kbd,VC_REPEAT) && tty &&
(L_ECHO(tty) ||
(EMPTY(&tty->secondary) &&
EMPTY(&tty->read_q)))))
continue;
}
rep = scancode;
key_table[scancode](scancode);
}
rep = scancode;
key_table[scancode](scancode);
do_keyboard_interrupt();
clr_kbd_flag(KG_E0);
clr_kbd_flag(KG_E1);
}
static void put_queue(int ch)
......@@ -147,7 +144,7 @@ static void puts_queue(char *cp)
static void ctrl(int sc)
{
if (kbd_flag(KG_E0))
if (kbd_dead(KGD_E0))
set_kbd_flag(KG_RCTRL);
else
set_kbd_flag(KG_LCTRL);
......@@ -155,7 +152,7 @@ static void ctrl(int sc)
static void alt(int sc)
{
if (kbd_flag(KG_E0))
if (kbd_dead(KGD_E0))
set_kbd_flag(KG_ALTGR);
else
set_kbd_flag(KG_ALT);
......@@ -163,7 +160,7 @@ static void alt(int sc)
static void unctrl(int sc)
{
if (kbd_flag(KG_E0))
if (kbd_dead(KGD_E0))
clr_kbd_flag(KG_RCTRL);
else
clr_kbd_flag(KG_LCTRL);
......@@ -171,7 +168,7 @@ static void unctrl(int sc)
static void unalt(int sc)
{
if (kbd_flag(KG_E0))
if (kbd_dead(KGD_E0))
clr_kbd_flag(KG_ALTGR);
else {
clr_kbd_flag(KG_ALT);
......@@ -218,6 +215,8 @@ static void uncaps(int sc)
static void show_ptregs(void)
{
if (!pt_regs)
return;
printk("\nEIP: %04x:%08x",0xffff & pt_regs->cs,pt_regs->eip);
if (pt_regs->cs & 3)
printk(" ESP: %04x:%08x",0xffff & pt_regs->cs,pt_regs->eip);
......@@ -1167,7 +1166,7 @@ static void cursor(int sc)
ctrl_alt_del();
return;
}
if (kbd_flag(KG_E0)) {
if (kbd_dead(KGD_E0)) {
cur(sc);
return;
}
......@@ -1226,7 +1225,7 @@ static void func(int sc)
static void slash(int sc)
{
if (!kbd_flag(KG_E0))
if (!kbd_dead(KGD_E0))
do_self(sc);
else if (vc_kbd_flag(kbd,VC_APPLIC))
applkey('Q');
......@@ -1244,7 +1243,7 @@ static void star(int sc)
static void enter(int sc)
{
if (kbd_flag(KG_E0) && vc_kbd_flag(kbd,VC_APPLIC))
if (kbd_dead(KGD_E0) && vc_kbd_flag(kbd,VC_APPLIC))
applkey('M');
else {
put_queue(13);
......@@ -1418,7 +1417,6 @@ static fptr key_table[] = {
unsigned long kbd_init(unsigned long kmem_start)
{
int i;
unsigned char a;
struct kbd_struct * kbd;
kbd = kbd_table + 0;
......@@ -1428,8 +1426,6 @@ unsigned long kbd_init(unsigned long kmem_start)
kbd->kbd_flags = KBDFLAGS;
}
request_irq(KEYBOARD_IRQ,keyboard_interrupt);
a=inb_p(0x61);
outb_p(a|0x80,0x61);
outb_p(a,0x61);
keyboard_interrupt(0);
return kmem_start;
}
......@@ -160,8 +160,9 @@ static void aux_interrupt(int cpl)
static void release_aux(struct inode * inode, struct file * file)
{
poll_status();
outb_p(AUX_DISABLE,AUX_COMMAND); /* Disable Aux device */
aux_write_dev(AUX_DISABLE_DEV); /* disable aux device */
poll_status();
outb_p(AUX_DISABLE,AUX_COMMAND); /* Disable Aux device */
aux_write_cmd(AUX_INTS_OFF); /* disable controller ints */
free_irq(AUX_IRQ);
aux_busy = 0;
......@@ -288,6 +289,9 @@ unsigned long psaux_init(unsigned long kmem_start)
queue->head = queue->tail = 0;
queue->proc_list = NULL;
aux_present = 1;
poll_status();
outb_p(AUX_DISABLE,AUX_COMMAND); /* Disable Aux device */
aux_write_cmd(AUX_INTS_OFF); /* disable controller ints */
return kmem_start;
}
......
......@@ -28,10 +28,8 @@ static void pty_close(struct tty_struct * tty, struct file * filp)
if (!tty->link)
return;
wake_up_interruptible(&tty->link->write_q.proc_list);
if (IS_A_PTY_MASTER(tty->line)) {
if (tty->link->session > 0)
kill_sl(tty->link->session,SIGHUP,1);
}
if (IS_A_PTY_MASTER(tty->line))
tty_hangup(tty->link);
}
static inline void pty_copy(struct tty_struct * from, struct tty_struct * to)
......
......@@ -59,7 +59,7 @@
*
*/
#define NEW_INTERRUPT_ROUTINE
#undef NEW_INTERRUPT_ROUTINE
#define WAKEUP_CHARS (3*TTY_BUF_SIZE/4)
......@@ -401,9 +401,8 @@ static void modem_status_intr(struct async_struct * info)
unsigned char status = inb(UART_MSR + info->port);
if (!(info->tty->termios->c_cflag & CLOCAL)) {
if (((status & (UART_MSR_DCD|UART_MSR_DDCD)) == UART_MSR_DDCD)
&& info->tty->session > 0)
kill_sl(info->tty->session,SIGHUP,1);
if ((status & (UART_MSR_DCD|UART_MSR_DDCD)) == UART_MSR_DDCD)
tty_hangup(info->tty);
if (info->tty->termios->c_cflag & CRTSCTS)
info->tty->stopped = !(status & UART_MSR_CTS);
......@@ -523,10 +522,8 @@ static void rs_timer(void)
if (!clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
wake_up_interruptible(&info->tty->write_q.proc_list);
}
if (!clear_bit(RS_EVENT_HUP_PGRP, &info->event)) {
if (info->tty->session > 0)
kill_sl(info->tty->session,SIGHUP,1);
}
if (!clear_bit(RS_EVENT_HUP_PGRP, &info->event))
tty_hangup(info->tty);
if (!clear_bit(RS_EVENT_BREAK_INT, &info->event)) {
flush_input(info->tty);
flush_output(info->tty);
......
This diff is collapsed.
......@@ -386,16 +386,22 @@ int tty_ioctl(struct inode * inode, struct file * file,
return -EINVAL;
}
case TIOCCONS:
if (!IS_A_PTY(dev))
return -EINVAL;
if (IS_A_CONSOLE(dev)) {
if (!suser())
return -EPERM;
redirect = NULL;
return 0;
}
if (redirect)
return -EBUSY;
if (!suser())
return -EPERM;
if (IS_A_PTY_MASTER(dev))
redirect = other_tty;
else
else if (IS_A_PTY_SLAVE(dev))
redirect = tty;
else
return -EINVAL;
return 0;
case FIONBIO:
arg = get_fs_long((unsigned long *) arg);
......
......@@ -20,13 +20,24 @@
#include "vt_kern.h"
/*
* console (vt and kd) routines, as defined by usl svr4 manual
* Console (vt and kd) routines, as defined by USL SVR4 manual
*
* One point of difference: SYSV vt's are /dev/vtX, which X >= 0, and
* /dev/console is a separate ttyp. Under Linux, /dev/tty0 is /dev/console,
* and the vc start at /dev/ttyX, X >= 1. We maintain that here, so we will
* always treat our set of vt as numbered 1..NR_CONSOLES (corresponding to
* ttys 0..NR_CONSOLES-1).
*
* Mostly done for X386, but with some slight differences and omissions.
* Should be useable by other SYSV programs in the future.
*/
struct vt_cons vt_cons[NR_CONSOLES];
extern int sys_ioperm(unsigned long from, unsigned long num, int on);
extern void set_leds(void);
extern void change_console(unsigned int new_console);
extern void complete_change_console(unsigned int new_console);
/*
* these are the valid i/o ports we're allowed to change. they map all the
......@@ -37,26 +48,53 @@ extern void set_leds(void);
#define GPNUM (GPLAST - GPFIRST + 1)
/*
* turns on sound of some freq. 0 turns it off.
* stolen from console.c, so i'm not sure if its the correct interpretation
* Generates sound of some count for some number of clock ticks
* [count = 1193180 / frequency]
*
* If freq is 0, will turn off sound, else will turn it on for that time.
* If msec is 0, will return immediately, else will sleep for msec time, then
* turn sound off.
*
* We use the BEEP_TIMER vector since we're using the same method to
* generate sound, and we'll overwrite any beep in progress. That may
* be something to fix later, if we like.
*
* We also return immediately, which is what was implied within the X
* comments - KDMKTONE doesn't put the process to sleep.
*/
static int
kiocsound(unsigned int freq)
void
kd_nosound(void)
{
if (freq == 0) {
/* disable counter 2 */
outb(inb_p(0x61)&0xFC, 0x61);
}
else {
/* disable counter 2 */
outb(inb_p(0x61)&0xFC, 0x61);
return;
}
void
kd_mksound(unsigned int count, unsigned int ticks)
{
if (count)
{
/* enable counter 2 */
outb_p(inb_p(0x61)|3, 0x61);
/* set command for counter 2, 2 byte write */
outb_p(0xB6, 0x43);
/* select desired HZ */
outb_p(freq & 0xff, 0x42);
outb((freq >> 8) & 0xff, 0x42);
outb_p(count & 0xff, 0x42);
outb((count >> 8) & 0xff, 0x42);
if (ticks)
{
timer_table[BEEP_TIMER].expires = jiffies + ticks;
timer_table[BEEP_TIMER].fn = kd_nosound;
timer_active |= (1 << BEEP_TIMER);
}
}
return 0;
else
kd_nosound();
return;
}
/*
......@@ -66,7 +104,7 @@ kiocsound(unsigned int freq)
int vt_ioctl(struct tty_struct *tty, struct file * file,
unsigned int cmd, unsigned int arg)
{
int console;
int console, i;
unsigned char ucval;
struct kbd_struct * kbd;
......@@ -78,7 +116,22 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
kbd = kbd_table + console;
switch (cmd) {
case KIOCSOUND:
return kiocsound((unsigned int)arg);
kd_mksound((unsigned int)arg, 0);
return 0;
case KDMKTONE:
{
unsigned int ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
/*
* Generate the tone for the appropriate number of ticks.
* If the time is zero, turn off sound ourselves.
*/
kd_mksound(arg & 0xffff, ticks);
if (ticks == 0)
kd_nosound();
return 0;
}
case KDGKBTYPE:
/*
......@@ -120,21 +173,25 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
default:
return -EINVAL;
}
if (vt_cons[console].vt_mode == (unsigned char) arg)
if (vt_cons[console].vc_mode == (unsigned char) arg)
return 0;
vt_cons[console].vt_mode = (unsigned char) arg;
vt_cons[console].vc_mode = (unsigned char) arg;
if (console != fg_console)
return 0;
/*
* explicitly blank/unblank the screen if switching modes
*/
if (arg == KD_TEXT)
unblank_screen();
else {
timer_active &= 1<<BLANK_TIMER;
timer_active &= ~(1<<BLANK_TIMER);
blank_screen();
}
return 0;
case KDGETMODE:
verify_area((void *) arg, sizeof(unsigned long));
put_fs_long(vt_cons[console].vt_mode, (unsigned long *) arg);
put_fs_long(vt_cons[console].vc_mode, (unsigned long *) arg);
return 0;
case KDMAPDISP:
......@@ -155,6 +212,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
return -EINVAL;
flush_input(tty);
return 0;
case KDGKBMODE:
verify_area((void *) arg, sizeof(unsigned long));
ucval = vc_kbd_flag(kbd, VC_RAW);
......@@ -172,6 +230,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
ucval |= LED_CAP;
put_fs_byte(ucval, (unsigned char *) arg);
return 0;
case KDSETLED:
if (arg & ~7)
return -EINVAL;
......@@ -190,6 +249,95 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
set_leds();
return 0;
case VT_SETMODE:
{
struct vt_mode *vtmode = (struct vt_mode *)arg;
char mode;
verify_area((void *)vtmode, sizeof(struct vt_mode));
mode = get_fs_byte(&vtmode->mode);
if (mode != VT_AUTO && mode != VT_PROCESS)
return -EINVAL;
vt_cons[console].vt_mode.mode = mode;
vt_cons[console].vt_mode.waitv = get_fs_byte(&vtmode->waitv);
vt_cons[console].vt_mode.relsig = get_fs_word(&vtmode->relsig);
vt_cons[console].vt_mode.acqsig = get_fs_word(&vtmode->acqsig);
/* the frsig is ignored, so we set it to 0 */
vt_cons[console].vt_mode.frsig = 0;
vt_cons[console].vt_pid = current->pid;
vt_cons[console].vt_newvt = 0;
return 0;
}
case VT_GETMODE:
{
struct vt_mode *vtmode = (struct vt_mode *)arg;
verify_area((void *)arg, sizeof(struct vt_mode));
put_fs_byte(vt_cons[console].vt_mode.mode, &vtmode->mode);
put_fs_byte(vt_cons[console].vt_mode.waitv, &vtmode->waitv);
put_fs_word(vt_cons[console].vt_mode.relsig, &vtmode->relsig);
put_fs_word(vt_cons[console].vt_mode.acqsig, &vtmode->acqsig);
put_fs_word(vt_cons[console].vt_mode.frsig, &vtmode->frsig);
return 0;
}
/*
* Returns the first available (non-opened) console.
*/
case VT_OPENQRY:
verify_area((void *) arg, sizeof(long));
for (i = 1; i <= NR_CONSOLES; ++i)
if (!tty_table[i] || tty_table[i]->count == 0)
break;
put_fs_long(i <= NR_CONSOLES ? i : -1, (unsigned long *)arg);
return 0;
/*
* ioctl(fd, VT_ACTIVATE, num) will cause us to switch to vt # num,
* with num >= 1 (switches to vt 0, our console) are not allowed, just
* to preserve sanity.
*/
case VT_ACTIVATE:
if (arg == 0 || arg > NR_CONSOLES)
return -ENXIO;
change_console(arg - 1);
return 0;
/*
* If a vt is under process control, the kernel will not switch to it
* immediately, but postpone the operation until the process calls this
* ioctl, allowing the switch to complete.
*
* XXX Under X, the switching code calls VT_RELDISP with an arg of 2
* when it has switched back to it's vt. That's not kosher according
* to my documentation, which says this is only called when releasing
* the vt under your control.
*/
case VT_RELDISP:
if (vt_cons[console].vt_mode.mode != VT_PROCESS ||
vt_cons[console].vt_newvt < 0)
return -EINVAL;
if (arg != 0)
{
/*
* If arg is nonzero, the current vt has been released,
* so we can go ahead and complete the switch.
*/
int newvt = vt_cons[console].vt_newvt;
vt_cons[console].vt_newvt = -1;
complete_change_console(newvt);
}
else
{
/*
* Mark that we've performed our part and return.
*/
vt_cons[console].vt_newvt = -1;
}
return 0;
default:
return -EINVAL;
}
......
......@@ -5,11 +5,17 @@
* this really is an extension of the vc_cons structure in console.c, but
* with information needed by the vt package
*/
#include <linux/vt.h>
extern struct vt_cons {
int vt_mode; /* KD_TEXT, ... */
unsigned char vc_mode; /* KD_TEXT, ... */
unsigned char vc_kbdraw;
unsigned char vc_kbde0;
unsigned char vc_kbdleds;
struct vt_mode vt_mode;
int vt_pid;
int vt_newvt;
} vt_cons[NR_CONSOLES];
#endif /* _VT_KERN_H */
......@@ -31,7 +31,6 @@ void verify_area(void * addr,int size)
start = (unsigned long) addr;
size += start & 0xfff;
start &= 0xfffff000;
start += get_base(current->ldt[2]);
while (size>0) {
size -= 4096;
write_verify(start);
......@@ -39,31 +38,6 @@ void verify_area(void * addr,int size)
}
}
int copy_mem(int nr,struct task_struct * p)
{
unsigned long old_data_base,new_data_base,data_limit;
unsigned long old_code_base,new_code_base,code_limit;
code_limit = get_limit(0x0f);
data_limit = get_limit(0x17);
old_code_base = get_base(current->ldt[1]);
old_data_base = get_base(current->ldt[2]);
if (old_data_base != old_code_base) {
printk("ldt[0]: %08x %08x\n",current->ldt[0].a,current->ldt[0].b);
printk("ldt[1]: %08x %08x\n",current->ldt[1].a,current->ldt[1].b);
printk("ldt[2]: %08x %08x\n",current->ldt[2].a,current->ldt[2].b);
panic("We don't support separate I&D");
}
if (data_limit < code_limit)
panic("Bad data_limit");
new_data_base = old_data_base;
new_code_base = old_code_base;
p->start_code = new_code_base;
set_base(p->ldt[1],new_code_base);
set_base(p->ldt[2],new_data_base);
return copy_page_tables(p);
}
static int find_empty_process(void)
{
int i, task_nr;
......@@ -163,7 +137,7 @@ int sys_fork(long ebx,long ecx,long edx,
if (last_task_used_math == current)
__asm__("clts ; fnsave %0 ; frstor %0"::"m" (p->tss.i387));
p->kernel_stack_page = get_free_page(GFP_KERNEL);
if (!p->kernel_stack_page || copy_mem(nr,p)) {
if (!p->kernel_stack_page || copy_page_tables(p)) {
task[nr] = NULL;
REMOVE_LINKS(p);
free_page(p->kernel_stack_page);
......
......@@ -64,7 +64,7 @@ int sys_syslog(int type, char * buf, int len)
sti();
}
i = 0;
while (log_size && len) {
while (log_size && i < len) {
c = *((char *) log_page+log_start);
log_start++;
log_size--;
......
......@@ -229,6 +229,8 @@ int sys_ptrace(long request, long pid, long addr, long data)
current->flags |= PF_PTRACED;
return 0;
}
if (pid == 1) /* you may not mess with init */
return -EPERM;
if (!(child = get_task(pid)))
return -ESRCH;
if (request == PTRACE_ATTACH) {
......
......@@ -14,6 +14,7 @@ SUBDIRS = tcp
ifdef CONFIG_TCPIP
NET_SUBDIRS = tcp
TCP_ARCHIVE = tcp/tcpip.a
endif
.c.o:
......@@ -26,7 +27,7 @@ endif
OBJS = socket.o unix.o
net.o: $(OBJS) subdirs
$(LD) -r -o net.o $(OBJS) tcp/tcpip.o
$(LD) -r -o net.o $(OBJS) $(TCP_ARCHIVE)
subdirs: dummy
......@@ -40,8 +41,6 @@ dep:
$(CPP) -M *.c > .depend
@for i in $(SUBDIRS); do (cd $$i && echo $$i && $(MAKE) dep) || exit; done
socket.o: Makefile
dummy:
#
......
......@@ -8,24 +8,25 @@ arp.o : arp.c /usr/include/linux/types.h /usr/include/linux/string.h /usr/includ
/usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
/usr/include/linux/nfs_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
/usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
/usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/socket.h \
/usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/cdefs.h /usr/include/sys/socket.h \
/usr/include/asm/system.h timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h \
eth.h tcp.h sock.h arp.h
dev.o : dev.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/linux/types.h \
/usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
/usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
/usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
/usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
/usr/include/linux/iso_fs_i.h /usr/include/linux/nfs_fs_i.h /usr/include/linux/nfs.h \
/usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
/usr/include/linux/iso_fs_sb.h /usr/include/linux/nfs_fs_sb.h /usr/include/linux/mm.h \
/usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
/usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
/usr/include/linux/string.h /usr/include/linux/socket.h /usr/include/netinet/in.h \
/usr/include/features.h /usr/include/sys/cdefs.h /usr/include/sys/socket.h dev.h \
eth.h timer.h ip.h /usr/include/linux/sock_ioctl.h tcp.h sock.h /usr/include/linux/errno.h \
/usr/include/linux/interrupt.h arp.h
/usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/config.h \
/usr/include/linux/autoconf.h /usr/include/linux/socket.h /usr/include/netinet/in.h \
/usr/include/features.h /usr/include/sys/cdefs.h /usr/include/sys/socket.h /usr/include/asm/system.h \
timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h eth.h tcp.h sock.h arp.h
dev.o : dev.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/linux/config.h \
/usr/include/linux/autoconf.h /usr/include/linux/types.h /usr/include/linux/kernel.h \
/usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
/usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/dirent.h \
/usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
/usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
/usr/include/linux/nfs_fs_i.h /usr/include/linux/nfs.h /usr/include/linux/minix_fs_sb.h \
/usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
/usr/include/linux/nfs_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
/usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
/usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/string.h \
/usr/include/linux/socket.h /usr/include/netinet/in.h /usr/include/features.h \
/usr/include/sys/cdefs.h /usr/include/sys/socket.h dev.h eth.h timer.h ip.h \
/usr/include/linux/sock_ioctl.h tcp.h sock.h /usr/include/linux/errno.h /usr/include/linux/interrupt.h \
arp.h
eth.o : eth.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/linux/types.h \
/usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
/usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
......
......@@ -19,8 +19,8 @@
OBJS = sock.o tcp.o ip.o timer.o we.o arp.o udp.o eth.o Space.o loopback.o \
icmp.o protocols.o raw.o pack_type.o dev.o packet.o
tcpip.o: $(OBJS)
$(LD) -r -o tcpip.o $(OBJS)
tcpip.a: $(OBJS)
$(AR) rcs tcpip.a $(OBJS)
subdirs: dummy
for i in $(SUBDIRS); do (cd $$i; $(MAKE)); done
......
......@@ -73,19 +73,16 @@ static void
send_arp_q(void)
{
struct sk_buff *skb;
struct sk_buff *skb2;
struct sk_buff *next;
cli();
if (arp_q == NULL) return;
skb = arp_q;
do {
next = arp_q;
arp_q = NULL;
sti();
while ((skb = next) != NULL) {
if (skb->magic != ARP_QUEUE_MAGIC)
{
printk ("arp.c skb with bad magic - %X: squashing queue\n");
cli();
arp_q = NULL;
sti();
printk ("arp.c skb with bad magic - %X: squashing queue\n", skb->magic);
return;
}
/* extra consistancy check. */
......@@ -94,46 +91,54 @@ send_arp_q(void)
|| (unsigned long)(skb->next) > 16*1024*1024
#endif
)
{
printk ("dev.c: *** bug bad skb->next, squashing queue \n");
cli();
arp_q = NULL;
sti();
return;
}
/* first remove skb from the queue. */
next = skb->next;
if (next == skb)
{
next = NULL;
}
else
{
skb->prev->next = next;
next->prev = skb->prev;
}
skb->magic = 0;
skb2=skb->next;
skb->next = NULL;
skb->prev = NULL;
sti();
if (!skb->dev->rebuild_header (skb+1, skb->dev))
{
cli();
if (skb->next == skb)
{
arp_q = NULL;
}
else
{
skb->next->prev = skb->prev;
skb->prev->next = skb->next;
arp_q = skb->next;
}
skb->next = NULL;
skb->prev = NULL;
skb->arp = 1;
sti();
skb->dev->queue_xmit (skb, skb->dev, 0);
if (arp_q == NULL) break;
cli();
}
skb=skb2;
} while (skb != arp_q);
sti();
else
{
cli();
skb->magic = ARP_QUEUE_MAGIC;
if (arp_q == NULL)
{
skb->next = skb;
skb->prev = skb;
arp_q = skb;
}
else
{
skb->next = arp_q;
skb->prev = arp_q->prev;
arp_q->prev->next = skb;
arp_q->prev = skb;
}
sti();
}
}
}
static void
......
......@@ -242,6 +242,12 @@ lock_skb (struct sk_buff *skb)
void
kfree_skb (struct sk_buff *skb, int rw)
{
if (skb == NULL)
{
printk ("kfree_skb: skb = NULL\n");
return;
}
if (skb->lock)
{
skb->free = 1;
......@@ -300,7 +306,7 @@ get_new_socknum(struct proto *prot, unsigned short base)
int best=0;
int size=32767; /* a big num. */
volatile struct sock *sk;
start++;
if (base == 0) base = PROT_SOCK+1+(start % 1024);
if (base <= PROT_SOCK)
{
......@@ -309,7 +315,7 @@ get_new_socknum(struct proto *prot, unsigned short base)
/* now look through the entire array and try to find an empty
ptr. */
for (i = 0; i < SOCK_ARRAY_SIZE; i++)
for (i=0; i < SOCK_ARRAY_SIZE; i++)
{
j = 0;
sk = prot->sock_array[(i+base+1) & (SOCK_ARRAY_SIZE -1)];
......@@ -318,7 +324,13 @@ get_new_socknum(struct proto *prot, unsigned short base)
sk = sk->next;
j++;
}
if (j == 0) return (i+base+1);
if (j == 0)
{
start = (i+1+start )%1024;
PRINTK ("get_new_socknum returning %d, start = %d\n",
i+base+1,start);
return (i+base+1);
}
if (j < size)
{
best = i;
......@@ -330,6 +342,7 @@ get_new_socknum(struct proto *prot, unsigned short base)
{
best += SOCK_ARRAY_SIZE;
}
PRINTK ("get_new_socknum returning %d, start = %d\n", best+base+1,start);
return (best+base+1);
}
......@@ -445,12 +458,15 @@ destroy_sock(volatile struct sock *sk)
/* just to be safe. */
sk->inuse = 1;
/* incase it's sleeping somewhere. */
if (!sk->dead) wake_up (sk->sleep);
remove_sock (sk);
/* now we can no longer get new packets. */
delete_timer((struct timer *)&sk->time_wait);
if (sk->send_tmp) kfree_skb (sk->send_tmp, FREE_WRITE);
if (sk->send_tmp != NULL) kfree_skb (sk->send_tmp, FREE_WRITE);
/* cleanup up the write buffer. */
for (skb = sk->wfront; skb != NULL; )
......@@ -617,7 +633,7 @@ destroy_sock(volatile struct sock *sk)
/* now if everything is gone we can free the socket structure,
otherwise we need to keep it around until everything is gone. */
if (sk->rmem_alloc <= 0 && sk->wmem_alloc <= 0)
if (sk->rmem_alloc == 0 && sk->wmem_alloc == 0)
{
kfree_s ((void *)sk,sizeof (*sk));
}
......@@ -634,6 +650,8 @@ destroy_sock(volatile struct sock *sk)
sk->timeout = TIME_DESTROY;
reset_timer ((struct timer *)&sk->time_wait);
}
PRINTK ("leaving destroy_sock\n");
}
......@@ -1004,10 +1022,9 @@ ip_proto_create (struct socket *sock, int protocol)
/* how many packets we should send before forcing an ack.
if this is set to zero it is the same as sk->delay_acks = 0 */
sk->max_ack_backlog = MAX_ACK_BACKLOG;
sk->max_ack_backlog = 0;
sk->inuse = 0;
sk->delay_acks = 1; /* default to waiting a while before sending
acks. */
sk->delay_acks = 0;
sk->wback = NULL;
sk->wfront = NULL;
sk->rqueue = NULL;
......@@ -1090,6 +1107,7 @@ ip_proto_release(struct socket *sock, struct socket *peer)
}
else
{
PRINTK ("sk->linger set.\n");
sk->prot->close(sk, 0);
cli();
while (sk->state != TCP_CLOSE)
......@@ -1109,6 +1127,7 @@ ip_proto_release(struct socket *sock, struct socket *peer)
/* this will destroy it. */
release_sock (sk);
sock->data = NULL;
PRINTK ("ip_proto_release returning\n");
return (0);
}
......
This diff is collapsed.
......@@ -84,23 +84,23 @@ enum {
#define MAX_RESET_SIZE 40 + sizeof (struct sk_buff) + MAX_HEADER
#define MAX_WINDOW 12000
#define MIN_WINDOW 2048
#define MAX_ACK_BACKLOG 8
#define MAX_ACK_BACKLOG 2
#define MIN_WRITE_SPACE 2048
#define TCP_WINDOW_DIFF 2048
#define TCP_RETR1 7 /* this is howmany retries it does
#define TCP_RETR1 10 /* this is howmany retries it does
before it tries to figure out
if the gateway is down. */
#define TCP_RETR2 10 /* this should take between 3 and
ten minutes ( 1024 * rtt). */
#define TCP_RETR2 25 /* this should take at least
90 minutes to time out. */
#define TCP_TIMEOUT_LEN 720000 /* should be about 2 hrs. */
#define TCP_TIMEWAIT_LEN 6000 /* How long to wait to sucessfully
close the socket, about 60 seconds. */
#define TCP_ACK_TIME 35 /* time to delay before sending an ack. */
#define TCP_DONE_TIME 2500 /* maximum time to wait before actually destroying
#define TCP_DONE_TIME 250 /* maximum time to wait before actually destroying
a socket. */
#define TCP_WRITE_TIME 100 /* initial time to wait for an ack,
after last transmit. */
......
......@@ -232,8 +232,18 @@ net_timer (void)
break;
case TIME_WRITE: /* try to retransmit. */
/* it could be we got here because we needed
to send an ack. So we need to check for that. */
if (sk->send_head != NULL)
{
if (before (jiffies, sk->send_head->when + 2*sk->rtt))
{
sk->time_wait.len = 2*sk->rtt;
sk->timeout = TIME_WRITE;
reset_timer ((struct timer *)&sk->time_wait);
release_sock (sk);
break;
}
PRINTK ("retransmitting.\n");
sk->prot->retransmit (sk, 0);
......@@ -268,27 +278,6 @@ net_timer (void)
release_sock (sk);
break;
}
/* if we have stuff which hasn't been written because the
window is too small, fall throught to TIME_KEEPOPEN */
if (sk->wfront == NULL && sk->send_tmp == NULL)
{
release_sock (sk);
break;
}
/* this basically assumes tcp here. */
/* exponential fall back. */
/* The rtt should quickly get back to normal once
we start sending packets again. */
sk->rtt *= 2;
sk->time_wait.len = sk->rtt;
sk->timeout = TIME_WRITE;
if (sk->prot->write_wakeup != NULL)
sk->prot->write_wakeup(sk);
reset_timer ((struct timer *)&sk->time_wait);
release_sock (sk);
break;
......@@ -298,6 +287,12 @@ net_timer (void)
if (sk->prot->write_wakeup != NULL)
sk->prot->write_wakeup(sk);
sk->retransmits ++;
if (sk->shutdown == SHUTDOWN_MASK)
{
sk->prot->close (sk,1);
sk->state = TCP_CLOSE;
}
if (sk->retransmits > TCP_RETR1)
{
PRINTK ("timer.c TIME_KEEPOPEN time-out 1\n");
......
......@@ -184,6 +184,26 @@ unix_proto_recv(struct socket *sock, void *buff, int len, int nonblock,
return (unix_proto_read (sock, buff, len, nonblock));
}
/*
* Since unix domain sockets use filenames to communicate, two sockets are
* the same if their strings are the same, even if their lengths are different
* (due to possible null terminations). Verified under SunOS 4.1.2
*/
static int
same_path(char *s1, int l1, char *s2, int l2)
{
/*
* Skip chars while they're equal
*/
for (; l1 && l2 && *s1 == *s2; ++s1, ++s2, --l1, --l2);
/*
* Both must be exhausted, or one must be null terminated and the
* other either exhausted or null terminated, for the paths to be
* equivalent
*/
return ((l1 == 0 || *s1 == '\0') && (l2 == 0 || *s2 == '\0'));
}
static struct unix_proto_data *
unix_data_lookup(struct sockaddr_un *sockun, int sockaddr_len)
......@@ -193,8 +213,10 @@ unix_data_lookup(struct sockaddr_un *sockun, int sockaddr_len)
for (upd = unix_datas; upd <= last_unix_data; ++upd) {
if (upd->refcnt && upd->socket &&
upd->socket->state == SS_UNCONNECTED &&
upd->sockaddr_len == sockaddr_len &&
memcmp(&upd->sockaddr_un, sockun, sockaddr_len) == 0)
upd->sockaddr_un.sun_family == sockun->sun_family &&
same_path(sockun->sun_path, sockaddr_len - UN_PATH_OFFSET,
upd->sockaddr_un.sun_path,
upd->sockaddr_len - UN_PATH_OFFSET))
return upd;
}
return NULL;
......
#define UTS_RELEASE "0.99-44"
#define UTS_VERSION "12/11/92"
#define LINUX_COMPILE_TIME "23:05:18"
#define UTS_RELEASE "0.99.pl1-46"
#define UTS_VERSION "12/20/92"
#define LINUX_COMPILE_TIME "14:31:20"
#define LINUX_COMPILE_BY "root"
#define LINUX_COMPILE_HOST "home"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment