#include #include #include #include #define TEST_CAST(p) OBJECT_C_CAST(struct test_object, base, &test_type, p) struct test_object { struct object base; char name[OBJECT_NAME_MAX]; }; static struct object_type test_type; static kern_status_t test_query_name(struct object *obj, char out[OBJECT_NAME_MAX]) { struct test_object *test = TEST_CAST(obj); strncpy(out, test->name, OBJECT_NAME_MAX); out[OBJECT_NAME_MAX - 1] = 0; return KERN_OK; } static struct object_type test_type = { .ob_name = "test", .ob_size = sizeof(struct test_object), .ob_ops = { .query_name = test_query_name, }, }; static void print_object_tree(struct object *obj, int depth) { char msg[256] = {0}; int len = 0; for (int i = 0; i < depth; i++) { len += snprintf(msg + len, sizeof msg - len, " "); } char name[OBJECT_NAME_MAX]; object_query_name(obj, name); len += snprintf(msg + len, sizeof msg - len, "%s", name); printk(msg); struct object *child = NULL; size_t i = 0; while (1) { kern_status_t status = object_get_child_at(obj, i, &child); if (status != KERN_OK) { break; } print_object_tree(child, depth + 1); object_unref(child); i++; } } static int run_obj_tests(void) { object_type_register(&test_type); struct object *test_obj = object_create(&test_type); struct test_object *test = TEST_CAST(test_obj); snprintf(test->name, sizeof test->name, "object1"); kern_status_t status = object_publish(global_namespace(), "/misc/objects", test_obj); if (status == KERN_OK) { printk("published object at /misc/objects/object1"); } else { printk("publish failed"); return -1; } if (object_publish(global_namespace(), "/misc/objects/object1", test_obj) == KERN_OK) { printk("second publish succeeded but shouldn't have"); return -1; } print_object_tree(ns_header(global_namespace()), 0); return 0; } test_initcall(run_obj_tests);