cha40.登录记账
40-1 40-4
实现getlogin0。在40.5节中曾提到过当进程运行在一些软件终端模拟器下时getlogin0可能无法正确工作,在那种情况下就在虚拟控制台中进行测试。
实现一个简单的who(1)。
1 | // |
40-2 40-3
- 修改程序清单40-3中的程序(utmpx loginc)使它除了更新utmp和wtmp文件之外还更新lastlog文件。
- 阅读login(3)、logout(3)以及logwtmp(3)的手册。实现这些函数
1 | // |
实现getlogin0。在40.5节中曾提到过当进程运行在一些软件终端模拟器下时getlogin0可能无法正确工作,在那种情况下就在虚拟控制台中进行测试。
实现一个简单的who(1)。
1 | // |
1 | // |
| 类型 | 解释 |
|---|---|
| 许可集 | 进程可使用的能力,删除一个能力是不可逆的 |
| 有效集 | 进程当前能使用的能力 |
| 可继承集 | exec之后,可以继承、进入许可集的能力集(规定被exec的文件可以继承哪些能力) |
| 类型 | 解释 |
|---|---|
| 许可集 | exec时添加到进程的许可集 |
| 有效集 | 1位,关闭,则exec后进程有效集为空;开启,exec后有效集为许可集 |
| 可继承集 | 文件可继承集与进程可继承集相交后,作为exec后可被继承、进入许可集的能力集合(规定被exec的文件可以继承哪些能力) |
用一个普通的非特权用户登录系统,创建一个可执行文件(或复制一个既有文件如/bin/sleep),然后启用该文件的set-user-ID权限位(chmod u+s)。尝试修改这个文件(如cat >>fle)。当使用(ls -l)时文件的权限会发生什么情况呢?为何会发生这种情况?
现象:saved-user-id不见了
原因:通过下面的例子,猜测open时会清除set-usr-id标志位
1 | // |
编写一个与 sudo(8)程序类似的 set-user-ID-root 程序。这个程序应该像下面这样接收命令行选项和参数:
编写一个使用syslog(3)的程序(与logger(1)类似)来将任意的消息写入到系统日志
文件中。程序应该接收包含如记录到日志中的消息的命令行参数,同时应该允许指
定消息的level。
1 | // |
不及丢为什么,syslog.conf中配置的东西打印不出来
2023年8月23日更新
wsl下syslog确实不行,换一个环境,安装syslog后,重新允许,可以正常打印log
编写一个程序使用getrusage0 RUSAGE CHILDREN标记获取wait调用所等待的
子进程相关的信息。(让程序创建一个子进程并使子进程消耗一些 CPU 时间,接着
让父进程在调用wait0前后都调用getrusage0。
1 | // |
编写一个程序来执行一个命令,接着显示其当前的资源使用。这个程序与 time(1)
命令的功能类似,因此可以像下面这样使用这个程序:
1 | $ ./rusage command arg... |
nice值形象的说是一个进程的友好(nice)程度,越nice(nice值数值越大的)的进程越礼让,多个任务争用cpu的时候越礼让。(本书中高nice值表示nice值数值更低,更不nice
资源限制,特权进程最高可以将nice值提升到20-RLIMIT_NICE
假设一个父进程执行了下面的步骤。
这个应用程序设计可能会碰到什么问题?考虑 shell 管道。
如何避免此类问题的发生?
1 |
|
SIGUSER1child-%d: %d被重复输出了多次,这是由于stdout被重定向后变成了全缓冲,fork的子进程退出后fflush()时会将fork前未flush的数据打印出来。./practice34.1 | cat,输出会是User defined signal 1,即cat与程序同属一个进程组,cat也会收到该信号,导致无法正常执行(非预期内)编写程序以便证明:作为函数sigpending()的返回值,同一个进程中的的不同线程可以拥有不同的 pending信号。可以使用函数pthread_kill(分别发送不同的信号给阻塞这些信号的两个不同的线程,接着调用sigpending()方法并显示这些pending信号的信息。(可能会发现程序清单20-4中函数的作用。)
1 | // |
假设一个线程使用fork()创建了一个子进程。当子进程终止时,可以保证由此产生的SIGCHLD信号一定会发送给调用fork()的线程吗(可以用进程中的其他线程做对比)?
1 | // |
从作用域的角度上看,带参宏和函数的区别:
pthread_cleanup_push和pthread_cleanup_pop,很多实现都是使用带参宏,那么这两个宏调用时必须属于同一个代码块?,保证push的作用域包含pop不就好了吗
线程取消状态可设置为启用和禁用。
pthread_once(pthread_once_t*, void (*)(void));int pthread_key_create(pthread_key_t *, void (*)(void *));每个线程都存储一份,第一个参数为一个全局变量的指针,第二个参数为线程终止时自动调用的析构函数int pthread_setspecific(pthread_key_t, const void *)指定key所对应的内存区域,进程终止时会将第二个参数送入析构函数void * pthread_getspecific(pthread_key_t)获取key所对应的内存区域实现pthread_once
1 | // |