从main.c中main函数开始

728阅读 0评论2010-06-29 toughie
分类:LINUX

从main.c中main函数开始,这里有几个结构需要注意一下:

svalue_t: 定义LPC中数据类型,其中使用了union u,该unixon结构则为lpc中
的所有数据类型,int, char*, float, object_s, array_s, mapping_s,
funptr_s, svalue_s, ref_s, 或者是错误处理函数指针(callback function),
其中有指代全部的类型refed_t。

refed_t:目前认为是一个地址,或者是一个id

buffer_s:指向一块buffer的数据结构,纪录其ref值和大小,ref的用途是内存
释放,因为lpc不提供free函数,所有的内存由内存管理单元管理,当ref为0时
可以释放。

object_s:LPC中的对象数据类型,

interactive_s:

sentence_t:初步猜想next为指向下一个句子的指针,而ob为该语句所对应的对
象,而function为该句所要执行的函数或者字符串。

userid_t:char*,应该是对应的用户的名字。

statgroup_t:里面为两个同为mudlib_stats_t*的域,domain和author。
mudlib_stats_t记录的是mudlib的名称,长度(应该是mudlib名字的长度,不然
好像没有什么用处),moves,heart_beats,size_array,errors,objects等
信息,目前只知道heart_beats为心跳的时间,objects应该记录的时目前object
的个数,size_array记录的是array的个数,其他的暂时还不清楚。

parse_info_s:

program_t:这里面有2个ref,一个是ref,一个是func_ref,第一个不难明白,
第二个不知道为什么要为func添加ref。域program为编译好的bytecode在内存中
的地址?function_table记录的是函数列表?

class_def_t:记录class的信息

class_memeber_entry_t:记录class的member function。这里注意一点,每个
class定义在一个文件中,而该class名称为文件名,如player.c则class名称为
player,这和java有点类似。但是lpc中并没有class关键字,所以定义语法与
C++就不相同了。

inherit_t:父类的信息,想像成C++中的虚函数表吧。

init_strings:stralloc:L85,初始化string hash table。

init_otable:otable.c:L34,初始化object hash table

init_identifiers:lex.c:L3389,

init_locals:compiler.c:L99, 初始化locals列表,并置初值为0

driver命令行中的m选项为mudlib的目录,我们在配置config文件的时候,会指
定该目录,当该目录错误的时候,我们会得到“Bad mudlib dirctory: ”(我在
配置mudlib的时候遇到这个问题多次了)

init_binaries:

init_lpc_to_c:compile_file.c:L35,初始化lpc_object。

interface_t:interface.h:L8,

lpc_object_t:object.h:L85,域string_switch_tables用于记录在表中的位置

string_switch_entry_t:cfuns.h:L11, 用于记录string在table中的位置。

猜想lpc_object用于表示类型,而object_t才识才是真正表示的是对象实例,如
class A与A a的关系一样。

add_predefines:

init_master:master.c:L51,从该函数可以看出,每一个.c文件将被comiple为
一个object,这与上面object_t的定义相符。

接下来的工作便是初始化signal函数了,初始化完成之后进入backend函数。

backend:backend.c:L85,初始化完成,打印“accepting connections on
port:%d”,此时服务启动成功。调用init_user_conn,初始化用户连接(登录)。
然后注册SIGHUP signal函数,当然是shutdown mudos了。clear_state就是把所
有的计数器清零:)。接下来则是死循环了,当然,所有的逻辑则在这里面处理了。
当监测到有io请求时,则调用process_io函数(处理读去和写入操作)。接下来
则是进行出来用户操作的函数:process_user_command。

init_user_conn:comm.c:L152,初始化socket(这里fd6不知道是何东东)

make_selectmasks:comm.c:L1340,置fd_set的readmask列表何writemasks列表。

process_io:comm.c:L1390,由于external_port的前面5个fd为监听端口,所以
检测是否激活,如若激活,则调用new_user_handler。然后检测无效连接,并从
列表中清除。如果fd_set激活,则说明有消息需要处理,这里需要注意的两个函
数:socket_read_select_handler和socket_write_select_handler

process_user_command:comm.c:L1744,

get_user_command:comm.c:L1631,

main函数流程基本上就是这样。这其中有个问题:为什么很多函数查找不到呢?
先分析一下mudlib的config文件和master.c文件。

-------------------->

config文件,以lima mudlib为例:

name:mudlib的名字,将与全局变量MUD_NAME对应

port number:server默认端口,我们要连接的端口

address server ip:一般情况下都用localhost了

address server port:现在不明白address_server的用途是什么,从解释来看,不
知道是把什么名字与number对应,但是文档上说又不同于dns,不知道什么用了。
至此端口用来干什么也不清楚:(

mudlib directory:与全局变量mud_lib对应

binary directory:driver的路径

全局定义函数:global.h

-------------------->

gdb main 跟踪

main中进入rc.c:L150的set_defaults函数,而该函数调用config_init函数
(rc.c:L30),初始化config列表之后;读取config(read_config_file at
rc.c:42),进入scan_config_line(rc.c:92)

save_contex(interpret.c:5589):

$Id$

上一篇:MUD中安全谈
下一篇:《config文件篇》