From: Alan Cox Date: Sat, 9 Jan 2016 15:27:13 +0000 (+0000) Subject: level2: plumb together all the level2 work and make it actually build X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=92fe7ff95e50ddaf28f6eeb2f8ff00ca8041ecb4;p=FUZIX.git level2: plumb together all the level2 work and make it actually build --- diff --git a/Kernel/include/kdata.h b/Kernel/include/kdata.h index e4fc7c4f..31a93bf5 100644 --- a/Kernel/include/kdata.h +++ b/Kernel/include/kdata.h @@ -83,8 +83,15 @@ struct runload { extern struct runload loadavg[]; // the system call dispatch table +#ifdef CONFIG_LEVEL_2 +#define FUZIX_SYSCALL_COUNT 80 +#else #define FUZIX_SYSCALL_COUNT 66 +#endif + typedef arg_t (*syscall_t)(void); extern const syscall_t syscall_dispatch[FUZIX_SYSCALL_COUNT]; +extern arg_t _nosys(void); + #endif diff --git a/Kernel/include/kernel.h b/Kernel/include/kernel.h index 7f51c894..9a95cbe2 100644 --- a/Kernel/include/kernel.h +++ b/Kernel/include/kernel.h @@ -571,6 +571,7 @@ struct s_argblk { #define EALREADY 39 /* Operation already in progress */ #define EADDRINUSE 40 /* Address already in use */ #define EADDRNOTAVAIL 41 /* Address not available */ +#define ENOSYS 42 /* No such system call */ /* * ioctls for kernel internal operations start at 0x8000 and cannot be issued @@ -805,15 +806,15 @@ extern void exec_or_die(void); extern void seladdwait(struct selmap *s); extern void selrmwait(struct selmap *s); extern void selwake(struct selmap *s); -#ifdef CONFIG_SELECT -extern int selwait_inode(inoptr i, uint8_t smask, uint8_t setit); +#ifdef CONFIG_LEVEL_2 +extern void selwait_inode(inoptr i, uint8_t smask, uint8_t setit); extern void selwake_inode(inoptr i, uint16_t mask); extern void selwake_pipe(inoptr i, uint16_t mask); extern int _select(void); #else #define selwait_inode(i,smask,setit) do {} while(0) -#define selwake_inode(i,smask,setit) do {} while(0) -#define selwake_pipe(i,smask,setit) do {} while(0) +#define selwake_inode(i,smask) do {} while(0) +#define selwake_pipe(i,smask) do {} while(0) #endif /* swap.c */ diff --git a/Kernel/include/level2.h b/Kernel/include/level2.h index e845e898..3c4ac3f5 100644 --- a/Kernel/include/level2.h +++ b/Kernel/include/level2.h @@ -1,3 +1,6 @@ +#ifndef _LEVEL_2_H +#define _LEVEL_2_H + /* Resource limits only exist on LEVEL_2 systems */ #define NRLIMIT 9 @@ -12,7 +15,7 @@ #define RLIMIT_RSS 7 #define RLIMIT_STACK 8 -typedef uint32_t rlimit_t +typedef uint32_t rlim_t; #define RLIM_INFINITY 0xFFFFFFFFUL @@ -21,6 +24,7 @@ struct rlimit { rlim_t rlim_max; }; +struct tty; extern int in_group(uint16_t gid); extern void jobcontrol_in(struct tty *tty); @@ -30,7 +34,7 @@ extern int tcsetpgrp(struct tty *tty, char *data); /* Platform must implement according to its PATH_MAX and allocators. If you are using a 512 byte path limit then calling tmpbuf() and brelse() is sufficient */ -extern char *pathhbuf(void); +extern char *pathbuf(void); extern void pathfree(char *p); /* The first half of this always gets used with a constant so using a macro @@ -44,9 +48,10 @@ extern void pathfree(char *p); FIXME: check for any setuid funnies */ #define can_signal(p, sig) \ - ((sig == SIGCONT && udata.u_ptab->p_session == (p)->session) \ + ((sig == SIGCONT && udata.u_ptab->p_session == (p)->p_session) \ || udata.u_ptab->p_uid == (p)->p_uid || super()) +extern arg_t _select(void); extern arg_t _setgroups(void); extern arg_t _getgroups(void); extern arg_t _getrlimit(void); @@ -54,3 +59,5 @@ extern arg_t _setrlimit(void); extern arg_t _setpgid(void); extern arg_t _setsid(void); extern arg_t _getsid(void); + +#endif diff --git a/Kernel/include/syscall_name.h b/Kernel/include/syscall_name.h index b2090587..f30a5192 100644 --- a/Kernel/include/syscall_name.h +++ b/Kernel/include/syscall_name.h @@ -69,6 +69,20 @@ char *syscall_name[NR_SYSCALL] = { "acct", "memalloc", "memfree", + "_nosys66", + "_nosys67", + "_nosys68", + "_nosys69", + "_nosys70", + "_nosys71", + "_select", + "setgroups", + "getgroups", + "getrlimit", + "setrlimit", + "setpgid", + "setsid", + "getsid", }; int syscall_args[NR_SYSCALL] = { @@ -138,4 +152,18 @@ int syscall_args[NR_SYSCALL] = { 1, //act 1, //memalloc 1, //memfree + 0, //nosys 66 + 0, //nosys 67 + 0, //nosys 68 + 0, //nosys 69 + 0, //nosys 70 + 0, //nosys 71 + 2, //_select + 2, //setgroups + 2, //getgroups + 2, //getrlimit + 2, //setrlimit + 2, //setpgid + 1, //setsid + 1, //getsid }; diff --git a/Kernel/kdata.c b/Kernel/kdata.c index 98ec535e..9cfdb304 100644 --- a/Kernel/kdata.c +++ b/Kernel/kdata.c @@ -100,4 +100,21 @@ const syscall_t syscall_dispatch[FUZIX_SYSCALL_COUNT] = { _acct, /* FUZIX system call 63 */ _memalloc, /* FUZIX system call 64 */ _memfree, /* FUZIX system call 65 */ + /* Level 2 calls */ +#if defined(CONFIG_LEVEL_2) + _nosys, /* 66-71 reserved */ + _nosys, + _nosys, + _nosys, + _nosys, + _nosys, + _select, /* FUZIX system call 72 */ + _setgroups, /* FUZIX system call 73 */ + _getgroups, /* FUZIX system call 74 */ + _getrlimit, /* FUZIX system call 75 */ + _setrlimit, /* FUZIX system call 76 */ + _setpgid, /* FUZIX system call 77 */ + _setsid, /* FUZIX system call 78 */ + _getsid, /* FUZIX system call 79 */ +#endif }; diff --git a/Kernel/level2.c b/Kernel/level2.c index 1c8a1a31..41d8d90b 100644 --- a/Kernel/level2.c +++ b/Kernel/level2.c @@ -1,10 +1,13 @@ #include #include #include +#include + +#ifdef CONFIG_LEVEL_2 int in_group(uint16_t gid) { - uint16_t *g = udata.u_group; + uint16_t *g = udata.u_groups; uint16_t *p = g + udata.u_ngroup; while(g < p) if (*g++ == gid) @@ -14,24 +17,24 @@ int in_group(uint16_t gid) void jobcontrol_in(struct tty *t) { - if (udata.u_proc->p_pgrp == t->pgrp) + if (udata.u_ptab->p_pgrp == t->pgrp) return; /* We probably want to special case a helper here because we need to handle the funnier side effects ? */ - ssig(udata.u_proc, SIGTTIN); + ssig(udata.u_ptab, SIGTTIN); /* So we halt */ - pause(0); + psleep(0); } void jobcontrol_out(struct tty *t) { - if (udata.u_proc->p_pgrp == t->pgrp) + if (udata.u_ptab->p_pgrp == t->pgrp) return; - if (!(t->termios.t_lflag & TOSTOP)) + if (!(t->termios.c_lflag & TOSTOP)) return; - ssig(udata.u_proc, SIGTTOU); + ssig(udata.u_ptab, SIGTTOU); /* So we halt */ - pause(0); + psleep(0); } int tcsetpgrp(struct tty *t, char *data) /* data is user pointer */ @@ -44,7 +47,7 @@ int tcsetpgrp(struct tty *t, char *data) /* data is user pointer */ /* Controlling tty check is done by caller */ /* No change -> ok */ - if (grp == tty->pgrp) + if (grp == t->pgrp) return 0; for (p = ptab; p < ptab_end; ++p) { @@ -56,10 +59,12 @@ int tcsetpgrp(struct tty *t, char *data) /* data is user pointer */ return -1; } /* So it's a valid group and in our session */ - tty->pgrp = grp; + t->pgrp = grp; return 0; } } udata.u_error = EINVAL; return -1; } + +#endif diff --git a/Kernel/process.c b/Kernel/process.c index da047d46..98ec0cc5 100644 --- a/Kernel/process.c +++ b/Kernel/process.c @@ -394,7 +394,7 @@ void unix_syscall(void) * Assembly Language Function handler in lowlevel.s */ if (udata.u_callno >= FUZIX_SYSCALL_COUNT) { - udata.u_error = EINVAL; + udata.u_error = ENOSYS; } else { #ifdef DEBUG kprintf("\t\tpid %d: syscall %d\t%s(%x, %x, %x)\n", diff --git a/Kernel/select.c b/Kernel/select.c index 5353c222..30fafcc5 100644 --- a/Kernel/select.c +++ b/Kernel/select.c @@ -3,12 +3,16 @@ #include #include +#ifdef CONFIG_LEVEL_2 + /* * Logic for select * * Each selectable object needs 3 words of memory (assuming max * 16 processes). If we go over that then this logic is ok but - * we would need to trim pipe buffers slightly. + * we would need to trim pipe buffers slightly. Alternatively we + * could use separate select objects at that point since presumably + * we have enough memory. * * While they are 16bits we can instead hide them in the inode copy * in memory for free. @@ -21,191 +25,209 @@ * Socket: TODO */ +uint16_t pipesel = 0; + void seladdwait(struct selmap *s) { - uint16_t p = udata.u_ptab - ptab; - s->map[p>>3] |= (1 << (p & 7)); + uint16_t p = udata.u_ptab - ptab; + s->map[p >> 3] |= (1 << (p & 7)); } void selrmwait(struct selmap *s) { - uint16_t p = udata.u_ptab - ptab; - s->map[p>>3] &= ~(1 << (p & 7)); + uint16_t p = udata.u_ptab - ptab; + s->map[p >> 3] &= ~(1 << (p & 7)); } void selwake(struct selmap *s) { - p = ptab; - for (i = 0; i < maxproc; i++) { - if (s->map[i>>3] & (1 << (i & 7))) - pwake(p); - p++; - } + ptptr p = ptab; + uint16_t i; + + for (i = 0; i < maxproc; i++) { + if (s->map[i >> 3] & (1 << (i & 7))) + pwake(p); + p++; + } } /* Set our select bits on the inode */ -int selwait_inode(inoptr i, uint8_t smask, uint8_t setit) { - struct selmap *s = (struct selmap *)(&i->c_node.i_addr[17]); - uint8_t bit = udata.u_ptab - ptab; - uint8_t mask = 1 << (bit & 7); - uint8_t bset = bit & setit; - bit >>= 3; - - if (smask & SELECT_IN) { - s->map[mask] &= ~bit; - s->map[mask] |= bset; - } - s++; - if (smask & SELECT_OUT) { - s->map[mask] &= ~bit; - s->map[mask] |= bset; - } - s++; - if (smask & SELECT_EX) { - s->map[mask] &= ~bit; - s->map[mask] |= bset; - } +void selwait_inode(inoptr i, uint8_t smask, uint8_t setit) +{ + struct selmap *s = (struct selmap *) (&i->c_node.i_addr[17]); + uint8_t bit = udata.u_ptab - ptab; + uint8_t mask = 1 << (bit & 7); + uint8_t bset = bit & setit; + bit >>= 3; + + if (smask & SELECT_IN) { + s->map[mask] &= ~bit; + s->map[mask] |= bset; + } + s++; + if (smask & SELECT_OUT) { + s->map[mask] &= ~bit; + s->map[mask] |= bset; + } + s++; + if (smask & SELECT_EX) { + s->map[mask] &= ~bit; + s->map[mask] |= bset; + } } /* Wake an inode for select */ -void selwake_inode(inoptr i, uint16_t mask) { - struct selmap *s = (struct selmap *)(&i->c_node.i_addr[17]); - if (mask & SELECT_IN) - selwake(s); - s++; - if (mask & SELECT_OUT) - selwake(s); - s++; - if (mask & SELECT_EX) - selwake(s); +void selwake_inode(inoptr i, uint16_t mask) +{ + struct selmap *s = (struct selmap *) (&i->c_node.i_addr[17]); + if (mask & SELECT_IN) + selwake(s); + s++; + if (mask & SELECT_OUT) + selwake(s); + s++; + if (mask & SELECT_EX) + selwake(s); } static int pipesel_begin(inoptr i, uint8_t bits) { - uint16_t mask = 0; - pipesel++; - /* Data or EOF */ - if (i->c_node.i_size || !i->c_refs) - mask |= SELECT_IN; - /* Enough room to be worth waking - keep wakeup rate down */ - if (i->c_node.i_size < 8 * BLKSIZE) - mask |= SELECT_OUT; - selwait_inode(i, bits, 1); - return mask & bits; + uint16_t mask = 0; + pipesel++; + /* Data or EOF */ + if (i->c_node.i_size || !i->c_refs) + mask |= SELECT_IN; + /* Enough room to be worth waking - keep wakeup rate down */ + if (i->c_node.i_size < 8 * BLKSIZE) + mask |= SELECT_OUT; + selwait_inode(i, bits, 1); + return mask & bits; } -static int pipesel_end(inoptr i) +static void pipesel_end(inoptr i) { - pipesel--; - /* Clear out wait masks */ - selwait(i, SELECT_IN|SELECT_OUT|SELECT_EX, 0); + pipesel--; + /* Clear out wait masks */ + selwait_inode(i, SELECT_IN | SELECT_OUT | SELECT_EX, 0); } void selwake_pipe(inoptr i, uint16_t mask) { - if (pipesel) - selwake_inode(i); + if (pipesel) + selwake_inode(i, mask); } + +/******************************************* + _select (nfd, base) Function 72 + int nfd; + uint16_t *base; + *******************************************/ #define nfd (uint16_t)udata.u_argn -#define base (uint16_t)udata.u_argn1 +#define base (uint16_t *)udata.u_argn1 int _select(void) { - struct inode *iptr; - uint16_t sumo; - uint8_t n; - uint16_t inr = 0, outr = 0, exr = 0; - /* Second 16bits of each spare for expansion */ - uint16_t in = ugetw(base); - uint16_t out = ugetw(base+4); - uint16_t ex = ugetw(base+8); - - uint16_t sum = in | out | ex; - - /* Timeout in 1/10th of a second (BSD api mangling done by libc) */ - udata.p_tab->p_timeout = ugetw(base + 12); - - do { - m = 1; - for (i = 0; i < nfd; i++) { - if (sum & m) { - if (in & m) - n = SELECT_IN; - else - n = 0; - if (out & m) - n |= SELECT_OUT; - if (ex & m) - n |= SELECT_EX; - ino = getinode(i); - if (ino == NULLINODE) - return -1; - switch(getmode(ino)) { - /* Device types that automatically report some ready states */ - case F_BDEV: - case F_REG: - outr |= m; - case F_DIR: - inr |= m; - break; - case F_PIPE: - n = pipesel_begin(ino, n); - goto setbits; - case F_CDEV: - /* If unsupported we report the device as read/write ready */ - if (d_ioctl(ino->c_node.i_addr[0], SELECT_BEGIN, &n) == -1) { - udata.u_error = 0; - n = SELECT_IN|SELECT_OUT; - } -setbits: - /* Set the outputs */ - if (n & SELECT_IN) - inr |= m; - if (n & SELECT_OUT) - outr |= m; - if (n & SELECT_EX) - exr |= m; - break; - } - m << = 1; /* Next fd mask */ - } - inr &= in; /* Don't reply with bits not being selected */ - outr &= out; - exr &= ex; - sumo = inr | outr | exr; /* Are we there yet ? */ - if (!sumo && psleep_flags(&udata.p_tab->p_timeout, 0) == -1) - break; - } - while (!sumo && udata.p_tab->p_timeout != 1); - - udata.p_tab->p_timeout = 0; - - /* Return the values to user space */ - uputw(inr, base); - uputw(outr, base + 4); - uputw(exr, base + 8) - - /* Tell the device less people care, we may want to remove all this - and just select check. The 0 check we could do instead is cheap */ - m = 1; - for (i = 0; i < nfd; i++) { - if (sum & m) { - ino = getinode(i); - switch(getmode(ino)) - { - case F_CDEV: - d_ioctl(ino->c_node.i_addr[0], SELECT_END, NULL); - break; - case F_PIPE: - pipesel_end(ino); - } - } - m <<= 1; - } - return 0; /* the scan and return of highest fd is done by - user space */ + inoptr ino; + uint16_t sumo; + uint8_t i, m, n; + uint16_t inr = 0, outr = 0, exr = 0; + /* Second 16bits of each spare for expansion */ + uint16_t in = ugetw(base); + uint16_t out = ugetw(base + 4); + uint16_t ex = ugetw(base + 8); + + uint16_t sum = in | out | ex; + + /* Timeout in 1/10th of a second (BSD api mangling done by libc) */ + udata.u_ptab->p_timeout = ugetw(base + 12); + + do { + m = 1; + for (i = 0; i < nfd; i++) { + if (sum & m) { + if (in & m) + n = SELECT_IN; + else + n = 0; + if (out & m) + n |= SELECT_OUT; + if (ex & m) + n |= SELECT_EX; + ino = getinode(i); + if (ino == NULLINODE) + return -1; + switch (getmode(ino)) { + /* Device types that automatically report some ready states */ + case F_BDEV: + case F_REG: + outr |= m; + case F_DIR: + inr |= m; + break; + case F_PIPE: + n = pipesel_begin(ino, n); + goto setbits; + case F_CDEV: + /* If unsupported we report the device as read/write ready */ + if (d_ioctl + (ino->c_node.i_addr[0], + SELECT_BEGIN, &n) == -1) { + udata.u_error = 0; + n = SELECT_IN | SELECT_OUT; + } + setbits: + /* Set the outputs */ + if (n & SELECT_IN) + inr |= m; + if (n & SELECT_OUT) + outr |= m; + if (n & SELECT_EX) + exr |= m; + break; + } + } + m <<= 1; /* Next fd mask */ + } + inr &= in; /* Don't reply with bits not being selected */ + outr &= out; + exr &= ex; + sumo = inr | outr | exr; /* Are we there yet ? */ + if (!sumo + && psleep_flags(&udata.u_ptab->p_timeout, 0) == -1) + break; + } + while (!sumo && udata.u_ptab->p_timeout != 1); + + udata.u_ptab->p_timeout = 0; + + /* Return the values to user space */ + uputw(inr, base); + uputw(outr, base + 4); + uputw(exr, base + 8); + + /* Tell the device less people care, we may want to remove all this + and just select check. The 0 check we could do instead is cheap */ + m = 1; + for (i = 0; i < nfd; i++) { + if (sum & m) { + ino = getinode(i); + switch (getmode(ino)) { + case F_CDEV: + d_ioctl(ino->c_node.i_addr[0], SELECT_END, + NULL); + break; + case F_PIPE: + pipesel_end(ino); + } + } + m <<= 1; + } + return 0; /* the scan and return of highest fd is done by + user space */ } #undef nfd #undef base + +#endif diff --git a/Kernel/syscall_fs.c b/Kernel/syscall_fs.c index d77c10c7..2c8056a7 100644 --- a/Kernel/syscall_fs.c +++ b/Kernel/syscall_fs.c @@ -473,3 +473,12 @@ arg_t _write(void) #undef buf #undef nbytes +/******************************************* +nosys () Function: various +********************************************/ + +arg_t _nosys(void) +{ + udata.u_error = ENOSYS; + return -1; +} diff --git a/Kernel/syscall_level2.c b/Kernel/syscall_level2.c index 43a27291..58d5edfe 100644 --- a/Kernel/syscall_level2.c +++ b/Kernel/syscall_level2.c @@ -3,8 +3,10 @@ #include #include +#ifdef CONFIG_LEVEL_2 + /******************************************* - setgroups (ngroup, groups) Function ?? + setgroups (ngroup, groups) Function 73 int ngroup; const uint16_t *groups; *******************************************/ @@ -17,7 +19,7 @@ arg_t _setgroups(void) return -1; if (ngroup < 0 || ngroup > NGROUP) { udata.u_error = EINVAL; - return -1 + return -1; } if (ngroup && uget(groups, udata.u_groups, ngroup * sizeof(uint16_t))) return -1; @@ -29,7 +31,7 @@ arg_t _setgroups(void) #undef groups /******************************************* - getgroups (ngroup, groups) Function ?? + getgroups (ngroup, groups) Function 74 int ngroup; uint16_t *groups; *******************************************/ @@ -42,7 +44,7 @@ arg_t _getgroups(void) return udata.u_ngroup; if (ngroup < udata.u_ngroup) { udata.u_error = EINVAL; - return; + return -1; } if (uput(groups, udata.u_groups, ngroup * sizeof(uint16_t)) < 0) return -1; @@ -53,7 +55,7 @@ arg_t _getgroups(void) #undef groups /******************************************* - getrlimit (res, rlimit) Function ?? + getrlimit (res, rlimit) Function 75 int res; struct rlimit *rlim; *******************************************/ @@ -74,7 +76,7 @@ arg_t _getrlimit(void) #undef rlim /******************************************* - setrlimit (res, rlimit) Function ?? + setrlimit (res, rlimit) Function 76 int res; const struct rlimit *rlim; *******************************************/ @@ -93,7 +95,7 @@ arg_t _setrlimit(void) if (uget(rlim, &r, sizeof(struct rlimit))) return -1; - o = uata.u_rlimit + res; + o = udata.u_rlimit + res; if (r.rlim_cur > r.rlim_max) goto bad; @@ -112,7 +114,7 @@ bad: #undef rlim /******************************************* - setpgid (pid, pgid) Function ?? + setpgid (pid, pgid) Function 77 uint16_t npid; uint16_t npgid; *******************************************/ @@ -122,8 +124,9 @@ bad: arg_t _setpgid(void) { - ptptr p, t; + ptptr p, t = NULL; uint16_t ses = udata.u_ptab->p_session; + uint16_t n = npgid; /* pid 0 means "self" */ if (npid == 0) @@ -142,15 +145,15 @@ arg_t _setpgid(void) if (t->p_session != udata.u_ptab->p_session) goto invalid; - if (npgid == 0) - npgid = t->p_pid; + if (n == 0) + n = t->p_pid; /* Check if the group is in use with a different session */ for (p = ptab; p < ptab_end; ++p) - if (p->p_pgrp == npgid && p->p_session != ses) + if (p->p_pgrp == n && p->p_session != ses) goto invalid; - t->p_pgrp = npgid; + t->p_pgrp = n; return 0; invalid: @@ -162,7 +165,7 @@ invalid: #undef npgid /******************************************* - setsid (void) Function ?? + setsid (void) Function 78 *******************************************/ arg_t _setsid(void) @@ -171,7 +174,7 @@ arg_t _setsid(void) uint16_t pid = udata.u_ptab->p_pid; for (p = ptab; p < ptab_end; ++p) { - if (p->p_pgid == pid || p->p_session == pid) { + if (p->p_pgrp == pid || p->p_session == pid) { udata.u_error = EPERM; return -1; } @@ -184,10 +187,12 @@ arg_t _setsid(void) } /******************************************* - getsid (pid) Function ?? + getsid (pid) Function 79 uint16_t pid; *******************************************/ +#define pid (uint16_t)udata.u_argn + arg_t _getsid(void) { ptptr p; @@ -198,4 +203,6 @@ arg_t _getsid(void) udata.u_error = ESRCH; return -1; } +#undef pid +#endif diff --git a/Kernel/syscall_net.c b/Kernel/syscall_net.c index 61f70d16..dc6079d4 100644 --- a/Kernel/syscall_net.c +++ b/Kernel/syscall_net.c @@ -2,6 +2,8 @@ #include #include +#ifndef CONFIG_NET + #define NSOCKET 8 @@ -504,3 +506,5 @@ arg_t _recvfrom(void) #undef nbytes #undef uaddr #undef flags + +#endif diff --git a/Kernel/syscall_proc.c b/Kernel/syscall_proc.c index 88c93f21..0acfa56f 100644 --- a/Kernel/syscall_proc.c +++ b/Kernel/syscall_proc.c @@ -573,7 +573,7 @@ arg_t _setpgrp(void) /* For full session management it's a shade more complicated and we have the routine to do the full job */ - return setsid(0,0); + return _setsid(); #else udata.u_ptab->p_pgrp = udata.u_ptab->p_pid; udata.u_ptab->p_tty = 0; diff --git a/Kernel/tty.c b/Kernel/tty.c index 3f5d7621..6d183f97 100644 --- a/Kernel/tty.c +++ b/Kernel/tty.c @@ -265,7 +265,7 @@ int tty_ioctl(uint8_t minor, uarg_t request, char *data) udata.u_error = ENOTTY; return -1; } - return tcsetpgrp(minor, t, data); + return tcsetpgrp(t, data); #endif default: udata.u_error = ENOTTY;