文章

Linux 函数说明

前言

在 strace 进程的时候会显示出来调用的函数,有的时候查看数据库进程的时候方便查看,在这里记录一下一些函数的说明

函数

以下内容结合 chatgpt 和 google 翻译

truncate

描述

truncate, ftruncate 函数作用是将文件截断为指定长度,函数原型

定义

1
2
3
4
5
#include <unistd.h>
#include <sys/types.h>

int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);

truncate() 和 ftruncate() 函数导致由路径命名或由 fd 引用的常规文件被截断为精确长度字节的大小。

如果文件以前大于此大小,则多余的数据将丢失。如果文件以前较短,则会对其进行扩展,并且扩展部分读取为空字节 (‘\0’)。

文件偏移量不会更改。

如果大小发生变化,则文件的 st_ctime 和 st_mtime 字段(分别为上次状态更改时间和上次修改时间;请参阅 stat(2))被更新,并且 set-user-ID 和 set-group-ID权限位可以被清除。

使用 ftruncate() 时,文件必须打开才能写入;使用 truncate() 时,文件必须可写。

返回值

成功后,返回零。出错时,返回 -1,并适当设置 errno。

epoll_wait

描述

epoll_wait – 等待 epoll 文件描述符上的 I/O 事件

函数定义

1
2
3
4
5
6
7
#include <sys/epoll.h>

int epoll_wait(int epfd, struct epoll_event *events,
                              int maxevents, int timeout);
int epoll_pwait(int epfd, struct epoll_event *events,
                               int maxevents, int timeout,
                               const sigset_t *sigmask);

epoll_wait() 系统调用等待文件描述符 epfd 引用的 epoll(7) 实例上的事件。事件指向的内存区域将包含调用者可用的事件。 epoll_wait() 最多返回 maxevents。 maxevents 参数必须大于零。

timeout 参数指定 epoll_wait() 将阻塞的最小毫秒数。 (此间隔将向上舍入到系统时钟粒度,内核调度延迟意味着阻塞间隔可能会小幅超出。)指定超时为 -1 会导致 epoll_wait() 无限期阻塞,而指定超时等于零会导致 epoll_wait() 立即返回,即使没有可用的事件。

返回值

成功时,epoll_wait() 返回为请求的 I/O 做好准备的文件描述符的数量,如果在请求的超时毫秒内没有文件描述符准备就绪,则返回零。当发生错误时,epoll_wait()返回-1,并适当设置errno。

recvfrom

描述

recv、recvfrom、recvmsg - 从套接字接收消息

定义

1
2
3
4
5
6
7
8
9
#include <sys/types.h>
#include <sys/socket.h>

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                                  struct sockaddr *src_addr, socklen_t *addrlen);

ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

recvfrom() 和 recvmsg() 调用用于从套接字接收消息,并且可以用于接收套接字上的数据,无论它是否是面向连接的。

如果src_addr不为NULL,且底层协议提供了源地址,则填写该源地址。当src_addr为NULL时,不填写任何内容;在这种情况下,addrlen 不被使用,并且也应该为 NULL。参数 addrlen 是一个值-结果参数,调用者应在调用与 src_addr 关联的缓冲区大小之前对其进行初始化,并在返回时进行修改以指示源地址的实际大小。如果提供的缓冲区太小,返回的地址将被截断;在这种情况下,addrlen 将返回一个大于提供给调用的值。

返回值

这些调用返回接收到的字节数,如果发生错误则返回 -1。当对等方执行有序关闭时,返回值为 0。

pwrite64 / pread

描述

pread、pwrite - 在给定偏移处读取或写入文件描述符

定义

1
2
3
4
5
6
7
8
9
10
11
#include <unistd.h>

ssize_t pread(int fd, void *buf, size_t count, off_t offset);

ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

pread(), pwrite():
_XOPEN_SOURCE >= 500
|| /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L

pread() 从文件描述符 fd 中以偏移量 offset(从文件开头)读取最多 count 个字节到从 buf 开始的缓冲区中。文件偏移量未更改。

pwrite() 将从 buf 开始的缓冲区中写入 count 个字节到文件描述符 fd 的偏移量 offset 处。文件偏移量未更改。

fd 引用的文件必须能够查找。

返回值

成功时,返回读取或写入的字节数(在 pwrite() 的情况下为零表示未写入任何内容,在 pread() 的情况下表示文件末尾),或在错误时返回 -1,其中case errno 设置为指示错误。

access

描述

access - 检查真实用户对文件的权限

定义

1
2
#include <unistd.h>
int access(const char *pathname, int mode);

access() 检查调用进程是否可以访问文件路径名。如果路径名是符号链接,则取消引用它。

返回值

成功时(授予所有请求的权限),返回零。出错时(模式中至少有一位请求的权限被拒绝,或者发生了其他错误),返回 -1,并适当设置 errno。

chdir

描述

chdir、fchdir - 更改工作目录

定义

1
2
3
4
#include <unistd.h>

int chdir(const char *path);
int fchdir(int fd);

chdir() 将调用进程的当前工作目录更改为 path 中指定的目录。

fchdir() 与 chdir() 相同;唯一的区别是目录作为打开的文件描述符给出。

返回值

成功后,返回零。出错时,返回 -1,并适当设置 errno。

close

描述

close - 关闭文件描述符

定义

1
2
#include <unistd.h>
int close(int fd);

close() 关闭文件描述符,以便它不再引用任何文件并且可以重用。与其关联且由进程拥有的文件上持有的任何记录锁(请参阅 fcntl(2))都将被删除(无论用于获取锁的文件描述符是什么)。

如果 fd 是引用底层打开文件描述的最后一个文件描述符(请参阅 open(2)),则释放与打开文件描述关联的资源;如果描述符是对已使用 unlink(2) 删除的文件的最后一个引用,则文件将被删除。

返回值

close() 成功时返回零。出错时,返回 -1,并适当设置 errno。

exit_group

描述

exit_group - 退出进程中的所有线程

定义

1
2
#include <linux/unistd.h>
void exit_group(int status);

此系统调用等效于 exit(2),只不过它不仅终止调用线程,而且终止调用进程的线程组中的所有线程。

返回值

该系统调用没有返回值

fdatasync

描述

fsync、fdatasync - 将文件的核心状态与存储设备同步

定义

1
2
3
4
5
#include <unistd.h>

int fsync(int fd);

int fdatasync(int fd);

fsync() 将文件描述符 fd 引用的文件的所有修改的核心数据(即修改的缓冲区高速缓存页面)传输(“刷新”)到磁盘设备(或其他永久存储设备),以便所有更改的信息即使系统崩溃或重新启动后也可以检索。这包括写入或刷新磁盘缓存(如果存在)。该调用将阻塞,直到设备报告传输已完成。它还刷新与文件关联的元数据信息(请参阅 stat(2))。

调用 fsync() 不一定确保包含该文件的目录中的条目也已到达磁盘。为此,还需要目录的文件描述符上的显式 fsync()。

fdatasync() 与 fsync() 类似,但不会刷新修改的元数据,除非需要该元数据以便正确处理后续数据检索。例如,对 st_atime 或 st_mtime(分别是上次访问时间和上次修改时间;请参阅 stat(2))的更改不需要刷新,因为正确处理后续数据读取不需要它们。另一方面,文件大小的更改(st_size,如 ftruncate(2) 所做的)将需要元数据刷新。

fdatasync() 的目的是减少不需要所有元数据与磁盘同步的应用程序的磁盘活动。

返回值

成功后,这些系统调用返回零。出错时,返回 -1,并适当设置 errno。

futex

描述

futex - 快速用户空间锁定

定义

1
2
3
4
5
#include <linux/futex.h>
#include <sys/time.h>

int futex(int *uaddr, int op, int val, const struct timespec *timeout,
                    int *uaddr2, int val3);

系统调用 futex() 提供了一种方法,使程序可以等待给定地址处的值发生变化,并提供一种方法来唤醒等待该特定地址的任何进程(尽管在不同进程中相同内存的地址可能不同,但内核会将它们内部映射,使得映射到不同位置的相同内存可以在 futex() 调用中对应)。此系统调用通常用于在共享内存中实现锁的争用情况,如 futex(7) 所描述的。

当 futex(7) 操作未能在用户空间无争用地完成时,需要调用内核进行仲裁。仲裁可能意味着将调用进程置于休眠状态,或者相反地唤醒等待的进程。

调用此函数的用户应遵守 futex(7) 中规定的语义。由于这些语义涉及编写不可移植的汇编指令,这意味着大多数用户实际上是库作者,而不是普通应用程序开发者。

uaddr 参数需要指向一个对齐的整数,该整数存储计数器。要执行的操作通过 op 参数传递,同时传递一个值 val。

目前定义了五种操作:

  • FUTEX_WAIT 该操作原子地验证 futex 地址 uaddr 是否仍然包含值 val,并在该地址上休眠,等待 FUTEX_WAKE。如果 timeout 参数不为 NULL,则其内容描述最小等待时间,否则为无限。uaddr2 和 val3 参数被忽略。对于 futex(7),如果递减计数给出了负值(表示争用),则会执行此调用并休眠,直到另一个进程释放 futex 并执行 FUTEX_WAKE 操作。

  • FUTEX_WAKE 此操作最多唤醒 val 个在该 futex 地址上等待的进程(即,在 FUTEX_WAIT 中)。timeout、uaddr2 和 val3 参数被忽略。对于 futex(7),当递增计数显示有等待者时,一旦 futex 值被设置为 1(表示可用),就会执行此操作。

  • FUTEX_FD(适用于 Linux 2.6.25 及之前版本) 为支持异步唤醒,此操作将文件描述符与 futex 关联。如果另一个进程执行 FUTEX_WAKE,则进程将收到传递给 val 的信号号。调用进程在使用后必须关闭返回的文件描述符。timeout、uaddr2 和 val3 参数被忽略。为防止竞态条件,调用方应在 FUTEX_FD 返回后测试 futex 是否已被提升。

    由于其本质上的竞争问题,FUTEX_FD 自 Linux 2.6.26 起被移除。

  • FUTEX_REQUEUE(自 Linux 2.5.70 起) 引入此操作是为了避免使用 FUTEX_WAKE 时的“雷鸣般的”效果,因为所有被唤醒的进程都需要获取另一个 futex。此调用唤醒 val 个进程,并将其他等待者重新排队到 uaddr2 地址上的 futex。timeout 和 val3 参数被忽略。

  • FUTEX_CMP_REQUEUE(自 Linux 2.6.7 起) FUTEX_REQUEUE 的预期使用中存在竞态,因此引入了 FUTEX_CMP_REQUEUE。此操作类似于 FUTEX_REQUEUE,但首先检查位置 uaddr 是否仍然包含值 val3。如果没有,则操作失败并返回错误 EAGAIN。timeout 参数被忽略。

返回值

如果发生错误,所有操作都返回-1,并设置 errno 来指示错误。成功时的返回值取决于操作,如下列表所述:

  • FUTEX_等待 如果进程被 FUTEX_WAKE 调用唤醒,则返回 0。请参阅 ERRORS 了解各种可能的错误返回。
  • FUTEX_唤醒 返回唤醒的进程数。
  • FUTEX_FD 返回与 futex 关联的新文件描述符。
  • FUTEX_REQUEUE 返回唤醒的进程数。
  • FUTEX_CMP_REQUEUE 返回唤醒的进程数。

getpid

描述

getpid, getppid - 获取进程标识

定义

1
2
3
4
5
#include <sys/types.h>
#include <unistd.h>

pid_t getpid(void);
pid_t getppid(void);

getpid() 返回调用进程的进程 ID。 (这通常由生成唯一临时文件名的例程使用。)

getppid() 返回调用进程的父进程的进程 ID。

返回值

kill

描述

Kill - 向一个进程或一组进程发送信号

定义

1
2
3
#include <signal.h>

int kill(pid_t pid, int sig);

kill() 函数将向由 pid 指定的进程或进程组发送信号。要发送的信号由 sig 指定,可以是 <signal.h> 中列出的信号之一,也可以是 0。如果 sig 为 0(空信号),则只执行错误检查而不发送任何信号。空信号可用于检查 pid 的有效性。

要允许一个进程向由 pid 指定的进程发送信号,除非发送进程具有适当的权限,否则发送进程的真实用户 ID 或有效用户 ID 必须与接收进程的真实用户 ID 或保存的设置用户 ID 匹配。

  • 如果 pid 大于 0,则信号将发送给进程 ID 等于 pid 的进程。
  • 如果 pid 为 0,信号将发送给所有进程(不包括某些未指定的系统进程),其进程组 ID 等于发送者的进程组 ID,并且该进程有权限发送信号。
  • 如果 pid 为 -1,信号将发送给所有进程(不包括某些未指定的系统进程),对于这些进程,发送者有权限发送信号。
  • 如果 pid 为负值但不等于 -1,信号将发送给所有进程组 ID 等于 pid 绝对值的进程(不包括某些未指定的系统进程),并且发送者有权限发送信号。

如果 pid 的值导致信号生成给发送进程,并且该信号未被调用线程阻塞,且没有其他线程解除阻塞或正在等待该信号,则在 kill() 返回之前,信号或至少一个未阻塞的待处理信号将被传递给发送线程。

在发送 SIGCONT 信号给与发送进程属于同一会话的进程时,不应用上述的用户 ID 检查。

实现提供的扩展安全控制可能会对发送信号施加进一步的实现定义的限制,包括空信号。系统可能会拒绝某些或全部由 pid 指定的进程的存在。

如果 kill() 函数成功,表示进程有权限向任何由 pid 指定的进程发送信号。如果 kill() 失败,则不会发送任何信号。

返回值

成功完成后,返回0。否则,应返回-1并设置errno以指示错误。

lseek

描述

lseek - 重新定位读/写文件偏移

定义

1
2
3
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);

lseek() 函数用于重新定位与文件描述符 fd 关联的打开文件的偏移量,依据参数 whence 指定的指令调整 offset,具体如下:

  • SEEK_SET: 将偏移量设置为 offset 字节。
  • SEEK_CUR: 将偏移量设置为当前位置加上 offset 字节。
  • SEEK_END: 将偏移量设置为文件大小加上 offset 字节。

lseek() 允许将文件偏移量设置到文件末尾之后,但不会改变文件的实际大小。如果稍后在此位置写入数据,那么在这个位置之前的 “空洞” 中读取到的数据将返回空字节(即 '\0'),直到真正有数据写入这些 “空洞”。

搜索文件数据和空洞

自 Linux 3.1 版起,支持以下 whence 选项:

  • SEEK_DATA: 将文件偏移量调整到文件中大于或等于 offset 的下一个包含数据的位置。如果 offset 指向数据位置,则将偏移量设置为 offset
  • SEEK_HOLE: 将文件偏移量调整到文件中大于或等于 offset 的下一个空洞的位置。如果 offset 指向空洞中间,则将偏移量设置为 offset。如果在 offset 之后没有空洞,偏移量将调整为文件末尾(文件末尾隐含一个空洞)。

在这两种情况下,如果 offset 超过文件末尾,lseek() 将失败。

这些操作允许应用程序在稀疏分配的文件中映射空洞。例如,文件备份工具可以利用这一功能来节省空间,通过发现空洞来保留这些稀疏部分。

关于空洞的定义

对于这些操作来说,空洞是指在底层文件存储中尚未分配的全零字节序列。然而,文件系统并没有义务报告空洞,因此这些操作并不能保证准确映射文件实际分配的存储空间(而且,已经写入底层存储的零字节序列可能不会被视为空洞)。在最简单的实现中,文件系统可以通过以下方式支持这些操作:使 SEEK_HOLE 总是返回文件末尾的偏移量,而 SEEK_DATA 总是返回 offset,即使 offset 指向空洞,该位置也可以被视为数据(全零字节序列)。

返回值

成功完成后,lseek() 返回结果偏移位置(从文件开头开始以字节为单位)。出错时,返回值 (off_t) -1,并设置 errno 来指示错误。

mkdir

描述

mkdir - 创建目录

定义

返回值

munmap

描述

mmap、munmap - 将文件或设备映射或取消映射到内存中

定义

1
2
3
#include <sys/mman.h>
void *mmap(void *addr, size_t lengthint " prot ", int " flags ,
                      int fd, off_t offset);int munmap(void *addr, size_t length);

mmap() 在调用进程的虚拟地址空间中创建一个新的映射。新映射的起始地址在 addr 中指定。长度参数指定映射的长度。

返回值

成功时,mmap() 返回指向映射区域的指针。出错时,返回值 MAP_FAILED(即 (void *) -1),并适当设置 errno。成功时,munmap() 返回 0,失败时返回 -1,并且设置 errno(可能为 EINVAL)。

newfstatat

描述

newfstatat

stat、fstat、lstat、fstatat - 获取文件状态

定义

返回值

openat

描述

openat - 打开相对于目录文件描述符的文件

定义

1
2
3
4
#include <fcntl.h>

int openat(int dirfd, const char *pathname, int flags);
int openat(int dirfd, const char *pathname, int flags, mode_t mode);

返回值

rt_sigaction

描述

sigaction - 检查并更改信号操作

定义

1
2
3
4
#include <signal.h>

int sigaction(int signum, const struct sigaction *act,
                            struct sigaction *oldact);

sigaction() 系统调用用于更改进程在收到特定信号时所采取的操作。 (有关信号的概述,请参阅 signal(7)。)

Signum 指定信号,可以是除 SIGKILL 和 SIGSTOP 之外的任何有效信号。

如果 act 为非 NULL,则从 act 安装信号signum 的新操作。如果oldact非NULL,则前一个操作将保存在oldact中。

返回值

rt_sigreturn

描述

sigreturn - 从信号处理程序返回并清理堆栈帧

定义

1
int sigreturn(unsigned long __unused);

当 Linux 内核为信号处理程序创建堆栈帧时,对 sigreturn() 的调用将插入到堆栈帧中,以便在从信号处理程序返回时调用 sigreturn()。

返回值

sendto

描述

send、sendto、sendmsg - 在套接字上发送消息

定义

1
2
3
4
5
6
7
8
9
#include <sys/types.h>
#include <sys/socket.h>

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                              const struct sockaddr *dest_addr, socklen_t addrlen);

ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);

系统调用 send()、sendto() 和 sendmsg() 用于将消息传输到另一个套接字。

返回值

setitimer

描述

getitimer、setitimer - 获取或设置间隔计时器的值

定义

1
2
3
4
5
#include <sys/time.h>

int getitimer(int which, struct itimerval *curr_value);
int setitimer(int which, const struct itimerval *new_value,
                            struct itimerval *old_value);

系统为每个进程提供三个间隔计时器,每个计时器在不同的时域内递减。当任何计时器到期时,都会向进程发送一个信号,并且计时器(可能)重新启动。

返回值

write

描述

write - 写入文件描述符

定义

1
2
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);

write() 将 buf 指向的缓冲区中最多 count 个字节写入文件描述符 fd 引用的文件。

返回值

writev

描述

readv、writev、preadv、pwritev - 将数据读取或写入多个缓冲区

定义

1
2
3
4
5
6
7
8
9
10
11
#include <sys/uio.h>

ssize_t readv(int fd, const struct iovec *iov, int iovcnt);

ssize_t writev(int fd, const struct iovec *iov, int iovcnt);

ssize_t preadv(int fd, const struct iovec *iov, int iovcnt,
                              off_t offset);

ssize_t pwritev(int fd, const struct iovec *iov, int iovcnt,
                                off_t offset);

readv() 系统调用将 iovcnt 缓冲区从与文件描述符 fd 关联的文件读取到 iov (“分散输入”)描述的缓冲区中。

writev() 系统调用将 iov 描述的数据的 iovcnt 缓冲区写入与文件描述符 fd 关联的文件(“收集输出”)。

返回值

参考

https://linux.die.net/

https://www.kernel.org/doc/html/latest/

https://www.kernel.org/doc/html/latest/_CN

https://www.linuxdoc.org/

https://tldp.org/guides.html

https://helpmanual.io/man2/newfstatat/

http://man.he.net/man2/newfstatat

https://github.com/torvalds/linux

本文由作者按照 CC BY 4.0 进行授权

© TheDarkStarJack. 保留部分权利。

[本站总访问量次] [本站访客数人次] [本文总阅读量次]

本站采用 Jekyll 主题 Chirpy