summaryrefslogtreecommitdiff
path: root/libcons/vcons-open.c
diff options
context:
space:
mode:
Diffstat (limited to 'libcons/vcons-open.c')
-rw-r--r--libcons/vcons-open.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/libcons/vcons-open.c b/libcons/vcons-open.c
index 7256b4c8..0d826b63 100644
--- a/libcons/vcons-open.c
+++ b/libcons/vcons-open.c
@@ -29,9 +29,10 @@
#include "cons.h"
-/* Open the virtual console VCONS. VCONS->cons is locked. */
+/* Open the virtual console for VCONS_ENTRY. CONS is locked.
+ Afterwards, R_VCONS will be locked. */
error_t
-cons_vcons_open (vcons_t vcons)
+cons_vcons_open (cons_t cons, vcons_list_t vcons_entry, vcons_t *r_vcons)
{
error_t err = 0;
char *name;
@@ -40,12 +41,23 @@ cons_vcons_open (vcons_t vcons)
int fd = -1;
struct stat statbuf;
mach_port_t notify = MACH_PORT_NULL;
+ vcons_t vcons;
- if (asprintf (&name, "%u", vcons->id) < 0)
+ if (asprintf (&name, "%u", vcons_entry->id) < 0)
return err;
+ /* Set up the port we receive notification messages on. */
+ err = ports_create_port (cons_port_class, cons_port_bucket,
+ sizeof (*vcons), &vcons);
+ if (err)
+ goto err;
+ vcons->notify.cons = NULL;
+ vcons->cons = cons;
+ vcons->vcons_entry = vcons_entry;
+ vcons->id = vcons_entry->id;
+
/* Open the directory port of the virtual console. */
- vconsp = file_name_lookup_under (vcons->cons->dirport, name,
+ vconsp = file_name_lookup_under (cons->dirport, name,
O_DIRECTORY | O_RDONLY, 0);
if (vconsp == MACH_PORT_NULL)
{
@@ -116,23 +128,19 @@ cons_vcons_open (vcons_t vcons)
vcons->state.changes.buffer = ((uint32_t *) vcons->display)
+ vcons->display->changes.buffer;
- /* Set up the port we receive notification messages on. */
- err = ports_create_port (cons_port_class, cons_port_bucket,
- sizeof (*vcons->notify), &vcons->notify);
- if (err)
- goto err;
- vcons->notify->cons = NULL;
- vcons->notify->vcons = vcons;
-
/* Request notification messages. */
- notify = ports_get_right (vcons->notify);
+ notify = ports_get_right (vcons);
mach_port_set_qlimit (mach_task_self (), notify, 1);
/* When this succeeds, we will immediately receive notification
messages for this virtual console. */
+ mutex_lock (&vcons->lock);
err = file_notice_changes (file, notify, MACH_MSG_TYPE_MAKE_SEND);
if (!err)
- goto out;
+ {
+ *r_vcons = vcons;
+ goto out;
+ }
err:
if (vcons->input >= 0)
@@ -148,8 +156,9 @@ cons_vcons_open (vcons_t vcons)
if (notify)
{
mach_port_deallocate (mach_task_self (), notify);
- vcons->notify = MACH_PORT_NULL;
+ ports_port_deref (vcons);
}
+ ports_destroy_right (vcons);
out:
if (fd > 0)
close (fd);