stdio.h: 你熟悉的味道

FILE * 背后其实是一个文件描述符

  • 我们可以用 gdb 查看具体的 FILE *
    • 例如 stdout
  • 封装了文件描述符上的系统调用 (fseek, fgetpos, ftell, feof, ...)

vprintf 系列

  • 使用了 stdarg.h 的参数列表
int vfprintf(FILE *stream, const char *format, va_list ap);
int vasprintf(char **ret, const char *format, va_list ap);

popen 和 pclose

我们在游戏修改器中使用了它

  • 一个设计有缺陷的 API
    • Since a pipe is by definition unidirectional, the type argument may specify only reading or writing, not both; the resulting stream is correspondingly read-only or write-only.

高情商 API (现代编程语言)

subprocess.check_output(['cat'],
  input=b'Hello World', stderr=subprocess.STDOUT)
let dir_checksum = {
  Exec::shell("find . -type f")
    | Exec::cmd("sort") | Exec::cmd("sha1sum")
}.capture()?.stdout_str();

err, error, perror

所有 API 都可能失败

$ gcc nonexist.c
gcc: error: nonexist.c: No such file or directory

这个 “No such file or directory” 似乎见得有点多?

  • cat nonexist.c, wc nonexist.c 都是同样的 error message
  • 这不是巧合!
    • 我们也可以 “山寨” 出同样的效果
    • warn("%s", fname); (观察 strace)
      • err 可以额外退出程序
  • errno 是进程共享还是线程独享?
    • 这下知道协程的轻量了吧

environ (7)

我们也可以实现自己的 env.c

  • 问题来了:environ 是谁赋值的?
    • 是时候请出我们的老朋友 watch point 了
  • RTFM: System V ABI
    • p33
    • Figure 3.9 Initial Process Stack