mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Add tcsetpgrp(2) and tcgetpgrp(2).
This commit is contained in:
parent
b6349e21cb
commit
938f722dcb
16 changed files with 227 additions and 8 deletions
|
@ -354,6 +354,8 @@ sys/socket/socket.o \
|
|||
sys/socket/socketpair.o \
|
||||
system.o \
|
||||
sys/time/gettimeofday.o \
|
||||
tcgetpgrp.o \
|
||||
tcsetpgrp.o \
|
||||
tfork.o \
|
||||
time/clock_getres.o \
|
||||
time/clock_gettime.o \
|
||||
|
|
|
@ -324,7 +324,26 @@ struct fsm_req_unref
|
|||
ino_t ino;
|
||||
};
|
||||
|
||||
#define FSM_MSG_NUM 40
|
||||
#define FSM_REQ_TCSETPGRP 40
|
||||
struct fsm_req_tcsetpgrp
|
||||
{
|
||||
ino_t ino;
|
||||
pid_t pgid;
|
||||
};
|
||||
|
||||
#define FSM_REQ_TCGETPGRP 41
|
||||
struct fsm_req_tcgetpgrp
|
||||
{
|
||||
ino_t ino;
|
||||
};
|
||||
|
||||
#define FSM_RESP_TCGETPGRP 42
|
||||
struct fsm_resp_tcgetpgrp
|
||||
{
|
||||
pid_t pgid;
|
||||
};
|
||||
|
||||
#define FSM_MSG_NUM 43
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" */
|
||||
|
|
|
@ -284,8 +284,6 @@ void swab(const void* __restrict, void* __restrict, ssize_t);
|
|||
int symlink(const char*, const char*);
|
||||
int symlinkat(const char*, int, const char*);
|
||||
void sync(void);
|
||||
pid_t tcgetpgrp(int);
|
||||
int tcsetpgrp(int, pid_t);
|
||||
int ttyname_r(int, char*, size_t);
|
||||
|
||||
#if __POSIX_OBSOLETE <= 200801
|
||||
|
@ -354,6 +352,8 @@ int setpgid(pid_t, pid_t);
|
|||
int setuid(uid_t);
|
||||
unsigned sleep(unsigned);
|
||||
long sysconf(int);
|
||||
pid_t tcgetpgrp(int);
|
||||
int tcsetpgrp(int, pid_t);
|
||||
int truncate(const char*, off_t);
|
||||
int truncateat(int dirfd, const char*, off_t);
|
||||
char* ttyname(int);
|
||||
|
|
34
libc/tcgetpgrp.cpp
Normal file
34
libc/tcgetpgrp.cpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*******************************************************************************
|
||||
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013.
|
||||
|
||||
This file is part of the Sortix C Library.
|
||||
|
||||
The Sortix C Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
The Sortix C Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the Sortix C Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
tcgetpgrp.cpp
|
||||
Get the foreground process group of a terminal.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
DEFN_SYSCALL1(pid_t, sys_tcgetpgrp, SYSCALL_TCGETPGRP, int);
|
||||
|
||||
extern "C" pid_t tcgetpgrp(int fd)
|
||||
{
|
||||
return sys_tcgetpgrp(fd);
|
||||
}
|
34
libc/tcsetpgrp.cpp
Normal file
34
libc/tcsetpgrp.cpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*******************************************************************************
|
||||
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2013.
|
||||
|
||||
This file is part of the Sortix C Library.
|
||||
|
||||
The Sortix C Library is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
The Sortix C Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the Sortix C Library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
tcsetpgrp.cpp
|
||||
set the foreground process group of a terminal.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
DEFN_SYSCALL2(int, sys_tcsetpgrp, SYSCALL_TCSETPGRP, int, pid_t);
|
||||
|
||||
extern "C" int tcsetpgrp(int fd, pid_t pgid)
|
||||
{
|
||||
return sys_tcsetpgrp(fd, pgid);
|
||||
}
|
|
@ -548,6 +548,16 @@ int Descriptor::tcgetwinsize(ioctx_t* ctx, struct winsize* ws)
|
|||
return vnode->tcgetwinsize(ctx, ws);
|
||||
}
|
||||
|
||||
int Descriptor::tcsetpgrp(ioctx_t* ctx, pid_t pgid)
|
||||
{
|
||||
return vnode->tcsetpgrp(ctx, pgid);
|
||||
}
|
||||
|
||||
pid_t Descriptor::tcgetpgrp(ioctx_t* ctx)
|
||||
{
|
||||
return vnode->tcgetpgrp(ctx);
|
||||
}
|
||||
|
||||
int Descriptor::settermmode(ioctx_t* ctx, unsigned mode)
|
||||
{
|
||||
return vnode->settermmode(ctx, mode);
|
||||
|
|
|
@ -213,6 +213,8 @@ public:
|
|||
const char* filename);
|
||||
virtual ssize_t readlink(ioctx_t* ctx, char* buf, size_t bufsiz);
|
||||
virtual int tcgetwinsize(ioctx_t* ctx, struct winsize* ws);
|
||||
virtual int tcsetpgrp(ioctx_t* ctx, pid_t pgid);
|
||||
virtual pid_t tcgetpgrp(ioctx_t* ctx);
|
||||
virtual int settermmode(ioctx_t* ctx, unsigned mode);
|
||||
virtual int gettermmode(ioctx_t* ctx, unsigned* mode);
|
||||
virtual int poll(ioctx_t* ctx, PollNode* node);
|
||||
|
@ -1115,6 +1117,38 @@ int Unode::tcgetwinsize(ioctx_t* ctx, struct winsize* ws)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int Unode::tcsetpgrp(ioctx_t* /*ctx*/, pid_t pgid)
|
||||
{
|
||||
Channel* channel = server->Connect();
|
||||
if ( !channel )
|
||||
return -1;
|
||||
int ret = -1;
|
||||
struct fsm_req_tcsetpgrp msg;
|
||||
msg.ino = ino;
|
||||
msg.pgid = pgid;
|
||||
if ( SendMessage(channel, FSM_REQ_TCSETPGRP, &msg, sizeof(msg)) &&
|
||||
RecvMessage(channel, FSM_RESP_SUCCESS, NULL, 0) )
|
||||
ret = 0;
|
||||
channel->KernelClose();
|
||||
return ret;
|
||||
}
|
||||
|
||||
pid_t Unode::tcgetpgrp(ioctx_t* /*ctx*/)
|
||||
{
|
||||
Channel* channel = server->Connect();
|
||||
if ( !channel )
|
||||
return -1;
|
||||
pid_t ret = -1;
|
||||
struct fsm_req_tcgetpgrp msg;
|
||||
struct fsm_resp_tcgetpgrp resp;
|
||||
msg.ino = ino;
|
||||
if ( SendMessage(channel, FSM_REQ_TCGETPGRP, &msg, sizeof(msg)) &&
|
||||
RecvMessage(channel, FSM_RESP_TCGETPGRP, &resp, sizeof(resp)) )
|
||||
ret = resp.pgid;
|
||||
channel->KernelClose();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Unode::settermmode(ioctx_t* /*ctx*/, unsigned mode)
|
||||
{
|
||||
Channel* channel = server->Connect();
|
||||
|
|
|
@ -78,6 +78,8 @@ public:
|
|||
int symlink(ioctx_t* ctx, const char* oldname, const char* filename);
|
||||
ssize_t readlink(ioctx_t* ctx, char* buf, size_t bufsiz);
|
||||
int tcgetwinsize(ioctx_t* ctx, struct winsize* ws);
|
||||
int tcsetpgrp(ioctx_t* ctx, pid_t pgid);
|
||||
pid_t tcgetpgrp(ioctx_t* ctx);
|
||||
int settermmode(ioctx_t* ctx, unsigned mode);
|
||||
int gettermmode(ioctx_t* ctx, unsigned* mode);
|
||||
int poll(ioctx_t* ctx, PollNode* node);
|
||||
|
|
|
@ -87,6 +87,8 @@ public:
|
|||
const char* filename) = 0;
|
||||
virtual ssize_t readlink(ioctx_t* ctx, char* buf, size_t bufsiz) = 0;
|
||||
virtual int tcgetwinsize(ioctx_t* ctx, struct winsize* ws) = 0;
|
||||
virtual int tcsetpgrp(ioctx_t* ctx, pid_t pgid) = 0;
|
||||
virtual pid_t tcgetpgrp(ioctx_t* ctx) = 0;
|
||||
virtual int settermmode(ioctx_t* ctx, unsigned mode) = 0;
|
||||
virtual int gettermmode(ioctx_t* ctx, unsigned* mode) = 0;
|
||||
virtual int poll(ioctx_t* ctx, PollNode* node) = 0;
|
||||
|
@ -163,6 +165,8 @@ public:
|
|||
const char* filename);
|
||||
virtual ssize_t readlink(ioctx_t* ctx, char* buf, size_t bufsiz);
|
||||
virtual int tcgetwinsize(ioctx_t* ctx, struct winsize* ws);
|
||||
virtual int tcsetpgrp(ioctx_t* ctx, pid_t pgid);
|
||||
virtual pid_t tcgetpgrp(ioctx_t* ctx);
|
||||
virtual int settermmode(ioctx_t* ctx, unsigned mode);
|
||||
virtual int gettermmode(ioctx_t* ctx, unsigned* mode);
|
||||
virtual int poll(ioctx_t* ctx, PollNode* node);
|
||||
|
|
|
@ -75,6 +75,8 @@ public:
|
|||
ssize_t readlink(ioctx_t* ctx, char* buf, size_t bufsiz);
|
||||
int fsbind(ioctx_t* ctx, Vnode* node, int flags);
|
||||
int tcgetwinsize(ioctx_t* ctx, struct winsize* ws);
|
||||
int tcsetpgrp(ioctx_t* ctx, pid_t pgid);
|
||||
pid_t tcgetpgrp(ioctx_t* ctx);
|
||||
int settermmode(ioctx_t* ctx, unsigned mode);
|
||||
int gettermmode(ioctx_t* ctx, unsigned* mode);
|
||||
int poll(ioctx_t* ctx, PollNode* node);
|
||||
|
|
|
@ -135,6 +135,8 @@
|
|||
#define SYSCALL_MKPARTITION 111
|
||||
#define SYSCALL_GETPGID 112
|
||||
#define SYSCALL_SETPGID 113
|
||||
#define SYSCALL_MAX_NUM 114 /* index of highest constant + 1 */
|
||||
#define SYSCALL_TCGETPGRP 114
|
||||
#define SYSCALL_TCSETPGRP 115
|
||||
#define SYSCALL_MAX_NUM 116 /* index of highest constant + 1 */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -265,6 +265,20 @@ int AbstractInode::tcgetwinsize(ioctx_t* /*ctx*/, struct winsize* /*ws*/)
|
|||
return errno = ENOTTY, -1;
|
||||
}
|
||||
|
||||
int AbstractInode::tcsetpgrp(ioctx_t* /*ctx*/, pid_t /*pgid*/)
|
||||
{
|
||||
if ( inode_type == INODE_TYPE_TTY )
|
||||
return errno = EBADF, -1;
|
||||
return errno = ENOTTY, -1;
|
||||
}
|
||||
|
||||
pid_t AbstractInode::tcgetpgrp(ioctx_t* /*ctx*/)
|
||||
{
|
||||
if ( inode_type == INODE_TYPE_TTY )
|
||||
return errno = EBADF, -1;
|
||||
return errno = ENOTTY, -1;
|
||||
}
|
||||
|
||||
int AbstractInode::settermmode(ioctx_t* /*ctx*/, unsigned /*mode*/)
|
||||
{
|
||||
if ( inode_type == INODE_TYPE_TTY )
|
||||
|
|
|
@ -604,6 +604,24 @@ static int sys_tcgetwinsize(int fd, struct winsize* ws)
|
|||
return desc->tcgetwinsize(&ctx, ws);
|
||||
}
|
||||
|
||||
static int sys_tcsetpgrp(int fd, pid_t pgid)
|
||||
{
|
||||
Ref<Descriptor> desc = CurrentProcess()->GetDescriptor(fd);
|
||||
if ( !desc )
|
||||
return -1;
|
||||
ioctx_t ctx; SetupUserIOCtx(&ctx);
|
||||
return desc->tcsetpgrp(&ctx, pgid);
|
||||
}
|
||||
|
||||
static int sys_tcgetpgrp(int fd)
|
||||
{
|
||||
Ref<Descriptor> desc = CurrentProcess()->GetDescriptor(fd);
|
||||
if ( !desc )
|
||||
return -1;
|
||||
ioctx_t ctx; SetupUserIOCtx(&ctx);
|
||||
return desc->tcgetpgrp(&ctx);
|
||||
}
|
||||
|
||||
static int sys_renameat_inner(int olddirfd, const char* oldpath,
|
||||
int newdirfd, const char* newpath)
|
||||
{
|
||||
|
@ -973,7 +991,9 @@ void Init()
|
|||
Syscall::Register(SYSCALL_SEND, (void*) sys_send);
|
||||
Syscall::Register(SYSCALL_SETTERMMODE, (void*) sys_settermmode);
|
||||
Syscall::Register(SYSCALL_STAT, (void*) sys_stat);
|
||||
Syscall::Register(SYSCALL_TCGETPGRP, (void*) sys_tcgetpgrp);
|
||||
Syscall::Register(SYSCALL_TCGETWINSIZE, (void*) sys_tcgetwinsize);
|
||||
Syscall::Register(SYSCALL_TCSETPGRP, (void*) sys_tcsetpgrp);
|
||||
Syscall::Register(SYSCALL_TRUNCATEAT, (void*) sys_truncateat);
|
||||
Syscall::Register(SYSCALL_TRUNCATE, (void*) sys_truncate);
|
||||
Syscall::Register(SYSCALL_UNLINKAT, (void*) sys_unlinkat);
|
||||
|
|
|
@ -84,6 +84,7 @@ LogTerminal::LogTerminal(dev_t dev, mode_t mode, uid_t owner, gid_t group,
|
|||
this->datacond = KTHREAD_COND_INITIALIZER;
|
||||
this->numwaiting = 0;
|
||||
this->numeofs = 0;
|
||||
this->foreground_pgid = 0;
|
||||
keyboard->SetOwner(this, NULL);
|
||||
}
|
||||
|
||||
|
@ -128,6 +129,27 @@ int LogTerminal::tcgetwinsize(ioctx_t* ctx, struct winsize* ws)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int LogTerminal::tcsetpgrp(ioctx_t* /*ctx*/, pid_t pgid)
|
||||
{
|
||||
ScopedLock lock(&termlock);
|
||||
Process* process = Process::Get(pgid);
|
||||
if ( !pgid || !process )
|
||||
return errno = ESRCH, -1;
|
||||
kthread_mutex_lock(&process->groupchildlock);
|
||||
bool is_process_group = process->group == process;
|
||||
kthread_mutex_unlock(&process->groupchildlock);
|
||||
if ( !is_process_group )
|
||||
return errno = EINVAL, -1;
|
||||
foreground_pgid = pgid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pid_t LogTerminal::tcgetpgrp(ioctx_t* /*ctx*/)
|
||||
{
|
||||
ScopedLock lock(&termlock);
|
||||
return foreground_pgid = 0;
|
||||
}
|
||||
|
||||
int LogTerminal::sync(ioctx_t* /*ctx*/)
|
||||
{
|
||||
return Log::Sync() ? 0 : -1;
|
||||
|
@ -152,10 +174,17 @@ void LogTerminal::ProcessKeystroke(int kbkey)
|
|||
{
|
||||
while ( linebuffer.CanBackspace() )
|
||||
linebuffer.Backspace();
|
||||
if ( foreground_pgid )
|
||||
{
|
||||
if ( Process* process = Process::Get(foreground_pgid) )
|
||||
process->DeliverGroupSignal(SIGINT);
|
||||
}
|
||||
else // TODO: Backwards compatibility, delete this.
|
||||
{
|
||||
pid_t pid = Process::HackGetForegroundProcess();
|
||||
Process* process = Process::Get(pid);
|
||||
if ( process )
|
||||
if ( Process* process = Process::Get(pid) )
|
||||
process->DeliverSignal(SIGINT);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ( termmode & TERMMODE_SIGNAL && control && kbkey == KBKEY_D )
|
||||
|
|
|
@ -45,6 +45,8 @@ public:
|
|||
virtual ssize_t read(ioctx_t* ctx, uint8_t* buf, size_t count);
|
||||
virtual ssize_t write(ioctx_t* ctx, const uint8_t* buf, size_t count);
|
||||
virtual int tcgetwinsize(ioctx_t* ctx, struct winsize* ws);
|
||||
virtual int tcsetpgrp(ioctx_t* ctx, pid_t pgid);
|
||||
virtual pid_t tcgetpgrp(ioctx_t* ctx);
|
||||
virtual int settermmode(ioctx_t* ctx, unsigned termmode);
|
||||
virtual int gettermmode(ioctx_t* ctx, unsigned* termmode);
|
||||
virtual int poll(ioctx_t* ctx, PollNode* node);
|
||||
|
@ -69,6 +71,7 @@ private:
|
|||
LineBuffer linebuffer;
|
||||
size_t partiallywritten;
|
||||
unsigned termmode;
|
||||
pid_t foreground_pgid;
|
||||
bool control;
|
||||
|
||||
};
|
||||
|
|
|
@ -224,6 +224,16 @@ int Vnode::tcgetwinsize(ioctx_t* ctx, struct winsize* ws)
|
|||
return inode->tcgetwinsize(ctx, ws);
|
||||
}
|
||||
|
||||
int Vnode::tcsetpgrp(ioctx_t* ctx, pid_t pgid)
|
||||
{
|
||||
return inode->tcsetpgrp(ctx, pgid);
|
||||
}
|
||||
|
||||
pid_t Vnode::tcgetpgrp(ioctx_t* ctx)
|
||||
{
|
||||
return inode->tcgetpgrp(ctx);
|
||||
}
|
||||
|
||||
int Vnode::settermmode(ioctx_t* ctx, unsigned mode)
|
||||
{
|
||||
return inode->settermmode(ctx, mode);
|
||||
|
|
Loading…
Add table
Reference in a new issue