Repository navigation
Expand file tree
/
Copy patharray_object.c
More file actions
142 lines (124 loc) · 4.2 KB
/
Copy patharray_object.c
File metadata and controls
142 lines (124 loc) · 4.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
* Copyright 2026 Graham Lee.
*
* This file is part of machoo.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mach.h>
#include <hurd.h>
#include <hurd/ports.h>
#include "machoo_defs.h"
#include "machoo_impl.h"
extern kern_return_t integerValue(
mach_port_t receiver,
int *value
);
extern kern_return_t integerWithValue(
mach_port_t receiver,
int value,
mach_port_t *object
);
struct machoo_array_state {
struct machoo_object_state base;
mach_port_t *array_objects;
mach_msg_type_number_t array_count;
};
const size_t subclass_state_size = sizeof(struct machoo_array_state);
void subclass_dealloc(struct machoo_object_state *self) {
struct machoo_array_state *state = (struct machoo_array_state *)self;
if (state->array_objects != NULL) {
for (mach_msg_type_number_t i = 0; i < state->array_count; i++) {
if (state->array_objects[i] != MACH_PORT_NULL) {
mach_port_deallocate(mach_task_self(), state->array_objects[i]);
}
}
free(state->array_objects);
state->array_objects = NULL;
}
}
void subclass_set_int_val(struct machoo_object_state *self, int value) {}
kern_return_t server_machoo_msg_send(
mach_port_t receiver,
machoo_selector selector,
object_array_t objects,
mach_msg_type_number_t objectsCnt,
mach_port_t *reply_object,
mach_msg_type_name_t *reply_objectPoly
)
{
struct machoo_object_state *tl_state = machoo_lookup_object(receiver);
if (!tl_state) return KERN_INVALID_ARGUMENT;
pthread_mutex_lock(&tl_state->lock);
if (tl_state->state == MACHOO_QUITTING) {
pthread_mutex_unlock(&tl_state->lock);
machoo_release_object(tl_state);
return KERN_INVALID_ARGUMENT;
}
*reply_object = MACH_PORT_NULL;
*reply_objectPoly = MACH_MSG_TYPE_MAKE_SEND;
struct machoo_array_state *astate = (struct machoo_array_state *)tl_state;
if (strcmp(selector, "initWithObjects:") == 0) {
if (astate->array_objects != NULL) {
pthread_mutex_unlock(&tl_state->lock);
machoo_release_object(tl_state);
return KERN_INVALID_ARGUMENT; /* It's an error to init the same object twice. */
}
if (objectsCnt == 0) {
static mach_port_t empty_array_port = MACH_PORT_NULL;
static pthread_mutex_t empty_array_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&empty_array_lock);
if (empty_array_port == MACH_PORT_NULL) {
empty_array_port = ports_get_right(&tl_state->pi);
astate->array_count = 0;
astate->array_objects = malloc(1); // Create a valid pointer to mark the empty array as initialized.
*reply_object = empty_array_port;
} else {
*reply_object = empty_array_port;
}
*reply_objectPoly = MACH_MSG_TYPE_MAKE_SEND;
pthread_mutex_unlock(&empty_array_lock);
} else {
astate->array_count = objectsCnt;
astate->array_objects = malloc(objectsCnt * sizeof(mach_port_t));
for (int i = 0; i < objectsCnt; i++) {
/* Copy the send rights of the element objects. */
mach_port_mod_refs(mach_task_self(), objects[i], MACH_PORT_RIGHT_SEND, 1);
astate->array_objects[i] = objects[i];
}
*reply_object = ports_get_right(&tl_state->pi);
}
}
else if (strcmp(selector, "count") == 0) {
mach_port_t int_class = file_name_lookup("/tmp/integer", 0, 0);
if (int_class != MACH_PORT_NULL) {
kern_return_t ret = integerWithValue(int_class, astate->array_count, reply_object);
if (ret == ERR_SUCCESS) {
*reply_objectPoly = MACH_MSG_TYPE_COPY_SEND;
}
mach_port_deallocate(mach_task_self(), int_class);
}
}
else if (strcmp(selector, "objectAtIndex:") == 0) {
if (objectsCnt == 1 && objects[0] != MACH_PORT_NULL) {
int index = -1;
kern_return_t ret = integerValue(objects[0], &index);
if (ret == ERR_SUCCESS && index >= 0 && index < astate->array_count) {
*reply_object = astate->array_objects[index];
*reply_objectPoly = MACH_MSG_TYPE_COPY_SEND;
}
}
}
pthread_mutex_unlock(&tl_state->lock);
machoo_release_object(tl_state);
return ERR_SUCCESS;
}
kern_return_t server_integerValue(
mach_port_t receiver,
int *value
)
{
*value = 0;
return ERR_SUCCESS;
}