-
在
quagga
中有很多的命令,利用这些下面分析一下命令是怎么被读取和执
行的。在
p>
quagga
中定义的命令都是利用宏定义实现的,这个宏定义还是
有点复
杂,下面是命令的宏定义语句。
#define DEFUN(funcname, cmdname,
cmdstr, helpstr)
DEFUN_CMD_FUNC_DECL(funcname)
DEFUN_CMD_ELEMENT(funcname, cmdname,
cmdstr, helpstr, 0, 0)
DEFUN_CMD_FUNC_TEXT(funcnam
e)
第一个
funcname
是函数的名称,
第二个是注册的命令的名字,
第三个是在
vtysh
终端下输入的命令字符串,第四个是帮助
信息,当输入“
?
”时,显示出来。
#define DEFUN_CMD_FUNC_DECL(funcname)
static int funcname (struct cmd_element
*, struct vty *, int, const char *[]);
#define
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr,
helpstr, attrs,
dnum)
struct
cmd_element cmdname =
{
.string = cmdstr,
.func = funcname,
.doc = helpstr,
.attr = attrs,
.daemon = dnum,
};
#define
DEFUN_CMD_FUNC_TEXT(funcname)
static int
funcname
(struct
cmd_element *self __attribute__ ((unused)),
struct vty *vty
__attribute__ ((unused)),
int argc __attribute__ ((unused)),
const char
*argv[] __attribute__ ((unused)) )
假设我们这里有一个下面宏定义:
DEFUN (vtysh_show_hello,
vtysh_show_hello_cmd,
)
{
printf(
return
CMD_SUCCESS;
}
看一下它是如何展开的:
首先看一下
下面的这个结构体,在宏
DEFUN_CMD_ELEMENT
中使用到。
struct cmd_element
{
const char *string;
/* Command
specification by string. */
int (*func) (struct
cmd_element *, struct vty *, int, const char
*[]);
const char *doc;
/* Documentation of this
command. */
int daemon;
/* Daemon to which this command belong.
*/
vector strvec;
/* Pointing
out each description vector. */
unsigned int
cmdsize;
/* Command index count.
*/
char *config;
/* Configuration string */
vector
subconfig;
/* Sub
configuration string */
u_char attr;
/* Command attributes
*/
};
#define DEFUN(funcname,
cmdname, cmdstr, helpstr)
int funcname (struct cmd_element *,
struct vty *, int, char **);
struct cmd_element cmdname
=
{
cmdstr,
funcname,
helpstr
};
int funcname
(struct cmd_element *self,
struct vty *vty, int argc, char **argv)
还有一个结构
struct vty
应
定义在
vty.h
中。根据宏定义
DE
FUN
,可展开如下:
int
vtysh_show_hello (struct cmd_element *, struct vty
*, int, char **);
struct
cmd_element vtysh_show_hello_cmd =
{
vtysh_show_hello,
};
int vtysh_show_hello (struct
cmd_element *self, struct vty *vty, int argc, char
**argv)
{
printf(
return CMD_SUCCESS;
}
在
vty
_main.c
中,包含有一个
main()
< br>函数,
假设我们定义了一个函数的宏定义,这里摘自<
/p>
quagga
里面。
DEFUN (show_version,
show_version_cmd,
SHOW_STR
{
vty_out (vty,
?:
VTY_NEWLINE);
vty_out (vty,
return CMD_SUCCESS;
}
p>
上面已经分析了这个函数是怎么一步一步展开的,我们在定义一个命令的时候,
也必须要在某一个节点下安装这个命令。使用下面的语句。
在
cmd_init
(
int
terminal
)函数中。
install_node (&view_node,
NULL);
void
install_node
(struct cmd_node *node,
int (*func)
(struct vty *))
{
vector_set_index (cmdvec, node->node,
node);
node->func = func;
node->cmd_vector = vector_init
(VECTOR_MIN_SIZE);
}
Cmdvec
变量在
cmd_init
函数一开始时进行了初始化,
p>
cmdvec = vector_init
(VECTOR_MIN_SIZE);
在
< br>vecto_init
函数中分配了内存,并且返回
ve
ctor
结构。一个命令要在某个结点
下安装。
install_element (VIEW_NODE,
&show_version_cmd);
/*
Install a command into a node.
安装一个命令到一个节点
*/
void
install_element (enum node_type ntype,
struct cmd_element *cmd)
{
struct cmd_node *cnode;
/* cmd_init hasn't been
called */
if (!cmdvec)
return;
cnode = vector_slot (cmdvec,
ntype);
if (cnode ==
NULL)
{
-
-
-
-
-
-
-
-
-
上一篇:照相机教案
下一篇:中英文操作系统 数码显微镜和工业相机驱动应用程序安装使用步骤