linux内核代码中我们会经常遇到如下的定义:
1
2
3
| #define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0) |
上面的写法,可以很安全的将下面的语句,用一个宏来代替,考虑到了很多特殊的情况。 比如
1
2
3
4
| if (doit)
INIT_LIST_HEAD(x);
else
displayError(x); |
这里如果我把宏定义的代码写成如下,在上面的if应用中就会暴露出问题。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| #define INIT_LIST_HEAD(ptr) (ptr)->next = (ptr); (ptr)->prev = (ptr);
//问题如下:
if (doit)
(ptr)->next = (ptr);
(ptr)->prev = (ptr); //两条语句,导致if语句范围出错
else
displayError(x);
//或者
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
}
//问题如下:
if (doit) {
(ptr)->next = (ptr);
(ptr)->prev = (ptr); };//多一个分号,表示一条语句,导致if语句范围出错
else
displayError(x); |
如果需要将多条语句,封装成宏的形式,可以使用这种do while的方式。
C/C++, PHP, 读书 C语言, linux, 宏
在家休了四天,有大量的时间来睡觉,睡的很爽。期间欢仔还过来玩了半天,我施展了下我的厨艺,做了几个菜,还不错。省下的时间收拾住的地方,洗衣服,看电影,帮惠菊弄了点东西,就没干其它的了。期间也想了很多,马上23岁,一点都没觉自己那点成熟。还跟个孩子一样,小时候的玩伴,大部分都结婚了,有的都快当爹了,一点都不感想象,连自己都养不活,怎么养活孩子。感觉自己的处境也很尴尬,在北京这个人才聚集,物欲横飞的大都市,自己从一个二流本科院校来到这里,没有很大的竞争力,每天都要挤地铁上班,挤地铁下班,每天上下班时间将近三个小时,毫无幸福感可言。虽然比唐家岭的蚁族要好一些,但是觉得自己也好不到那去。昨天估算了下,十一想换一个近一点的地方住,想给老妹买电脑,想换两部手机,过年又想有点结余,不想空手回家。看着比我大两岁的张宴、杨远骋同学,自己鸭梨很大呀,所以现在必须要改变。
杂记 休假, 工作
网上找不到完整的中文版,于是就自己把RFC文档翻译了一遍,有错误欢迎指正,转载请注明出处!下面正文。
Post Office Protocol - Version 3
1、 简介
对于互联网上较小的节点,维护一个信息传送系统(MTS)是不大现实的。例如,一个工作站没有足够的资源(时间,磁盘空间)使一个SMTP服务器[RFC821]和关联的本地邮件投递系统驻留和连续运行。类似地,把一台个人电脑长时间连接在IP网络上是昂贵的说着不现实的(资源受限的节点称为”连通性”)。
尽管如此,在小节点上收发邮件是非常有用的,所以经常架设一个用户代理(UA)来帮助处理邮件任务。为了解决这个问题,我们在MTS实体上为资源受限的节点提供了邮筒功能。邮局协议-版本3(POP3)允许工作站以一种比较实用的方式来访问服务器邮筒。通常,这意味着POP3协议支持工作站去服务器检索服务器上为本工作站存储的邮件。
POP3未打算提供大量服务器上的邮件操作;一般,邮件被下载后即被删除。一个更为先进和复杂的协议,IMAP4,正在设计中[RFC1730]。
在下文中,客户主机指使用POP3服务的主机,服务器主机指提供POP3服务的主机。
阅读全文…
网络与安全 POP3, RFC1939, 邮件协议
前几天晚上和同事吃饭的时候,有一个经理就不禁感慨,自己读书太多了,后悔阿,应该早点踏入社会工作,读那么多的书,真正可以在工作中用到的谋生的技能并不多。他是我们的高级经理,一直读到博士,才出来工作。有时候就想做IT的,到底出来,小富即安容易,但是想到进入中产或者更高一点,难阿,至少我现在看到的现象是这样的。有时候真的有点看不到方向,不知道自己做的工作有什么意义,单纯的自我满足?
进入工作,发现与人沟通的成本真的很高,高到别人不想跟你合作,自己在这点上也有很多的欠缺,需要学习阿。刚进入工作,自己很想将自己的工作做好,但是毕竟没有经验,很多的时候会出一些错误,但是人不是神,孰能无过。我最懊恼的地方不是我犯错误,而是我该怎样去看待自己的所犯的这些错误。出错了,责任在自己,要主动承认错误,改正错误;但是承认错误改正错误的方法也是一种艺术阿!
杂记 学习, 工作, 沟通, 生活
最近在读《你的灯还亮着吗》,有一句话让我很有感触,“人们总是没有时间把一件事情做好,但是总有时间去后悔或者把这件事情重新做一遍”。确实,我很多的时候也是这样,做什么事情都匆匆忙忙,急急忙忙的想把事情尽快的做完,总是在慌,怕自己浪费时间,怕自己赶不上进度。总是没能静下心来,仔细想想怎么把事情做好。事情没能成功的完成之后,又得很懊悔的重来一遍。就像我平时读一本书,匆匆读完,毫无收获,毫无见解,怎么办,重读,浪费生命。
对于治学,真是“非宁静无以致远”。只有真的静下心来,学会思考,学会掌控方向,这样才能快速的奔跑。做什么事情都没有捷径,唯一需要的就是一颗宁静而又有耐心的心。
“古之所谓豪杰之士者,必有过人之节,人情有所不能忍者。匹夫见辱,拔剑而起,挺身而斗,此不足为勇也。天下有大勇者,卒然临之而不惊,无故加之而不怒,此其所挟持者甚大,而其志甚远也。”
杂记 学习, 态度
系统从我们按下计算机的电源键到机器可以使用,执行流程如下:
power on–>BIOS–>Grub–>Kernerl boot–>init(rc.sysinit, rc)–>mingetty(login)–>Shell—->
Init进程进程号为1,是linux内核引导完之后运行的第一个进程,init进程运行初会去读取配置文件/etc/inittab。Inittab是一个不可执行的文本文件,由若干指令组成。这里总结一下init进程开始的系统脚本执行顺序,以及各个脚本的含义。
脚本/etc/inittab中所有的记录都以以下的格式呈现:
id:runlevel:action:process
id是入口标示符号,为一个字符串,对于getty或mingetty等login程序项,要求id与tty的编号相同,否则getty程序将不能正常工作。
runlevel是级别标志,init进程启动时会有一个运行级别,/etc/inittab脚本中和init运行级别匹配的记录会被执行。
Action表述后面的process的运行方式。action的取值包括initdefault、sysinit、boot 、bootwait。
Initdefalut是一个特殊的action值,用于标示缺省的启动级别。当init进程启动后会去读取initdefault的值,如果没有此值,则会在控制台请求用户输入runlevel值。
Process为具体的执行程序,程序可以带参数。
脚本中记录的含义:
id:5:initdefault:
用于指定当前的runlevel,5标示运行于界面模式。
si::sysinit:/etc/rc.d/rc.sysinit
此脚本主要用于完成系统初始化工作,它是每一个级别都要首先运行的重要脚本。rc.sysinit程序执行完后,将返回init继续执行。
l2:2:wait:/etc/rc.d/rc2
各守护进程的启动,rc2为一个shell脚本,在rc2中回去循环执行/etc/rc.d/rc2.d目录下的所有脚本,这些脚本一般都是符号链接,链接到别的位置文件,这些脚本一般都会接受start、stop、restart、status等参数。
1:2345:respawn:/sbin/getty 38400 tty1
用于启动终端
OS inittab, linux, 系统, 脚本
机遇
人们总说机遇总是留给有准备的人,但是并不是人人都在准备,当人们没有抓住某个自以为是机会的机遇的时候,总是在内心里给自己一个宽慰的理由,自己没有准备好!但是面对未来的机遇自己该准备些什么的,我感觉什么都不需要准备,简单的把自己想做的事情和该做的事情做好,这就已经很好了,很不容易了。
运气、选择
人生就想赌博一样,每天自己都在选择,都在押注,是买巴西赢还是买荷兰赢。今年世界杯买荷兰赢的人应该是赚翻了,他们的运气真的是太好了,但是他们毕竟是少数人,大多数理性的人就算历史可以重演还是会买巴西赢的,这就是大多数人的选择,不要在这样的事情上迷恋那些少数人。
这几天同学们相继的都签约了,谁签了一家有前景的公司,谁做了一份不错的工作,成为了刚毕业的同学们的必聊内容。很多的同学很羡慕那些签了好公司的同学,说自己也技术也不比他差,比他还努力,自己怎么就这么点背呢!怎么就没有被好的公司给看上呢,很是郁闷。其实我感觉这还是人的主观感觉比较多,对一个刚毕业的大学生来说,只要一个不是业界倒数的公司,都是可以学到东西的,而且是和别人不一样的东西,试着去发现自己公司的好,去提高自己的能力比什么都强。既然自己已经选择就不能后悔。要有曹操的那份自信,自己说的话、做的事、做出的决定那就是自己的选择,那就是对的!送给刚毕业的同学们!
杂记 思考, 机遇
人生观是指人们对生活意义的理解和对人生价值的认识,它决定着一个人会追求什么样的人生目标,也决定着一个人的生活态度及其生活方式,还决定着一个人占主导地位的情绪特征和心境。
世界是同一个世界,太阳是同一个太阳,月亮也是同一个月亮,而不同人生观的人眼里看到的,内心感受到的体验却是截然不同的。具有积极人生观的人,内心是充满阳光的,性情是开朗乐观的,生活是丰富多彩的,事业也往往是蒸蒸日上的。具有消极人生观的人,内心是灰色黯淡的,性情是悲天悯人的,生活是味同嚼蜡的,事业也往往是举步维艰的。这正所谓:生活就像一面镜子,你对它笑它就笑,你对它哭它就哭。这一哭一笑之间,起决定作用的是我们对生活的认知评价。
为了让生活对我们微笑,首先就得我们对生活微笑。而要使自己对生活露出由衷的笑颜,有一个办法十分有效,那就是:赋予生活以意义,让生活充实起来。
杂记 工作, 态度, 生活
早上九点到公司,像往常一样打开Google用gmail收邮件,calendar查事物清单。但是一打开首页就觉得不对,我平时指向的一直是google国际版的首页,今天早上一打开怎么是中文版的了,一开始我还以为谁昨天用了我的电脑给我修改了。然后就在首页上看到一句话“欢迎您来到谷歌搜索在中国的新家”,我猜就是goolge要退出中国了。然后马上就上twitter看,满屏都是google退出中国的消息,大家都兴奋的不行,你说一句我说一句。我想google的退出对中国的科研人员来说并不是一件好的事情,因为大多数的科研人员经常检索的是英文资料,而在英文方面百度不是不行而是并没有做,gooogle在这方面一直领先,也不知道从现在百度会怎么想,百度会不会沦落为ZF的工具,不得自拔。google reader、google code、gmail、google calendar、google document等等我经常用的goolge服务不知道能够用到那一天。
杂记 google, 百度, 退出
昨天一直在公司读反垃圾邮件的代码,整个模块包含三部分:1、WEB界面程序 2、命令行解析程序 3、核心检测程序。现在界面程序的代码还没有拿到,昨天就一直在阅读反垃圾邮件的2、3部分的代码,感觉命令行解析程序写的有些繁琐,严重违反了DRY原则,代码里有好多的本可以写为函数的重复语句,会为后期的维护增加困难。
我们的反垃圾命令行终端要解析的输入格式如下:
antispam blackserver add ip comment
antispam blackserver del ip
antispam blackserver {import | export }
antispam blackserver {on | off}
当前使用的方法如果需要增加一个新的命令行的话,需要更改命令行解析程序中的命令行解析函数,然后再去增加相应的一系列的解析函数,很绕很繁琐。
我的想法是使用一个数据结构,使我们可以很简单、很清晰明白的增加新的命令行。下面是写的一个演示的Demo,这样写的话整个命令行解析程序结构会很清晰,我增加一条命令行只需要在解析结构体中加入新的命令行和对应的解析函数就可以。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
| #include <stdio.h>
#include <string.h>
/*
antispam blackserver add ip <ip> comment <comment>
antispam blackserver del ip <ip>
antispam blackserver {import <fromfile>| export <tofile>}
antispam blackserver {on | off}
*/
#define ARGV_MAX 20 /* 最大参数个数 */
int cli_parse(int argc, char *argv[]);
int cli_bs_on(int argc, char *argv[]);
int cli_bs_add_ip(int argc, char *argv[]);
struct parse_struct {
int argc;
int (*func)(int argc, char *argv[]);
char *argv[ARGV_MAX];
} parse_r[] = {
{3, cli_bs_on, {"antispam", "blackserver", "on", NULL}},
{7, cli_bs_add_ip, {"antispam", "blackserver",
"add", "ip", "*", "comment", "*", NULL}},
{0, NULL, {NULL}}
};
int
main(int argc, char *argv[])
{
int ret;
ret = cli_parse(argc, argv);
if (ret != 0)
{
printf("do not prase right\n");
}
return 0;
}
int cli_bs_on(int argc, char *argv[])
{
printf("cli_bs_on\n");
return 0;
}
int cli_bs_add_ip(int argc, char *argv[])
{
printf("cli_bs_add_ip(ip:%s, comment:%s)\n", argv[4], argv[6]);
return 0;
}
int cli_parse(int argc, char *argv[])
{
int i = 0, j = 0;
for (i = 0; 0 != parse_r[i].argc; i++)
{
if (argc == parse_r[i].argc)
{
/* argv[0]可以不一样,只要执行的是本程序即可 */
for (j = 1; NULL != parse_r[i].argv[j]; j++)
{
if (strncmp(argv[j],parse_r[i].argv[j],
strlen(parse_r[i].argv[j])))
{
/* 不相等,看是否为参数 */
if ('*' == parse_r[i].argv[j][0]) {
continue;
}
return -1; /* 不匹配 */
}
}
(*parse_r[i].func)(argc, argv);
return 0;
}
}
return -1;
} |
C/C++ C语言, 命令行, 解析
最新评论