APUE笔记-信号

2013-05-01 17:18:39

Session leader终止时产生SIGHUP,发送给所有前台进程。由于daemon没有控制终端, 通常不会收到这一信号,因此SIGHUP常用于通知daemon读取更新的配置文件。

向读端终止的管道,或向连接已断开的SOCK_STREAM类型的socket写数据将产生SIGPIPE

后台进程读终端将产生SIGTTIN。若读进程忽略或屏蔽SIGTTIN,或读进程所在组是孤儿组, 则不产生SIGTTIN,读操作返回EIO

不允许后台进程写终端时,后台进程对终端的写操作将产生SIGTTOU。 若写进程忽略或屏蔽SIGTTOU,或写进程所在组是孤儿组,则写操作返回EIO

exec将所有信号捕获重置为默认动作,其余未捕获信号不变(exec之后, caller的内存布局已无意义)。

Reentrant functions。包含资源分配(如malloc)、操作全局数据结构(如getpwnam)等动作的函数在信号发生时可能出现问题。 大多数标准I/O库中的函数因使用了全局数据结构而成为nonreentrant。但即使是reentrant,也要注意在signal handler里保存和恢复每个线程的errno

Unreliable signals的缺点:a.信号产生后,处理动作会被重置为默认动作; b.只能捕获或者忽略信号。这两点会造成信号丢失:信号在某个控制之外的时刻产生了,但程序处理不到。 为了保证语义正确,不依赖于具体实现,请用sigaction

Reliable signal。触发信号的事件发生时,信号被generated。 一个信号产生之后,kernel在进程表中设置一个标记。信号处理动作发生时,信号被delivered。 这之间信号被pending。

若信号按默认动作处理,或被捕获,则除非进程unblock信号,或者将信号处理动作改为ignore, 否则信号一直被pending。

若系统多次deliver一个信号,则称该信号被queued。大多数UNIX系统,除非支持POSIX.1的real-time extension, 都不会排队信号,只会deliver一次。POSIX.1也没有指明信号deliver给进程的顺序。

阅读全文 →

APUE笔记-进程关系

2013-03-15 16:07:26

终端登录

使用sysvinit时,init对每个每个终端设备forkexec一个getty程序。 getty调用open以读写方式打开终端设备,将描述符0、1、2连接到打开的终端设备。 getty打印出输入用户名的提示符,等待用户输入。

输入用户名后,getty通过exec调用login程序,传入一个初始的环境供login使用。 login根据输入的用户名,调用getpwnam函数,获取相应用户的passwd结构。 login调用getpass函数,显示输入密码的提示符,读取用户输入。 用户输入的密码由crypt函数加密,并与登录用户passwd结构中pw_passwd成员比较以验证密码是否正确。 若连续若干次登录错误,login调用exit退出。init获知其退出后,重新forkexec一个getty程序。

若登录正确,login

  • 调用chdir修改用户的home目录
  • 调用chown修改终端设备的拥有者
  • 修改终端设备的读写权限
  • 调用initgroupssetgid设置用户的gid
  • 初始化环境,如HOMESHELLUSERPATH
  • 调用setuid修改用户的uid
  • 调用exec启动shell

此时shell的描述符0、1、2均连到终端设备,shell读取其配置文件并执行一些初始化操作。

阅读全文 →

APUE笔记-进程控制

2013-03-11 10:25:01

进程创建

fork创建子进程。父子进程共享text段,但子进程拥有自己独立的堆、栈、数据段等内存区域。 实际系统中常利用copy on write来推迟和减少内存区域的复制。

子进程继承父进程的:

  • ruid, euid, rgid, egid
  • supplimentary gids
  • 进程组id
  • 会话id
  • 控制终端
  • suid和sgid标记
  • 当前工作目录(cwd)
  • 根目录
  • umask
  • 信号屏蔽和配置
  • 已打开的描述符的FD_CLOEXEC标记
  • 环境
  • 共享内存段
  • 内存映射
  • 资源限制

vfork创建的子进程共享父进程的内存空间,直到其调用execexit, 并保证子进程先运行,直到其调用execexit,通常在vfork后调用exec来spawn一个新的进程。

阅读全文 →

APUE笔记-进程环境

2013-03-06 10:43:05

程序执行和退出

Loader先于main执行,退出时调用exit, 以相反顺序调用atexit注册的exit handlers, 并进行一些清理工作(flush缓冲的写,fclose文件流,删除临时文件等)。 _exit_Exit直接将控制返回给内核,清理工作是否进行依赖于实现。

mainreturn不带返回值,或者main没有被定义为返回整数,则进程退出状态不确定。 C99中,若main被定义为返回整数,但没有return或调用exit,则返回值为0。

atexit可注册的exit hander数量受ATEXIT_MAX控制。POSIX.1规定,若调用了exec, 则之前注册的exit handler将被清除。

环境变量

环境指针extern char **environ,指向环境列表,其中每个指针指向一个name=value形式的环境字符串。 这些字符串通常被保存在进程地址空间中栈以上的区域。 getenvputenvsetenvunsetenv用于操作环境列表。 当需要增加环境变量时,若原有空间不够,则调用malloc为新串分配堆空间,并mallocrealloc一个新的环境列表, 将原有的列表复制到新列表中,更新environ指针指向堆上的新列表。realloc可能导致数据复制,小心指针失效。

非局部跳转

manpage说

The stack context will be invalidate if the function which called setjmp returns.

另外,longjmp后是否恢复栈上auto变量的值取决于实现和优化。 将变量声明为volatile将使其保留longjmp前最后一次更新的值。

进程资源限制

soft limit为当前限制,hard limit是对soft limit的限制,即soft limit可调节的最大值。 在hard limit范围内调节soft limit,或降低hard limit不需要超级用户权限。上调hard limit需超级用户权限。

setrlimit设置的资源限制将影响调用进程和所有子进程。

阅读全文 →

APUE笔记-系统数据文件

2013-03-04 13:44:09

密码文件

读取/etc/passwd中的信息:

  • 获取某个uid的账户信息getpwuidls调用)
  • 获取某个用户名对应的账户信息getpwnamlogin调用)

getpwent遍历所有/etc/passwd中的条目,一次返回一个struct passwd *,不保证顺序。 setpwent打开密码文件,重置到文件开头。endpwent关闭文件。

为保护加密的用户密码,防止“猜密码->加密->比较”形式的攻击,系统将加密密码保存在/etc/shadow,权限为rw-------。 使用getspnam获取一个struct spwd *getspentsetspentendspent以类似方式遍历shadow password文件。

组文件

遍历/etc/groupgetgrentsetgrentendgrent

每个组可设置组密码(gpasswd命令),用newgrp命令可切换当前用户的egid(id命令可查看)。

Supplementary GID

NGROUPS_MAX变量限制一个用户最多可加入的组数,通常为16。

getgroups获取当前用户加入的所有组的gid。

initgroups遍历/etc/group找出某个用户加入的组,并调用setgroups设置该用户的组列表。

阅读全文 →

APUE笔记-标准IO库

2013-01-18 17:00:42

标准I/O库(以下简写为stdio)屏蔽底层细节,如缓冲管理、选择最佳的I/O chunk size等等。

流和FILE

用stdio函数打开或创建一个文件称为"associate a stream with the file", 表示为FILE结构,其中封装了fd、文件指针、buffer指针、error flag、buffer大小等成员。

流可按其orientation区分为byte-oriented和wide-oriented, 即用单个字符还是宽字符来表示流数据。规则如下:

  • when a stream is created, it has no orientation
  • if a multibyte I/O function is used on a stream without orientation, it's set to wide-oriented
  • if a byte I/O function is used on a stream without orientation, it's set to byte-oriented

fwide函数可设置或查询一个流的orientation。

Stdio

各种函数

  • 打开流
    • fopen, freopen, fdopen
  • Character-at-a-time I/O
    • getc, getchar, fgetc, ungetc
    • putc, putchar, fputc
    • 注意getcputc可能被实现为宏,所以要避免参数的副作用
  • Line-at-a-time I/O
    • fgets, gets
    • fputs, puts
  • Direct (binary) I/O
    • fread
    • fwrite
  • 格式化
    • printfscanf家族
  • 定位
    • ftell, rewind, fseek, fgetpos, fsetpos
  • 临时文件
    • 文件名:tmpnam, tempnam
    • 文件:tmpfile(打开方式为wb+fclose或进程终止时被清除), mkstemp(返回fd,文件可读写,不自动清除)
  • Misc
    • ferror, feof, clearerr, fileno

阅读全文 →

APUE笔记-文件与目录

2013-01-09 14:50:23

文件系统的概念结构

层次关系

    disk            -> partition
    partition       -> boot block 
                       super block 
                       cylinder groups
    cylinder groups -> super block copy
                       cylinder group info
                       inode map
                       block bitmap
                       inodes
                       data blocks

inodes和data blocks

每个目录和文件用一个inode记录其元信息。inode保存了指向文件data block或目录directory block的指针。 文件的data block包含其实际数据,目录directory block包含一系列directory entry, 每个entry记录了该目录下文件的inode号(ino_t)和文件名。

由于inode号指定了同一文件系统中的inode,所以硬链接不可跨越文件系统。

同一文件系统中mv文件只需要unlink旧的directory entry并创建一个新的,无需移动文件数据。

阅读全文 →

新年快乐2013

2012-12-31 15:47:16

2012年终于过了!!!再不写总结就不幸福了!!!

毕业这个恼人的问题终于解决了。五六月份的时候想了一个比较冷门的点子,随便做了点实验, 扔出去一篇论文竟然中了个Rank C的世博会。其实文章很水,中的原因主要是因为点子太冷,很少被人提及, 于是也就显出一点微弱得可怜的新意了。借此机会去美帝游荡了一趟,也算是开了下眼界。

有了篇还算说得过去的论文,也就不怕答辩的时候被人找茬了。 我毕设论文用了LaTeX排版,模板是史上流传下来的,实验室上一届有师兄就是用的这个模板。 学校的毕设论文交上去首先要进行形式审查,也就是学校/学院找来一帮人, 翻看每个人的论文,标出所有他们觉得格式有问题的地方, 再发下去让你改。审查那两天我正好在美帝,天天半夜收到北京同学的短信通知近况, 一大早就得起来改。带着困意改论文其实问题不大,关键是他们让改的地方着实令人哭笑不得。 有一条意见是说我论文目录中章节标题和页码之间的点太大。 其实我想一下用word的同学们就平衡了,光是引用编号和参考文献就已经能让他们头疼了……

找工作也是今年的大事之一。我给自己列的想去的地方只有两个,豆瓣和淘宝,方向是偏后台的研发。 喜欢豆瓣是因为它的产品、技术风格、氛围和公司文化;喜欢淘宝是因为它们的平台优势和技术实力。 那段时间总共投了大概十份简历,但大都因为口味的原因翘掉了。 到最后我花时间准备了的公司都挂了,拿到offer的笔试面试都是没怎么准备、临场发挥的结果。

阅读全文 →

Austin

2012-12-30 09:24:18

我还是决定把这次行程记录在这儿。如果不用文字把记忆固定下来,这些零星的场景必将在时间里慢慢消退, 最后只剩下干枯的轮廓,苍白无色、冷若冰霜。

因为12月中旬有硕士毕业答辩,要赶着回来忙相关的事情,所以这次去Austin开会讲论文,行程是很紧张的, 除了参会之外基本上就没有太多时间到处游荡了。来回的机票都是Delta Airlines的, 去的时候航班很折腾人,先从北京到Seatle,再转去Minneapolis,最后才到Austin,路上一共差不多18个小时。 不过毕竟是第一次出国,心里还是很激动的,这点旅途劳累也就算不上什么了。

从北京到Seatle的航班上大都还是中国人,其中有不少是出国看望孩子的父母。 好像这种国际航线旅客都不太多,最后我旁边的两个座位都是空的,整个机舱里也有不少空座位。 因为是向东的飞行,当机舱逐渐被黄昏和黑夜包围时,真有一种时间加快了的感觉。我想着后面还有两趟航班, 为了保存点体力,也顺便调整下时差,飞机上大多数时间里我都在睡觉。 其间空乘发来了传说中的I-94表格和海关报关表让填写,之前从网上查过攻略,很快就搞定了。 期望从飞机上看到太平洋的想法果然是不现实的。四周一片漆黑,只能看见飞机下厚厚的云层, 像是覆雪的丘陵起起伏伏,蔓延到黑暗的边缘。

阅读全文 →

摘译-通向蜘蛛巢的小径

2012-12-28 21:47:59
阅读经验和生活经验不是两个分裂的世界,而是一个整体的世界,每种生活经验, 一旦需要得到适当的诠释,就必然会依赖你的阅读经验,然后再融入其中。(P14)

……世上没有比干坏事更痛苦了。我小时候有一天关在房间里两天不吃饭, 我非常痛苦,但还是不开门,最后他们用梯子从窗户进来领我。我非常希望 被人同情。(P123)

——以上摘自伊塔罗·卡尔维诺《通向蜘蛛巢的小径》

第九章写到吉姆政委和费列拉司令关于战争的理解,还有政委的独白,翻译比较混乱, 有些地方不知所云,所以还是自己找个英文版来练习翻译吧,虽然我自己翻译得也很乱……

有些句子翻译起来还是很有难度的,例如:

It comes from the squalor of their lives, the filth of their homes, the obscenities they've known ever since babyhood, the strain of having to be bad.

这里的strain本来是应力、世系、气质的意思,我翻译成了“本性”,但我觉得有点不准确, 因为这个strain应该不是指他们(参加革命斗争的社会边缘人士)与生俱来的某种性格特质。 结合前几句来看,我觉得指的是一种其生存和成长环境给他们造成的带有强制性的外力。 但是不太容易找到一个中文里对应的词,来保证跟前面几句格式一致。

又如后文中的“lost gesture”,gesture表示手势、姿势、态度等含义,我觉得在文中应该是指 一种立场,指参与战争(包括敌我双方)的所有人抱持的对战争的看法。原书的翻译是“行为”, 那么什么叫做“失去的行为”呢?有点莫名其妙……

阅读全文 →