QNX相关历史文章:
Extending the POSIX-Layer Data Structures
这篇文章主要描述如何扩展POSIX-Layer的数据结构。
1. Overview
如果使用默认的数据结构,不能满足需求时,可以对它进行扩展,需要把默认的结构包含在一个另外一个结构中,并且默认的成员放置在新定义结构的开始部分:
2. Extending the OCB and attribute structures
在实际的使用过程中,我们可能需要扩展iofunc_attr_t
和iofunc_ocb_t
结构,直接来看一个例子:
/* Define our overrides before including <sys/iofunc.h> */
struct device;
#define IOFUNC_ATTR_T struct device /* see note 1 */
struct ocb;
#define IOFUNC_OCB_T struct ocb /* see note 1 */
#include <sys/iofunc.h>
#include <sys/dispatch.h>
struct ocb { /* see note 2 */
iofunc_ocb_t hdr; /* see note 4; must always be first */
struct ocb *next;
struct ocb **prev; /* see note 3 */
};
struct device { /* see note 2 */
iofunc_attr_t attr; /* must always be first */
struct ocb *list; /* waiting for write */
};
/* Prototypes, needed since we refer to them a few lines down */
struct ocb *ocb_calloc (resmgr_context_t *ctp, struct device *device);
void ocb_free (struct ocb *ocb);
iofunc_funcs_t ocb_funcs = { /* our ocb allocating & freeing functions */
_IOFUNC_NFUNCS,
ocb_calloc,
ocb_free
};
/* The mount structure. We have only one, so we statically declare it */
iofunc_mount_t mountpoint = { 0, 0, 0, 0, &ocb_funcs };
/* One struct device per attached name (there's only one name in this
example) */
struct device deviceattr;
main()
{
...
/*
* deviceattr will indirectly contain the addresses
* of the OCB allocating and freeing functions
*/
deviceattr.attr.mount = &mountpoint;
resmgr_attach (..., &deviceattr);
...
}
/*
* ocb_calloc
*
* The purpose of this is to give us a place to allocate our own OCB.
* It is called as a result of the open being done
* (e.g. iofunc_open_default causes it to be called). We
* registered it through the mount structure.
*/
IOFUNC_OCB_T
ocb_calloc (resmgr_context_t *ctp, IOFUNC_ATTR_T *device)
{
struct ocb *ocb;
if (!(ocb = calloc (1, sizeof (*ocb)))) {
return 0;
}
/* see note 3 */
ocb -> prev = &device -> list;
if (ocb -> next = device -> list) {
device -> list -> prev = &ocb -> next;
}
device -> list = ocb;
return (ocb);
}
/*
* ocb_free
*
* The purpose of this is to give us a place to free our OCB.
* It is called as a result of the close being done
* (e.g. iofunc_close_ocb_default causes it to be called). We
* registered it through the mount structure.
*/
void
ocb_free (IOFUNC_OCB_T *ocb)
{
/* see note 3 */
if (*ocb -> prev = ocb -> next) {
ocb -> next -> prev = ocb -> prev;
}
free (ocb);
}
- note 1
在包含标准I/O函数头文件之前,放置了结构的定义,这样在I/O函数中使用到这些宏定义的时候,可以方便的进行结构的覆盖; - note 2
定义新的数据结构,确保原有的放置在头部; - note 3
ocb_calloc()
和ocb_free()
示例函数,将新创建的ocb
维护在一个列表中; - note 4
必须始终把将iofunc
结构作为新扩展结构的第一个成员,这能确保公共库在默认情况下能正常工作;
3. Extending the mount structure
iofunc_mount_t
的扩展方式,与上述结构是一样的,比如:
#define IOFUNC_MOUNT_T struct newmount
/* then add statements */
struct newmount {
iofunc_mount_t mount;
int ourflag;
};