Skip to content

Commit

Permalink
Implement TIOCGPGRP
Browse files Browse the repository at this point in the history
  • Loading branch information
tbodt committed Sep 1, 2017
1 parent f8f43d4 commit 3c4b180
Show file tree
Hide file tree
Showing 13 changed files with 120 additions and 66 deletions.
24 changes: 0 additions & 24 deletions fs/tty-real.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,32 +62,8 @@ void real_tty_close(struct tty *tty) {
pthread_cancel(tty->thread);
}

#define TCGETS_ 0x5401
#define TCSETS_ 0x5402
#define TIOCGWINSZ_ 0x5413

static ssize_t real_tty_ioctl_size(struct tty *tty, int cmd) {
switch (cmd) {
case TIOCGWINSZ_: return sizeof(struct winsize_);
case TCGETS_: return sizeof(struct termios_);
case TCSETS_: return sizeof(struct termios_);
}
return -1;
}

static int real_tty_ioctl(struct tty *tty, int cmd, void *arg) {
switch (cmd) {
case TIOCGWINSZ_: *(struct winsize_ *) arg = tty->winsize; break;
case TCGETS_: *(struct termios_ *) arg = tty->termios; break;
case TCSETS_: tty->termios = *(struct termios_ *) arg; break;
}
return 0;
}

struct tty_driver real_tty_driver = {
.open = real_tty_open,
.write = real_tty_write,
.ioctl_size = real_tty_ioctl_size,
.ioctl = real_tty_ioctl,
.close = real_tty_close,
};
44 changes: 42 additions & 2 deletions fs/tty.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "debug.h"
#include <string.h>
#include "sys/calls.h"
#include "sys/group.h"
#include "fs/tty.h"

// TODO remove magic number
Expand Down Expand Up @@ -38,6 +39,9 @@ static int tty_get(int type, int num, struct tty **tty_out) {
return err;
}

tty->session = 0;
tty->fg_group = 0;

ttys[type][num] = tty;
pthread_mutex_unlock(&ttys_lock);
}
Expand Down Expand Up @@ -73,17 +77,33 @@ static int tty_open(int major, int minor, int type, struct fd *fd) {
type = TTY_PSEUDO;
else
assert(false);

struct tty *tty;
int err = tty_get(type, minor, &tty);
if (err < 0)
return err;
fd->tty = tty;

lock(&tty->pl);
lock(fd);
list_add(&tty->pl.fds, &fd->pollable_other_fds);
fd->pollable = &tty->pl;
unlock(fd);
unlock(&tty->pl);

lock(current);
if (current->sid == current->pid) {
struct session *session = pid_get_session(current->sid);
lock(session);
if (session->tty == NULL) {
session->tty = tty;
tty->session = current->sid;
tty->fg_group = current->pgid;
}
unlock(session);
}
unlock(current);

return 0;
}

Expand Down Expand Up @@ -229,11 +249,31 @@ static int tty_poll(struct fd *fd) {
return types;
}

#define TCGETS_ 0x5401
#define TCSETS_ 0x5402
#define TIOCGWINSZ_ 0x5413
#define TIOCGPRGP_ 0x540f
#define TIOCSPGRP_ 0x5410

static ssize_t tty_ioctl_size(struct fd *fd, int cmd) {
return fd->tty->driver->ioctl_size(fd->tty, cmd);
switch (cmd) {
case TIOCGWINSZ_: return sizeof(struct winsize_);
case TCGETS_: return sizeof(struct termios_);
case TCSETS_: return sizeof(struct termios_);
case TIOCGPRGP_: return sizeof(dword_t);
}
return -1;
}

static int tty_ioctl(struct fd *fd, int cmd, void *arg) {
return fd->tty->driver->ioctl(fd->tty, cmd, arg);
switch (cmd) {
case TIOCGWINSZ_: *(struct winsize_ *) arg = fd->tty->winsize; break;
case TCGETS_: *(struct termios_ *) arg = fd->tty->termios; break;
case TCSETS_: fd->tty->termios = *(struct termios_ *) arg; break;
case TIOCGPRGP_: *(dword_t *) arg = fd->tty->fg_group;
TRACELN("fg_group %d", fd->tty->fg_group); break;
}
return 0;
}

struct dev_ops tty_dev = {
Expand Down
5 changes: 3 additions & 2 deletions fs/tty.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ struct termios_ {
struct tty_driver {
int (*open)(struct tty *tty);
ssize_t (*write)(struct tty *tty, const void *buf, size_t len);
ssize_t (*ioctl_size)(struct tty *tty, int cmd);
int (*ioctl)(struct tty *tty, int cmd, void *arg);
void (*close)(struct tty *tty);
};

Expand All @@ -84,6 +82,9 @@ struct tty {
int type;
int num;

dword_t session;
dword_t fg_group;

pthread_mutex_t lock;

// for real tty driver
Expand Down
5 changes: 2 additions & 3 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ sys_src = [
'sys/user.c',
'sys/vdso.c',
'sys/process.c',
'sys/group.c',

'sys/fork.c',
'sys/exec.c',
Expand All @@ -50,9 +51,7 @@ sys_src = [
'fs/tty.c',
'fs/tty-real.c',

'sys/poll.c',

'util/buffer.c'
'sys/poll.c'
]
emu_src = [
'emu/memory.c',
Expand Down
2 changes: 1 addition & 1 deletion misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdnoreturn.h>
#include <sys/types.h>
#include <pthread.h>

Expand All @@ -28,7 +29,6 @@
#define postulate assert
#endif
#define unlikely(x) __builtin_expect((x), 0)
#define noreturn __attribute__((noreturn))
#define must_check __attribute__((warn_unused_result))

#if defined(__i386__) || defined(__x86_64__)
Expand Down
4 changes: 4 additions & 0 deletions sys/calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ syscall_t syscall_table[] = {
[54] = (syscall_t) sys_ioctl,
[63] = (syscall_t) sys_dup2,
[64] = (syscall_t) sys_getppid,
[65] = (syscall_t) sys_getpgrp,
[85] = (syscall_t) sys_readlink,
[90] = (syscall_t) sys_mmap,
[91] = (syscall_t) sys_munmap,
Expand All @@ -43,6 +44,7 @@ syscall_t syscall_table[] = {
[120] = (syscall_t) sys_clone,
[122] = (syscall_t) _sys_uname,
[125] = (syscall_t) sys_mprotect,
[132] = (syscall_t) sys_getpgid,
[140] = (syscall_t) sys__llseek,
[145] = (syscall_t) sys_readv,
[146] = (syscall_t) sys_writev,
Expand Down Expand Up @@ -78,6 +80,7 @@ void handle_interrupt(struct cpu_state *cpu, int interrupt) {
if (syscall_num >= NUM_SYSCALLS || syscall_table[syscall_num] == NULL) {
// TODO SIGSYS
println("missing syscall %d", syscall_num);
debugger;
send_signal(current, SIGSYS_);
} else {
TRACE("syscall %d ", syscall_num);
Expand All @@ -97,4 +100,5 @@ void handle_interrupt(struct cpu_state *cpu, int interrupt) {
println("exiting");
sys_exit(interrupt);
}
receive_signals();
}
3 changes: 3 additions & 0 deletions sys/calls.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ dword_t sys_sendfile64(fd_t out_fd, fd_t in_fd, addr_t offset_addr, dword_t coun
dword_t sys_getpid();
dword_t sys_gettid();
dword_t sys_getppid();
dword_t sys_getpgid(dword_t pid);
dword_t sys_getpgrp();
dword_t sys_getuid32();
dword_t sys_getuid();
dword_t sys_geteuid32();
Expand All @@ -93,6 +95,7 @@ dword_t sys_getcwd(addr_t buf_addr, dword_t size);
dword_t sys_chdir(addr_t path_addr);
int sys_set_thread_area(addr_t u_info);
int sys_set_tid_address(addr_t blahblahblah);
dword_t sys_setsid();

// system information
#define UNAME_LENGTH 65
Expand Down
7 changes: 1 addition & 6 deletions sys/exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,7 @@ dword_t sys_wait4(dword_t id, addr_t status_addr, dword_t options, addr_t rusage
}
} else {
// check if this child is a zombie
struct pid *pid = pid_get(id);
if (pid == NULL) {
unlock(current);
return _ECHILD;
}
struct process *proc = pid->proc;
struct process *proc = pid_get_proc(id);
if (proc == NULL || proc->parent != current) {
unlock(current);
return _ECHILD;
Expand Down
8 changes: 8 additions & 0 deletions sys/getset.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ dword_t sys_gettid() {
dword_t sys_getppid() {
return current->ppid;
}
dword_t sys_getpgid(dword_t pid) {
if (pid != 0)
return _EPERM;
return current->pgid;
}
dword_t sys_getpgrp() {
return current->pgid;
}

dword_t sys_getuid32() {
return current->uid;
Expand Down
44 changes: 37 additions & 7 deletions sys/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,28 +29,58 @@ static struct pid *pid_create() {
return pid;
}

static void pid_retain(struct pid *pid) {
void pid_retain(struct pid *pid) {
pid->refcnt++;
}
static void pid_release(struct pid *pid) {
pthread_mutex_lock(&pids_lock);
void pid_release(struct pid *pid) {
if (--pid->refcnt == 0) {
pthread_mutex_lock(&pids_lock);
pids[pid->id] = NULL;
pthread_mutex_unlock(&pids_lock);
free(pid);
}
pthread_mutex_unlock(&pids_lock);
}

struct pid *pid_get(dword_t id) {
pthread_mutex_lock(&pids_lock);
struct pid *pid = pids[id];
lock(pid);
pid->refcnt++;
unlock(pid);
if (pid != NULL)
pid_retain(pid);
pthread_mutex_unlock(&pids_lock);
return pid;
}

// TODO more dry
struct process *pid_get_proc(dword_t id) {
struct pid *pid = pid_get(id);
if (pid == NULL) return NULL;
lock(pid);
struct process *proc = pid->proc;
unlock(pid);
pid_release(pid);
return proc;
}

struct pgroup *pid_get_group(dword_t id) {
struct pid *pid = pid_get(id);
if (pid == NULL) return NULL;
lock(pid);
struct pgroup *group = pid->group;
unlock(pid);
pid_release(pid);
return group;
}

struct session *pid_get_session(dword_t id) {
struct pid *pid = pid_get(id);
if (pid == NULL) return NULL;
lock(pid);
struct session *session = pid->session;
unlock(pid);
pid_release(pid);
return session;
}

struct process *process_create() {
struct pid *pid = pid_create();
if (pid == NULL)
Expand Down
30 changes: 12 additions & 18 deletions sys/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@
#define PROCESS_H

#include <pthread.h>
#include <stdatomic.h>
#include "util/list.h"
#include "emu/cpu.h"
#include "sys/fs.h"
#include "sys/signal.h"

struct proc_group;
struct pgroup;
struct session;

struct process {
struct cpu_state cpu;
struct cpu_state cpu; // do not access this field except on the current process
pthread_t thread;

dword_t pid, ppid;
Expand All @@ -35,7 +36,7 @@ struct process {
struct list children;
struct list siblings;

struct proc_group *group;
dword_t sid, pgid;
struct list group_procs;

bool has_timer;
Expand Down Expand Up @@ -64,28 +65,21 @@ struct process *process_create(void);
void process_destroy(struct process *proc);

struct pid {
unsigned refcnt;
dword_t id;
atomic_uint refcnt;
dword_t id; // immutable, no lock needed
struct process *proc;
struct proc_group *group;
struct pgroup *group;
struct session *session;
pthread_mutex_t lock;
};

// Returns the process with the given PID, or NULL if it doesn't exist.
struct pid *pid_get(dword_t pid);
struct process *pid_get_proc(dword_t pid);
struct pgroup *pid_get_group(dword_t pid);
struct session *pid_get_session(dword_t pid);

struct proc_group {
struct list procs;
struct session *session;
struct list session_groups;
pthread_mutex_t lock;
};

struct session {
struct list groups;
pthread_mutex_t lock;
};
void pid_retain(struct pid *pid);
void pid_release(struct pid *pid);

// When a thread is created to run a new process, this function is used.
extern void (*run_process_func)();
Expand Down
2 changes: 2 additions & 0 deletions tools/ptraceomatic.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@ static void step_tracing(struct cpu_state *cpu, int pid, int sender, int receive
// put syscall result from fake process into real process
case 3: // read
pt_copy(pid, regs.rcx, cpu->edx); break;
case 7: // waitpid
pt_copy(pid, regs.rcx, sizeof(dword_t)); break;
case 13: // time
if (regs.rbx != 0)
pt_copy(pid, regs.rbx, sizeof(dword_t));
Expand Down
Loading

0 comments on commit 3c4b180

Please sign in to comment.