常用系统调用

98 阅读4分钟

文件操作

open()

打开文件

int fd = open(file.c_str(), O_RDWR | P_CREAT, (mode_t)0666);
if (fd != -1) {
}

参数2是权限,参数三是模式,类似chmod 777

lseek()

off_t lseek(int fildes, off_t offset, int whence); 控制该文件的读写位置. 参数fildes 为已打开的文件描述词, 参数offset 为根据参数whence来移动读写位置的位移数.

参数 whence 为下列其中一种:

  •     SEEK_SET 参数offset 即为新的读写位置.
  •     SEEK_CUR 以目前的读写位置往后增加offset 个位移量.
  •     SEEK_END 将读写位置指向文件尾后再增加offset 个位移量. 当whence 值为SEEK_CUR 或
  •     SEEK_END 时, 参数offet 允许负值的出现.

下列是教特别的使用方式:

  • 欲将读写位置移到文件开头时:lseek(int fildes, 0, SEEK_SET);
  • 欲将读写位置移到文件尾时:lseek(int fildes, 0, SEEK_END);
  • 想要取得目前文件位置时:lseek(int fildes, 0, SEEK_CUR);

返回值:当调用成功时则返回目前的读写位置, 也就是距离文件开头多少个字节. 若有错误则返回-1, errno 会存放错误代码.

write()

ssize_t write (int fd, const void * buf, size_t count);

#include <unistd.h>
return_code = write(fd, "", 1);
if (return_code == false) {...}

函数说明:write()会把参数buf 所指的内存写入count 个字节到参数fd 所指的文件内. 当然, 文件读写位置也会随之移动.

返回值:如果顺利write()会返回实际写入的字节数. 当有错误发生时则返回-1, 错误代码存入errno 中.

错误代码:

  • EINTR 此调用被信号所中断.
  • EAGAIN 当使用不可阻断I/O 时 (O_NONBLOCK), 若无数据可读取则返回此值
  • EADF 参数fd 非有效的文件描述词, 或该文件已关闭.

flock()

int flock(int fd, int operation);

函数说明:flock()会依参数operation 所指定的方式对参数fd 所指的文件做各种锁定或解除锁定的动作. 此函数只能锁定整个文件, 无法锁定文件的某一区域.

void lock() {
    flock(fd, LOCK_EX);
}
void unlock() {
    flock(fd, LOCK_UN);
}

参数 operation 有下列四种情况:

  1. LOCK_SH 建立共享锁定. 多个进程可同时对同一个文件作共享锁定.
  2. LOCK_EX 建立互斥锁定. 一个文件同时只有一个互斥锁定.
  3. LOCK_UN 解除文件锁定状态.
  4. LOCK_NB 无法建立锁定时, 此操作可不被阻断, 马上返回进程. 通常与LOCK_SH 或LOCK_EX 做OR(|)组合.

返回值:返回 0 表示成功, 若有错误则返回-1, 错误代码存于errno

内存控制

mmap()

void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offsize);

函数说明:mmap()用来将某个文件内容映射到内存中,对该内存区域的存取即是直接对该文件内容的读写

  • example:
mem_ = (char*)mmap(nullptr, total_, PORT_READ|PORT_WRITE, MAP_SHARED, fd, 0);
if (mem_ != MAP_FAILED){...};

参数:

  1. start:指向欲对应的内存起始地址,通常设为NULL,代表让系统自动选定地址,对应成功后该地址会返回。
  2. length:代表将文件中多大的部分对应到内存。
  3. port:代表映射区域的保护方式,有下列组合:
    • PROT_EXEC  映射区域可被执行;
    • PROT_READ  映射区域可被读取;
    • PROT_WRITE  映射区域可被写入;
    • PROT_NONE  映射区域不能存取。
  4. flags:会影响映射区域的各种特性:
    • MAP_FIXED  如果参数 start 所指的地址无法成功建立映射时,则放弃映射,不对地址做修正。通常不鼓励用此旗标。
    • MAP_SHARED  对应射区域的写入数据会复制回文件内,而且允许其他映射该文件的进程共享。
    • MAP_PRIVATE  对应射区域的写入操作会产生一个映射文件的复制,即私人的"写入时复制" (copy on write)对此区域作的任何修改都不会写回原来的文件内容。
    • MAP_ANONYMOUS  建立匿名映射,此时会忽略参数fd,不涉及文件,而且映射区域无法和其他进程共享。
    • MAP_DENYWRITE  只允许对应射区域的写入操作,其他对文件直接写入的操作将会被拒绝。
    • MAP_LOCKED  将映射区域锁定住,这表示该区域不会被置换(swap)。 在调用mmap()时必须要指定MAP_SHARED 或MAP_PRIVATE。
  5. fd: 略
  6. offsize: 文件映射的偏移量,通常设置为0,代表从文件最前方开始对应,offset必须是分页大小的整数倍。

返回值:若映射成功则返回映射区的内存起始地址,否则返回MAP_FAILED(-1),错误原因存于errno 中。

dlopen()系列

void *dlopen(const char * filename , int flags );

dlopen 将filename指向的动态库加载进内存并返回指针handlerdlsym在指针handler中搜索符号,dlclose从内存中卸载共享库

如果filename依赖其他共享库,dlopen()会自动加载那些库

举例:

using func_t = int(int a, int b);

handle = dlopen(path,RTLD_NOW|RTLD_LOCAL);
if (handle == NULL) {
    return false;
}
onload = (func_t*)(unsigned long) dlsym(handle,"RedisModule_OnLoad");
if (onload == NULL) {
    dlclose(handle);
    return false;
}
return true;