kernel: getpgid; esh: fixups
This commit is contained in:
parent
36afa24d2f
commit
35c29e9b4d
45
apps/sh.c
45
apps/sh.c
@ -71,9 +71,32 @@ static int current_line = 0;
|
||||
static char * current_file = NULL;
|
||||
|
||||
int pid; /* Process ID of the shell */
|
||||
int my_pgid;
|
||||
|
||||
int is_subshell = 0;
|
||||
|
||||
struct semaphore {
|
||||
int fds[2];
|
||||
};
|
||||
|
||||
struct semaphore create_semaphore(void) {
|
||||
struct semaphore out;
|
||||
pipe(out.fds);
|
||||
return out;
|
||||
}
|
||||
|
||||
void raise_semaphore(struct semaphore s){
|
||||
close(s.fds[0]);
|
||||
close(s.fds[1]);
|
||||
}
|
||||
|
||||
void wait_semaphore(struct semaphore s) {
|
||||
close(s.fds[1]);
|
||||
char buf;
|
||||
read(s.fds[0], &buf, 1);
|
||||
close(s.fds[0]);
|
||||
}
|
||||
|
||||
void set_pgid(int pgid) {
|
||||
if (shell_interactive == 1) {
|
||||
setpgid(0, pgid);
|
||||
@ -88,7 +111,7 @@ void set_pgrp(int pgid) {
|
||||
|
||||
void reset_pgrp() {
|
||||
if (shell_interactive == 1 && !is_subshell) {
|
||||
tcsetpgrp(STDIN_FILENO, pid);
|
||||
tcsetpgrp(STDIN_FILENO, my_pgid);
|
||||
}
|
||||
}
|
||||
|
||||
@ -783,9 +806,11 @@ int wait_for_child(int pgid, char * name) {
|
||||
int waitee = (shell_interactive == 1 && !is_subshell) ? -pgid : pgid;
|
||||
int outpid;
|
||||
int ret_code = 0;
|
||||
int e;
|
||||
|
||||
do {
|
||||
outpid = waitpid(waitee, &ret_code, WSTOPPED);
|
||||
e = errno;
|
||||
if (WIFSTOPPED(ret_code)) {
|
||||
suspended_pgid = pgid;
|
||||
if (name) {
|
||||
@ -797,7 +822,7 @@ int wait_for_child(int pgid, char * name) {
|
||||
suspended_pgid = 0;
|
||||
hashmap_remove(job_hash, (void*)pgid);
|
||||
}
|
||||
} while (outpid != -1 || (outpid == -1 && errno != ECHILD));
|
||||
} while (outpid != -1 || (outpid == -1 && e != ECHILD));
|
||||
reset_pgrp();
|
||||
handle_status(ret_code);
|
||||
return WEXITSTATUS(ret_code);
|
||||
@ -1244,10 +1269,13 @@ _nope:
|
||||
if (cmdi > 0) {
|
||||
int last_output[2];
|
||||
pipe(last_output);
|
||||
|
||||
struct semaphore s = create_semaphore();
|
||||
child_pid = fork();
|
||||
if (!child_pid) {
|
||||
set_pgid(0);
|
||||
set_pgrp(getpid());
|
||||
if (!nowait) set_pgrp(getpid());
|
||||
raise_semaphore(s);
|
||||
is_subshell = 1;
|
||||
dup2(last_output[1], STDOUT_FILENO);
|
||||
close(last_output[0]);
|
||||
@ -1294,16 +1322,20 @@ _nope:
|
||||
close(last_output[0]);
|
||||
close(last_output[1]);
|
||||
|
||||
wait_semaphore(s);
|
||||
|
||||
/* Now execute the last piece and wait on all of them */
|
||||
} else {
|
||||
shell_command_t func = shell_find(*arg_starts[0]);
|
||||
if (func) {
|
||||
return func(argcs[0], arg_starts[0]);
|
||||
} else {
|
||||
struct semaphore s = create_semaphore();
|
||||
child_pid = fork();
|
||||
if (!child_pid) {
|
||||
set_pgid(0);
|
||||
set_pgrp(getpid());
|
||||
if (!nowait) set_pgrp(getpid());
|
||||
raise_semaphore(s);
|
||||
is_subshell = 1;
|
||||
if (output_files[cmdi]) {
|
||||
int fd = open(output_files[cmdi], file_args[cmdi], 0666);
|
||||
@ -1316,6 +1348,9 @@ _nope:
|
||||
}
|
||||
run_cmd(arg_starts[0]);
|
||||
}
|
||||
|
||||
wait_semaphore(s);
|
||||
|
||||
pgid = child_pid;
|
||||
last_child = child_pid;
|
||||
}
|
||||
@ -1519,7 +1554,7 @@ int main(int argc, char ** argv) {
|
||||
|
||||
shell_interactive = 1;
|
||||
|
||||
signal(SIGTSTP, SIG_IGN);
|
||||
my_pgid = getpgid(0);
|
||||
signal(SIGTTOU, SIG_IGN);
|
||||
signal(SIGTTIN, SIG_IGN);
|
||||
|
||||
|
@ -119,6 +119,7 @@ DECL_SYSCALL1(pipe, int *);
|
||||
DECL_SYSCALL3(readlink, char *, char *, int);
|
||||
DECL_SYSCALL0(setsid);
|
||||
DECL_SYSCALL2(setpgid,int,int);
|
||||
DECL_SYSCALL1(getpgid,int);
|
||||
|
||||
_End_C_Header
|
||||
|
||||
|
@ -52,3 +52,4 @@
|
||||
#define SYS_CHOWN 61
|
||||
#define SYS_SETSID 62
|
||||
#define SYS_SETPGID 63
|
||||
#define SYS_GETPGID 64
|
||||
|
@ -85,5 +85,6 @@ extern int sethostname(const char * name, size_t len);
|
||||
|
||||
extern pid_t setsid(void);
|
||||
extern int setpgid(pid_t, pid_t);
|
||||
extern pid_t getpgid(pid_t);
|
||||
|
||||
_End_C_Header
|
||||
|
@ -986,6 +986,21 @@ static int sys_setpgid(pid_t pid, pid_t pgid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sys_getpgid(pid_t pid) {
|
||||
process_t * proc;
|
||||
if (pid == 0) {
|
||||
proc = (process_t*)current_process;
|
||||
} else {
|
||||
proc = process_from_pid(pid);
|
||||
}
|
||||
|
||||
if (!proc) {
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
return proc->job;
|
||||
}
|
||||
|
||||
/*
|
||||
* System Call Internals
|
||||
*/
|
||||
@ -1043,6 +1058,7 @@ static int (*syscalls[])() = {
|
||||
[SYS_CHOWN] = sys_chown,
|
||||
[SYS_SETSID] = sys_setsid,
|
||||
[SYS_SETPGID] = sys_setpgid,
|
||||
[SYS_GETPGID] = sys_getpgid,
|
||||
};
|
||||
|
||||
uint32_t num_syscalls = sizeof(syscalls) / sizeof(*syscalls);
|
||||
|
@ -4,8 +4,13 @@
|
||||
#include <errno.h>
|
||||
|
||||
DEFN_SYSCALL2(setpgid, SYS_SETPGID, int, int);
|
||||
DEFN_SYSCALL1(getpgid, SYS_GETPGID, int);
|
||||
|
||||
int setpgid(pid_t pid, pid_t pgid) {
|
||||
__sets_errno(syscall_setpgid((int)pid,(int)pgid));
|
||||
}
|
||||
|
||||
pid_t getpgid(pid_t pid) {
|
||||
__sets_errno(syscall_getpgid((int)pid));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user