Implement proper wait/waitpid.
This is a pretty big commit, so let's run through it in parts: - All of the userspace changes are to switch away from syscall_wait Mostly, this is to waitpid; some things were tweaked to do things "properly" instead of waiting for particular processes. Init has been fixed to do a proper spin wait. - syscall_wait is gone - as are its uses. newlib bindings have been using just waitpid for a while now. - waitpid now performs like a Unix waitpid - process reaping is no longer a "do this on next change thing": it happens when a process is waited on, like it should (That means we can have real zombies: terminated processes that have not yet been waited on) - Reparenting of children to init has been implemented, so you can fork-daemonize! Overall, this is pretty big... So I hope it doesn't break everything.
This commit is contained in:
parent
cd1880ebb5
commit
4d8335ad75
@ -152,6 +152,20 @@ void tree_remove(tree_t * tree, tree_node_t * node) {
|
||||
free(node);
|
||||
}
|
||||
|
||||
void tree_remove_reparent_root(tree_t * tree, tree_node_t * node) {
|
||||
/* Remove this node and move its children into the root children */
|
||||
tree_node_t * parent = node->parent;
|
||||
if (!parent) return;
|
||||
tree->nodes--;
|
||||
list_delete(parent->children, list_find(parent->children, node));
|
||||
foreach(child, node->children) {
|
||||
/* Reassign the parents */
|
||||
((tree_node_t *)child->value)->parent = tree->root;
|
||||
}
|
||||
list_merge(tree->root->children, node->children);
|
||||
free(node);
|
||||
}
|
||||
|
||||
void tree_break_off(tree_t * tree, tree_node_t * node) {
|
||||
tree_node_t * parent = node->parent;
|
||||
if (!parent) return;
|
||||
|
@ -102,6 +102,7 @@ typedef struct process {
|
||||
node_t sleep_node;
|
||||
node_t * timed_sleep_node;
|
||||
uint8_t is_tasklet;
|
||||
volatile uint8_t sleep_interrupted;
|
||||
} process_t;
|
||||
|
||||
typedef struct {
|
||||
@ -117,18 +118,14 @@ extern process_t * spawn_init(void);
|
||||
extern process_t * spawn_kidle(void);
|
||||
extern void set_process_environment(process_t * proc, page_directory_t * directory);
|
||||
extern void make_process_ready(process_t * proc);
|
||||
extern void make_process_reapable(process_t * proc);
|
||||
extern uint8_t process_available(void);
|
||||
extern process_t * next_ready_process(void);
|
||||
extern uint8_t should_reap(void);
|
||||
extern process_t * next_reapable_process(void);
|
||||
extern uint32_t process_append_fd(process_t * proc, fs_node_t * node);
|
||||
extern process_t * process_from_pid(pid_t pid);
|
||||
extern process_t * process_get_first_child(process_t * process);
|
||||
extern void delete_process(process_t * proc);
|
||||
process_t * process_get_parent(process_t * process);
|
||||
extern uint32_t process_move_fd(process_t * proc, int src, int dest);
|
||||
extern int process_is_ready(process_t * proc);
|
||||
extern void set_reaped(process_t * proc);
|
||||
|
||||
extern void wakeup_sleepers(unsigned long seconds, unsigned long subseconds);
|
||||
extern void sleep_until(process_t * process, unsigned long seconds, unsigned long subseconds);
|
||||
@ -140,6 +137,10 @@ extern list_t * process_list;
|
||||
typedef void (*tasklet_t) (void *, char *);
|
||||
extern int create_kernel_tasklet(tasklet_t tasklet, char * name, void * argp);
|
||||
|
||||
extern void release_directory(page_directory_t * dir);
|
||||
extern void release_directory_for_exec(page_directory_t * dir);
|
||||
|
||||
extern void reap_process(process_t * proc);
|
||||
extern int waitpid(int pid, int * status, int options);
|
||||
|
||||
#endif
|
||||
|
@ -25,5 +25,4 @@ typedef struct page_directory {
|
||||
int32_t ref_count;
|
||||
} page_directory_t;
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -16,13 +16,10 @@
|
||||
tree_t * process_tree; /* Parent->Children tree */
|
||||
list_t * process_list; /* Flat storage */
|
||||
list_t * process_queue; /* Ready queue */
|
||||
list_t * reap_queue; /* Processes to reap */
|
||||
list_t * sleep_queue;
|
||||
list_t * recently_reaped;
|
||||
volatile process_t * current_process = NULL;
|
||||
process_t * kernel_idle_task = NULL;
|
||||
|
||||
static uint8_t volatile reap_lock = 0;
|
||||
static uint8_t volatile tree_lock = 0;
|
||||
static uint8_t volatile process_queue_lock = 0;
|
||||
static uint8_t volatile wait_lock_tmp = 0;
|
||||
@ -38,9 +35,7 @@ void initialize_process_tree(void) {
|
||||
process_tree = tree_create();
|
||||
process_list = list_create();
|
||||
process_queue = list_create();
|
||||
reap_queue = list_create();
|
||||
sleep_queue = list_create();
|
||||
recently_reaped = list_create();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -102,16 +97,6 @@ process_t * next_ready_process(void) {
|
||||
return next;
|
||||
}
|
||||
|
||||
process_t * next_reapable_process(void) {
|
||||
spin_lock(&reap_lock);
|
||||
node_t * np = list_dequeue(reap_queue);
|
||||
spin_unlock(&reap_lock);
|
||||
if (!np) { return NULL; }
|
||||
process_t * next = np->value;
|
||||
free(np);
|
||||
return next;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reinsert a process into the ready queue.
|
||||
*
|
||||
@ -130,6 +115,7 @@ void make_process_ready(process_t * proc) {
|
||||
}
|
||||
/* Else: I have no idea what happened. */
|
||||
} else {
|
||||
proc->sleep_interrupted = 1;
|
||||
spin_lock(&wait_lock_tmp);
|
||||
list_delete((list_t*)proc->sleep_node.owner, &proc->sleep_node);
|
||||
spin_unlock(&wait_lock_tmp);
|
||||
@ -140,18 +126,8 @@ void make_process_ready(process_t * proc) {
|
||||
spin_unlock(&process_queue_lock);
|
||||
}
|
||||
|
||||
void make_process_reapable(process_t * proc) {
|
||||
delete_process(proc);
|
||||
spin_lock(&reap_lock);
|
||||
list_insert(reap_queue, (void *)proc);
|
||||
spin_unlock(&reap_lock);
|
||||
}
|
||||
|
||||
void set_reaped(process_t * proc) {
|
||||
spin_lock(&reap_lock);
|
||||
list_insert(recently_reaped, (void *)proc);
|
||||
spin_unlock(&reap_lock);
|
||||
}
|
||||
extern void tree_remove_reparent_root(tree_t * tree, tree_node_t * node);
|
||||
|
||||
/*
|
||||
* Delete a process from the process tree
|
||||
@ -167,11 +143,20 @@ void delete_process(process_t * proc) {
|
||||
/* We can not remove the root, which is an error anyway */
|
||||
assert((entry != process_tree->root) && "Attempted to kill init.");
|
||||
|
||||
if (process_tree->root == entry) {
|
||||
/* We are init, don't even bother. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Remove the entry. */
|
||||
spin_lock(&tree_lock);
|
||||
tree_remove(process_tree, entry);
|
||||
/* Reparent everyone below me to init */
|
||||
tree_remove_reparent_root(process_tree, entry);
|
||||
list_delete(process_list, list_find(process_list, proc));
|
||||
spin_unlock(&tree_lock);
|
||||
|
||||
/* Uh... */
|
||||
free(proc);
|
||||
}
|
||||
|
||||
static void _kidle(void) {
|
||||
@ -408,14 +393,6 @@ process_t * spawn_process(volatile process_t * parent) {
|
||||
return proc;
|
||||
}
|
||||
|
||||
process_t * find_reaped_process(pid_t pid) {
|
||||
foreach(node, recently_reaped) {
|
||||
process_t * proc = node->value;
|
||||
if (proc && proc->id == pid) return proc;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t process_compare(void * proc_v, void * pid_v) {
|
||||
pid_t pid = (*(pid_t *)pid_v);
|
||||
process_t * proc = (process_t *)proc_v;
|
||||
@ -431,32 +408,20 @@ process_t * process_from_pid(pid_t pid) {
|
||||
spin_unlock(&tree_lock);
|
||||
if (entry) {
|
||||
return (process_t *)entry->value;
|
||||
} else {
|
||||
return find_reaped_process(pid);
|
||||
}
|
||||
}
|
||||
|
||||
process_t * process_get_first_child_rec(tree_node_t * node, process_t * target) {
|
||||
if (!node) return NULL;
|
||||
process_t * proc = (process_t *)node->value;
|
||||
if (proc == target) {
|
||||
foreach(child, node->children) {
|
||||
process_t * cproc = (process_t *)((tree_node_t *)child->value)->value;
|
||||
return cproc;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
foreach(child, node->children) {
|
||||
/* Recursively print the children */
|
||||
process_t * out = process_get_first_child_rec(child->value, target);
|
||||
if (out) return out;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
process_t * process_get_first_child(process_t * process) {
|
||||
process_t * process_get_parent(process_t * process) {
|
||||
process_t * result = NULL;
|
||||
spin_lock(&tree_lock);
|
||||
process_t * result = process_get_first_child_rec(process_tree->root, process);
|
||||
|
||||
tree_node_t * entry = process->tree_entry;
|
||||
|
||||
if (entry->parent) {
|
||||
result = entry->parent->value;
|
||||
}
|
||||
|
||||
spin_unlock(&tree_lock);
|
||||
return result;
|
||||
}
|
||||
@ -519,10 +484,6 @@ uint8_t process_available(void) {
|
||||
return (process_queue->head != NULL);
|
||||
}
|
||||
|
||||
uint8_t should_reap(void) {
|
||||
return (reap_queue->head != NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Append a file descriptor to a process.
|
||||
*
|
||||
@ -583,11 +544,12 @@ int sleep_on(list_t * queue) {
|
||||
switch_task(0);
|
||||
return 0;
|
||||
}
|
||||
current_process->sleep_interrupted = 0;
|
||||
spin_lock(&wait_lock_tmp);
|
||||
list_append(queue, (node_t *)¤t_process->sleep_node);
|
||||
spin_unlock(&wait_lock_tmp);
|
||||
switch_task(0);
|
||||
return 0;
|
||||
return current_process->sleep_interrupted;
|
||||
}
|
||||
|
||||
int process_is_ready(process_t * proc) {
|
||||
@ -640,3 +602,119 @@ void sleep_until(process_t * process, unsigned long seconds, unsigned long subse
|
||||
process->timed_sleep_node = list_insert_after(sleep_queue, before, proc);
|
||||
spin_unlock(&sleep_lock);
|
||||
}
|
||||
|
||||
void reap_process(process_t * proc) {
|
||||
debug_print(INFO, "Reaping process %d; mem before = %d", proc->id, memory_use());
|
||||
list_free(proc->wait_queue);
|
||||
free(proc->wait_queue);
|
||||
list_free(proc->signal_queue);
|
||||
free(proc->signal_queue);
|
||||
free(proc->wd_name);
|
||||
debug_print(INFO, "Releasing shared memory for %d", proc->id);
|
||||
shm_release_all(proc);
|
||||
free(proc->shm_mappings);
|
||||
debug_print(INFO, "Freeing more mems %d", proc->id);
|
||||
free(proc->name);
|
||||
if (proc->signal_kstack) {
|
||||
free(proc->signal_kstack);
|
||||
}
|
||||
debug_print(INFO, "Dec'ing fds for %d", proc->id);
|
||||
proc->fds->refs--;
|
||||
if (proc->fds->refs == 0) {
|
||||
debug_print(INFO, "Reached 0, all dependencies are closed for %d's file descriptors and page directories", proc->id);
|
||||
release_directory(proc->thread.page_directory);
|
||||
debug_print(INFO, "Going to clear out the file descriptors %d", proc->id);
|
||||
for (uint32_t i = 0; i < proc->fds->length; ++i) {
|
||||
if (proc->fds->entries[i]) {
|
||||
//close_fs(proc->fds->entries[i]);
|
||||
//free(proc->fds->entries[i]);
|
||||
}
|
||||
//close_fs(proc->fds->entries[i]);
|
||||
}
|
||||
debug_print(INFO, "... and their storage %d", proc->id);
|
||||
free(proc->fds->entries);
|
||||
free(proc->fds);
|
||||
debug_print(INFO, "... and the kernel stack (hope this ain't us) %d", proc->id);
|
||||
free((void *)(proc->image.stack - KERNEL_STACK_SIZE));
|
||||
}
|
||||
debug_print(INFO, "Reaped process %d; mem after = %d", proc->id, memory_use());
|
||||
|
||||
delete_process(proc);
|
||||
debug_print_process_tree();
|
||||
}
|
||||
|
||||
static int wait_candidate(process_t * parent, int pid, int options, process_t * proc) {
|
||||
(void)options; /* there is only one option that affects candidacy, and we don't support it yet */
|
||||
|
||||
if (!proc) return 0;
|
||||
|
||||
if (pid < -1) {
|
||||
if (proc->group == -pid || proc->id == -pid) return 1;
|
||||
} else if (pid == 0) {
|
||||
/* Matches our group ID */
|
||||
if (proc->group == parent->id) return 1;
|
||||
} else if (pid > 0) {
|
||||
/* Specific pid */
|
||||
if (proc->id == pid) return 1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int waitpid(int pid, int * status, int options) {
|
||||
process_t * proc = (process_t *)current_process;
|
||||
if (proc->group) {
|
||||
proc = process_from_pid(proc->group);
|
||||
}
|
||||
|
||||
debug_print(NOTICE, "waitpid(%s%d, ..., %d) (from pid=%d.%d)", (pid >= 0) ? "" : "-", (pid >= 0) ? pid : -pid, options, current_process->id, current_process->group);
|
||||
|
||||
do {
|
||||
process_t * candidate = NULL;
|
||||
int has_children = 0;
|
||||
|
||||
/* First, find out if there is anyone to reap */
|
||||
foreach(node, proc->tree_entry->children) {
|
||||
if (!node->value) {
|
||||
continue;
|
||||
}
|
||||
process_t * child = ((tree_node_t *)node->value)->value;
|
||||
|
||||
if (wait_candidate(proc, pid, options, child)) {
|
||||
has_children = 1;
|
||||
if (child->finished) {
|
||||
candidate = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_children) {
|
||||
/* No valid children matching this description */
|
||||
debug_print(NOTICE, "No children matching description.");
|
||||
return -ECHILD;
|
||||
}
|
||||
|
||||
if (candidate) {
|
||||
debug_print(NOTICE, "Candidate found (%x:%d), bailing early.", candidate, candidate->id);
|
||||
if (status) {
|
||||
*status = candidate->status;
|
||||
}
|
||||
int pid = candidate->id;
|
||||
reap_process(candidate);
|
||||
return pid;
|
||||
} else {
|
||||
if (options & 1) {
|
||||
return 0;
|
||||
}
|
||||
debug_print(NOTICE, "Sleeping until queue is done.");
|
||||
/* Wait */
|
||||
if (sleep_on(proc->wait_queue) != 0) {
|
||||
debug_print(NOTICE, "wait() was interrupted");
|
||||
return -EINTR;
|
||||
}
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
|
||||
|
@ -109,73 +109,10 @@ static int write(int fd, char * ptr, int len) {
|
||||
return out;
|
||||
}
|
||||
|
||||
static int advanced_wait(int child, int * status, int options) {
|
||||
process_t * volatile child_task;
|
||||
if (child == 0) {
|
||||
debug_print_process_tree();
|
||||
child_task = process_get_first_child((process_t *)current_process);
|
||||
} else if (child == -1) {
|
||||
debug_print(WARNING, "wait(-1) from %d", getpid());
|
||||
child_task = process_get_first_child((process_t *)current_process);
|
||||
} else if (child < 1) {
|
||||
debug_print(WARNING, "Process %d requested group wait, which we can not do! Pretending they asked for a single process (%d)", getpid(), -child);
|
||||
child_task = process_from_pid(-child);
|
||||
} else {
|
||||
child_task = process_from_pid(child);
|
||||
}
|
||||
/* If the child task doesn't exist, bail */
|
||||
if (!child_task) {
|
||||
if (status && !validate_safe(status)) {
|
||||
*status = 0;
|
||||
}
|
||||
debug_print(WARNING, "Tried to wait for non-existent process by pid %d", getpid());
|
||||
return -ECHILD;
|
||||
}
|
||||
debug_print(NOTICE, "pid=%d waiting on pid=%d", current_process->id, child_task->id);
|
||||
while (child_task->finished == 0) {
|
||||
/* Add us to the wait queue for this child */
|
||||
sleep_on(child_task->wait_queue);
|
||||
}
|
||||
/* Grab the child's return value */
|
||||
int ret = child_task->status;
|
||||
if (status && !validate_safe(status)) {
|
||||
*status = ret;
|
||||
}
|
||||
return child_task->id;
|
||||
}
|
||||
static int sys_waitpid(int pid, int * status, int options) {
|
||||
if (status && validate_safe(status)) return -EINVAL;
|
||||
|
||||
static int wait(int child) {
|
||||
process_t * volatile child_task;
|
||||
if (child == 0) {
|
||||
debug_print_process_tree();
|
||||
child_task = process_get_first_child((process_t *)current_process);
|
||||
} else if (child == -1) {
|
||||
debug_print(WARNING, "wait(-1) from %d", getpid());
|
||||
child_task = process_get_first_child((process_t *)current_process);
|
||||
if (child_task) {
|
||||
child = child_task->id;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else if (child < 1) {
|
||||
debug_print(WARNING, "Process %d requested group wait, which we can not do! Pretending they asked for a single process (%d)", getpid(), -child);
|
||||
child_task = process_from_pid(-child);
|
||||
} else {
|
||||
child_task = process_from_pid(child);
|
||||
}
|
||||
/* If the child task doesn't exist, bail */
|
||||
if (!child_task) {
|
||||
debug_print(WARNING, "Tried to wait for non-existent process %d by pid %d", child, getpid());
|
||||
return 0;
|
||||
}
|
||||
debug_print(NOTICE, "pid=%d waiting on pid=%d", current_process->id, child_task->id);
|
||||
while (child_task->finished == 0) {
|
||||
/* Add us to the wait queue for this child */
|
||||
sleep_on(child_task->wait_queue);
|
||||
}
|
||||
/* Grab the child's return value */
|
||||
int ret = child_task->status;
|
||||
return ret;
|
||||
return waitpid(pid, status, options);
|
||||
}
|
||||
|
||||
static int open(const char * file, int flags, int mode) {
|
||||
@ -714,7 +651,7 @@ static uintptr_t syscalls[] = {
|
||||
(uintptr_t)&seek,
|
||||
(uintptr_t)&stat,
|
||||
(uintptr_t)&RESERVED, /* 16 */
|
||||
(uintptr_t)&wait,
|
||||
(uintptr_t)&RESERVED,
|
||||
(uintptr_t)&RESERVED,
|
||||
(uintptr_t)&RESERVED,
|
||||
(uintptr_t)&RESERVED, /* 20 */
|
||||
@ -750,7 +687,7 @@ static uintptr_t syscalls[] = {
|
||||
(uintptr_t)&sys_chmod,
|
||||
(uintptr_t)&sys_umask,
|
||||
(uintptr_t)&sys_unlink, /* 52 */
|
||||
(uintptr_t)&advanced_wait,
|
||||
(uintptr_t)&sys_waitpid,
|
||||
};
|
||||
uint32_t num_syscalls;
|
||||
|
||||
|
@ -112,45 +112,6 @@ void release_directory_for_exec(page_directory_t * dir) {
|
||||
|
||||
extern char * default_name;
|
||||
|
||||
void reap_process(process_t * proc) {
|
||||
debug_print(INFO, "Reaping process %d; mem before = %d", proc->id, memory_use());
|
||||
list_free(proc->wait_queue);
|
||||
free(proc->wait_queue);
|
||||
list_free(proc->signal_queue);
|
||||
free(proc->signal_queue);
|
||||
free(proc->wd_name);
|
||||
debug_print(INFO, "Releasing shared memory for %d", proc->id);
|
||||
shm_release_all(proc);
|
||||
free(proc->shm_mappings);
|
||||
debug_print(INFO, "Freeing more mems %d", proc->id);
|
||||
free(proc->name);
|
||||
if (proc->signal_kstack) {
|
||||
free(proc->signal_kstack);
|
||||
}
|
||||
debug_print(INFO, "Dec'ing fds for %d", proc->id);
|
||||
proc->fds->refs--;
|
||||
if (proc->fds->refs == 0) {
|
||||
debug_print(INFO, "Reached 0, all dependencies are closed for %d's file descriptors and page directories", proc->id);
|
||||
release_directory(proc->thread.page_directory);
|
||||
debug_print(INFO, "Going to clear out the file descriptors %d", proc->id);
|
||||
for (uint32_t i = 0; i < proc->fds->length; ++i) {
|
||||
if (proc->fds->entries[i]) {
|
||||
//close_fs(proc->fds->entries[i]);
|
||||
//free(proc->fds->entries[i]);
|
||||
}
|
||||
//close_fs(proc->fds->entries[i]);
|
||||
}
|
||||
debug_print(INFO, "... and their storage %d", proc->id);
|
||||
free(proc->fds->entries);
|
||||
free(proc->fds);
|
||||
debug_print(INFO, "... and the kernel stack (hope this ain't us) %d", proc->id);
|
||||
free((void *)(proc->image.stack - KERNEL_STACK_SIZE));
|
||||
}
|
||||
debug_print(INFO, "Reaped process %d; mem after = %d", proc->id, memory_use());
|
||||
debug_print_process_tree();
|
||||
set_reaped(proc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clone a page table
|
||||
*
|
||||
@ -449,12 +410,6 @@ void switch_task(uint8_t reschedule) {
|
||||
if (eip == 0x10000) {
|
||||
/* Returned from EIP after task switch, we have
|
||||
* finished switching. */
|
||||
while (should_reap()) {
|
||||
process_t * proc = next_reapable_process();
|
||||
if (proc) {
|
||||
reap_process(proc);
|
||||
}
|
||||
}
|
||||
fix_signal_stacks();
|
||||
|
||||
/* XXX: Signals */
|
||||
@ -599,9 +554,12 @@ void task_exit(int retval) {
|
||||
}
|
||||
current_process->status = retval;
|
||||
current_process->finished = 1;
|
||||
debug_print(INFO, "[%d] Waking up %d processes...", getpid(), current_process->wait_queue->length);
|
||||
wakeup_queue(current_process->wait_queue);
|
||||
make_process_reapable((process_t *)current_process);
|
||||
process_t * parent = process_get_parent((process_t *)current_process);
|
||||
|
||||
if (parent) {
|
||||
wakeup_queue(parent->wait_queue);
|
||||
}
|
||||
|
||||
switch_next();
|
||||
}
|
||||
|
||||
|
@ -108,9 +108,9 @@ static hashmap_t * shell_commands_map = NULL;
|
||||
static int shell_create_userspace_shell(fs_node_t * tty, int argc, char * argv[]) {
|
||||
int pid = create_kernel_tasklet(debug_shell_run_sh, "[[k-sh]]", NULL);
|
||||
fprintf(tty, "Shell started with pid = %d\n", pid);
|
||||
process_t * child_task = process_from_pid(pid);
|
||||
sleep_on(child_task->wait_queue);
|
||||
return child_task->status;
|
||||
int status;
|
||||
waitpid(pid,&status,0);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int shell_echo(fs_node_t * tty, int argc, char * argv[]) {
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <syscall.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#define DEFAULT_HOSTNAME "toaru-test"
|
||||
|
||||
@ -50,7 +51,10 @@ int start_options(char * args[]) {
|
||||
int i = execvp(args[0], args);
|
||||
exit(0);
|
||||
} else {
|
||||
return syscall_wait(pid);
|
||||
while (1) {
|
||||
int i = wait(NULL);
|
||||
if (i == -1) return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <termios.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <sys/utsname.h>
|
||||
|
||||
@ -178,7 +179,7 @@ int main(int argc, char ** argv) {
|
||||
int i = execvp(args[0], args);
|
||||
} else {
|
||||
child = f;
|
||||
syscall_wait(f);
|
||||
waitpid(f, NULL, 0);
|
||||
}
|
||||
child = 0;
|
||||
free(username);
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include <syscall.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
int pid = syscall_system_function(7, NULL);
|
||||
return syscall_wait(pid);
|
||||
int status;
|
||||
wait(&status);
|
||||
return status;
|
||||
}
|
||||
|
@ -10,9 +10,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <syscall.h>
|
||||
#include "lib/pthread.h"
|
||||
#include <signal.h>
|
||||
#include <termios.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "lib/pthread.h"
|
||||
|
||||
int fd = 0;
|
||||
|
||||
@ -77,8 +79,7 @@ int main(int argc, char ** argv) {
|
||||
if (!strcmp(line, "quit")) {
|
||||
kill(child_pid, SIGKILL);
|
||||
printf("Waiting for threads to shut down...\n");
|
||||
syscall_wait(child_pid);
|
||||
|
||||
while (wait(NULL) != -1);
|
||||
printf("Exiting.\n");
|
||||
return 0;
|
||||
} else if (!strcmp(line, "continue")) {
|
||||
|
@ -1393,13 +1393,9 @@ int main(int argc, char * argv[]) {
|
||||
break;
|
||||
case YUTANI_MSG_SESSION_END:
|
||||
{
|
||||
for (unsigned int i = 0; i <= YUTANI_ZORDER_MAX; ++i) {
|
||||
if (yg->zlist[i]) {
|
||||
yutani_msg_t * response = yutani_msg_build_session_end();
|
||||
pex_send(server, yg->zlist[i]->owner, response->size, (char *)response);
|
||||
free(response);
|
||||
}
|
||||
}
|
||||
yutani_msg_t * response = yutani_msg_build_session_end();
|
||||
pex_broadcast(server, response->size, (char *)response);
|
||||
free(response);
|
||||
}
|
||||
break;
|
||||
case YUTANI_MSG_WINDOW_FOCUS:
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <cairo.h>
|
||||
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "lib/sha2.h"
|
||||
#include "lib/graphics.h"
|
||||
@ -418,7 +419,7 @@ int main (int argc, char ** argv) {
|
||||
free(foo);
|
||||
free(buf);
|
||||
|
||||
syscall_wait(_session_pid);
|
||||
waitpid(_session_pid, NULL, 0);
|
||||
}
|
||||
|
||||
yutani_close(y, wina);
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <unistd.h>
|
||||
#include <syscall.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#define LINE_LEN 1024
|
||||
|
||||
@ -70,13 +71,12 @@ int main(int argc, char * argv[]) {
|
||||
execvp(args[0], args);
|
||||
}
|
||||
|
||||
syscall_wait(_panel_pid);
|
||||
wait(NULL);
|
||||
|
||||
printf("Session leader has exited. Sending INT signals to %d.\n", _wallpaper_pid);
|
||||
|
||||
printf("Waiting on wallpaper.\n");
|
||||
syscall_wait(_wallpaper_pid);
|
||||
|
||||
printf("Session has ended.\n");
|
||||
while (1) {
|
||||
int pid = waitpid(-1, NULL, 0);
|
||||
if (pid == -1) break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -122,12 +122,13 @@ static void * toastd_handler(void * garbage) {
|
||||
|
||||
while (!exit_app) {
|
||||
pex_packet_t * p = calloc(PACKET_SIZE, 1);
|
||||
pex_listen(toastd_server, p);
|
||||
if (pex_listen(toastd_server, p) > 0) {
|
||||
|
||||
notification_t * toast = (void *)p->data;
|
||||
add_toast(toast);
|
||||
notification_t * toast = (void *)p->data;
|
||||
add_toast(toast);
|
||||
|
||||
free(p);
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,7 +198,7 @@ int main (int argc, char ** argv) {
|
||||
}
|
||||
}
|
||||
|
||||
pthread_kill(toastd_thread, SIGWINCH);
|
||||
pthread_kill(toastd_thread, SIGINT);
|
||||
pthread_kill(closer_thread, SIGWINCH);
|
||||
|
||||
return 0;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <wchar.h>
|
||||
@ -477,7 +478,7 @@ void key_event(int ret, key_event_t * event) {
|
||||
}
|
||||
|
||||
void * wait_for_exit(void * garbage) {
|
||||
syscall_wait(child_pid);
|
||||
waitpid(child_pid, NULL, 0);
|
||||
/* Clean up */
|
||||
exit_application = 1;
|
||||
/* Exit */
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
#include <ft2build.h>
|
||||
@ -887,7 +888,7 @@ void key_event(int ret, key_event_t * event) {
|
||||
}
|
||||
|
||||
void * wait_for_exit(void * garbage) {
|
||||
syscall_wait(child_pid);
|
||||
waitpid(child_pid, NULL, 0);
|
||||
/* Clean up */
|
||||
exit_application = 1;
|
||||
/* Exit */
|
||||
@ -1069,6 +1070,7 @@ void * handle_incoming(void * garbage) {
|
||||
case YUTANI_MSG_SESSION_END:
|
||||
{
|
||||
kill(child_pid, SIGKILL);
|
||||
exit_application = 1;
|
||||
}
|
||||
break;
|
||||
case YUTANI_MSG_RESIZE_OFFER:
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
#include "lib/pthread.h"
|
||||
|
||||
#define NUM_THREADS 5
|
||||
@ -69,7 +70,7 @@ int main(int argc, char * argv[]) {
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUM_THREADS; ++i) {
|
||||
syscall_wait(thread[i].id);
|
||||
waitpid(thread[i].id, NULL, 0);
|
||||
}
|
||||
|
||||
printf("Done. Result of %scomputation was %d %s!!\n",
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
int quiet = 0;
|
||||
@ -28,7 +29,7 @@ int main(int argc, char ** argv) {
|
||||
} else {
|
||||
if (!quiet)
|
||||
printf("Waiting on %d\n", k);
|
||||
syscall_wait(k);
|
||||
waitpid(k, NULL, 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user