#ifndef SOCKS_OBJECT_H_ #define SOCKS_OBJECT_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif #define OBJECT_MAGIC 0xBADDCAFE #define OBJECT_NAME_MAX 64 #define OBJECT_CAST(to_type, to_type_member, p) \ ((to_type *)((uintptr_t)p) - offsetof(to_type, to_type_member)) #define OBJECT_C_CAST(c_type, c_type_member, obj_type, objp) \ OBJECT_IS_TYPE(objp, obj_type) ? OBJECT_CAST(c_type, c_type_member, (objp)) : NULL #define OBJECT_IS_TYPE(obj, type_ptr) \ ((obj)->ob_type == (type_ptr)) struct object; struct object_attrib; enum object_type_flags { OBJTYPE_INIT = 0x01u, }; struct object_ops { kern_status_t(*open)(struct object *obj); kern_status_t(*close)(struct object *obj); kern_status_t(*destroy)(struct object *obj); kern_status_t(*query_name)(struct object *obj, char out[OBJECT_NAME_MAX]); kern_status_t(*parse)(struct object *obj, const char *path, struct object **out); kern_status_t(*get_named)(struct object *obj, const char *name, struct object **out); kern_status_t(*get_at)(struct object *obj, size_t at, struct object **out); kern_status_t(*read_attrib)(struct object *obj, struct object_attrib *attrib, char *out, size_t max, size_t *r); kern_status_t(*write_attrib)(struct object *obj, struct object_attrib *attrib, const char *s, size_t len, size_t *r); }; struct object_attrib { char *a_name; struct queue_entry a_list; }; struct object_type { enum object_type_flags ob_flags; char ob_name[32]; unsigned int ob_size; struct vm_cache ob_cache; struct queue_entry ob_list; struct queue ob_attrib; struct object_ops ob_ops; }; struct object { uint32_t ob_magic; struct object_type *ob_type; spin_lock_t ob_lock; unsigned int ob_refcount; unsigned int ob_handles; struct queue ob_attrib; struct queue_entry ob_list; } __aligned(sizeof(long)); extern kern_status_t object_bootstrap(void); extern kern_status_t object_type_register(struct object_type *p); extern kern_status_t object_type_unregister(struct object_type *p); extern struct object_namespace *global_namespace(void); extern struct object_namespace *object_namespace_create(void); extern struct object *ns_header(struct object_namespace *ns); extern kern_status_t object_namespace_get_object(struct object_namespace *ns, const char *path, struct object **out); extern kern_status_t object_publish(struct object_namespace *ns, const char *path, struct object *obj); extern kern_status_t object_unpublish(struct object_namespace *ns, struct object *obj); extern struct object *object_create(struct object_type *type); extern struct object *object_ref(struct object *obj); extern void object_deref(struct object *obj); extern void object_lock(struct object *obj, unsigned long *flags); extern void object_unlock(struct object *obj, unsigned long flags); static inline kern_status_t object_get(const char *path, struct object **out) { return object_namespace_get_object(global_namespace(), path, out); } extern kern_status_t object_get_child_named(struct object *obj, const char *name, struct object **out); extern kern_status_t object_get_child_at(struct object *obj, size_t at, struct object **out); extern kern_status_t object_query_name(struct object *obj, char name[OBJECT_NAME_MAX]); extern struct object *set_create(const char *name); extern kern_status_t set_add_object(struct object *set, struct object *obj); extern kern_status_t set_remove_object(struct object *set, struct object *obj); extern bool object_is_set(struct object *obj); extern void init_set_objects(void); extern void init_global_namespace(void); #ifdef __cplusplus } #endif #endif