2024年10月glibc手册(linux手册翻译——epoll_wait(2))

 更新时间:2024-10-12

  ⑴glibc手册(linux手册翻译——epoll_wait()

  ⑵linux手册翻译——epoll_wait()

  ⑶epoll_wait,epoll_pwait,epoll_pwait-在epollfd上等待I/O事件

  ⑷events指向了事件缓冲区,每当interestlist中fd触发事件加入到readylist后,会将其返回到事件缓冲区中。最大返回maxevents个,因此maxevents至少大于。返回的event顺序写入缓冲区。timeout参数指定epoll_wait将阻塞的毫秒数。

  ⑸epoll_wait()将会一直阻塞直到:fd产生事件/被信号处理函数打断/超时。

  ⑹时间测量将使用CLOCK_MONOTONIC(系统启动后到现在的时间,记录的是tick的总次数时钟,超时时间将向上舍入到系统时钟粒度,内核调度延迟可能让阻塞时间稍微超出。指定为-时将无限期阻塞,指定为时若没有可用事件则立即返回。

  ⑺返回的epoll_event中,data字段与使用event_ctl()(EPOLL_CTL_ADD,EPOLL_CTL_MOD)传入的data一致。(所以一般来说用fd足矣),而events字段是此fd触发的事件。

  ⑻与epoll_wait自比,后者允许应用程序安全的等待(在调用epoll_wait(),设置自定义的信号掩码,并在epoll_wait()结束后恢复),直到文件描述等就绪或信号被捕获。

  ⑼sigmask指定为NULL时,epoll_pwait与epoll_wait相同。epoll_pwait与epoll_pwait除timeout参数外完全相同,它指定timespec结构来执行纳秒级的等待。设为NULL时将一直等。

  ⑽错误将返回-,并设定errno;超时将返回;成功将返回触发I事件的fd个数。

  ⑾epoll_wait()在.版中被添加到内核中。从版本..开始,glibc中提供了库支持。epoll_pwait()在内核..中被添加到Linux。从版本.开始,glibc中提供了库支持。epoll_pwait()在内核.中被添加到Linux。

  ⑿epoll_wait(),epoll_pwait(),andepoll_pwait()areLinux-specific.

  ⒀虽然一个线程在调用epoll_wait()时被阻塞,但另一个线程可能会向等待的epoll实例添加文件描述符。如果新的文件描述符准备好,它将导致epoll_wait()调用解除阻塞。

  ⒁如果在调用epoll_wait()时有超过maxevents个文件描述符准备就绪,那么连续的epoll_wait()调用将循环遍历准备好的文件描述符集。此行为有助于避免饥饿情况,即进程未能注意到其他文件描述符已准备就绪,因为它专注于一组已知已准备就绪的文件描述符。循环遍历的意义就在于避免只访问固定位置的事件。

  ⒂请注意,可以在interest-list当前为空的epoll实例上调用epoll_wait()(或者其interest-list因为文件描述符被关闭或从另一个线程中的兴趣中删除而变为空。该调用将阻塞,直到在另一个线程中将某个文件描述符添加到interest-list并且该文件描述符准备就绪。Clibrary/kerneldifferences原始的epoll_pwait()和epoll_pwait()系统调用有第六个参数size_tsigsetsize,它指定了sigmask参数的字节大小。glibcepoll_pwait()包装函数将此参数指定为固定值(等于sizeof(sigset_t)。在..之前的内核中,大于大约LONG_MAX/HZ毫秒的超时值被视为-(即无穷大。因此,例如,在sizeof(long)为且内核HZ值为的系统上,这意味着大于.分钟的超时被视为无穷大

  ⒃linux手册翻译——sendfile()

  ⒄sendfile-transferdatabetweenfiledescriptors

  ⒅sendfile()在一个文件描述符和另一个文件描述符之间复制数据。因为这种复制是在内核中完成的,所以sendfile()比read()和write()的组合更有效,后者需要将数据传入和传出用户空间。

  ⒆in_fd是一个为读取而打开的文件描述符,out_fd是一个为写入而打开的描述符。

  ⒇如果offset不为NULL,则sendfile()将以其为偏移量从in_fd中读取数据。当sendfile()返回时,此变量将设置为读取的最后一个字节之后的偏移量。如果offset为NULL,则将从in_fd中的文件偏移量开始读取数据。

  ⒈需要注意!如果指定了offset,那么读取in_fd中的数据是不会修改其打开文件自身的偏移量的。

  ⒉count是要在文件描述符之间复制的字节数。

  ⒊in_fd参数必须是支持类似mmap()等操作的文件(即它不能是套接字。

  ⒋在..之前的Linux内核中,out_fd必须引用套接字。从Linux..开始,它可以是任何文件。如果它是一个常规文件,则sendfile()适当地更改out_fd的文件偏移量。

  ⒌如果传输成功,则返回写入out_fd的字节数。请注意,成功调用sendfile()可能会写入比请求更少的字节;如果有未发送的字节,调用者应该准备重试调用。另见NOTES。出错时,返回-,并设置errno以指示错误。

  ⒍sendfile()首次出现在Linux.中。从glibc.开始就存在包含文件《sys/sendfile.h》。

  ⒎NotspecifiedinPOSIX.-,norinotherstandards.

  ⒏OtherUNIXsystemsimplementsendfile()withdifferentsemanticsandprototypes.Itshouldnotbeusedinportableprograms.

  ⒐sendfile()最多传输xffff(,,,)个字节,返回的是实际传输的字节数。(在位和位系统上都是如此。

  ⒑如果您计划使用sendfile()将文件发送到TCP套接字,但需要在文件内容之前发送一些标头数据,您会发现使用TCP_CORK选项很有用,在tcp()中描述,以最小化数据包的数量并调整性能。

  ⒒根据tcp(),TCP_CORK的作用是:如果设置,则不发送部分帧。当再次清除该选项时,将发送所有排队的部分帧。更方便的,可以在执行时send()时设置MSG_MORE标志,见send()

  ⒓在Linux.及更早版本中,out_fd也可以指普通文件;这种可能性在Linux..x内核系列中消失了,但在Linux..中恢复了。

  ⒔最初的Linuxsendfile()系统调用不是为了处理大文件偏移量而设计的。因此,Linux.添加了sendfile(),偏移参数的类型更宽。glibcsendfile()包装函数透明地处理内核差异。

  ⒕在sendfile()因EINVAL或ENOSYS失败的情况下,应用程序可以回退到read()/write()。

  ⒖如果out_fd引用了具有零拷贝支持的套接字或管道,则调用者必须确保in_fd引用的文件的传输部分保持不变,直到out_fd另一端的读取器消耗了传输的数据。

  ⒗Linux特定的splice()调用支持在任意文件描述符之间传输数据,前提是其中一个(或两个是管道。

  ⒘如何解决源码包安装时的依赖性问题

  ⒙不管是初步跨入Linux殿堂的新手,还是具有多年经验的专家,在安装或编译软件包的过程中或多或少的都会遇到包的依赖问题,从而导致安装过程无法继续,比如管理员在安装LAMP时,包需要libgd.so文件,而这个文件属于GD软件包。但是在安装GD软件包时,可能这个软件包跟其他软件包又具有依赖关系,又需要安装其他软件包才行。这时有的管理员便失去耐心。在遇到这种Linux软件包依赖关系问题时,该如何解决呢?在谈这个具体的措施之前,先跟大家聊聊Linux系统里的软件依赖性问题。一、什么是依赖性程序依赖于程序代码的共享库,以便它们可以发出系统调用将输出发送到设备或打开文件等(共享库存在于许多方面,而不只局限于系统调用。没有共享库,每次程序员开发一个新的程序,每个程序员都需要从头开始重写这些基本的系统操作。当编译程序时,程序员将他的代码链接到这些库。如果链接是静态的,编译后的共享库对象代码就添加到程序执行文件中;如果是动态的,编译后的共享库对象代码只在运行时需要它时由程序员加载。动态可执行文件依赖于正确的共享库或共享对象来进行操作。rpm依赖性尝试在安装时强制实施动态可执行文件的共享对象需求,以便在以后当程序运行时不会有与动态链接过程有关的任何问题。注意:还有一种类型的依赖性,它基于显式的条目,rpm通过程序员将该依赖性强加到rpm配置文件中,但目前我们不关心这种类型的依赖性,这种依赖性比较容易解决。这里将重点放在rpm强制实施的更加复杂的共享对象依赖性。二、动态可执行文件和共享对象动态可执行文件使用最初编译和链接程序时使用的库文件的共享对象名称来查找共享对象。它们在少数的几个标准位置查找,比如在/lib和/usr/lib目录及在LD_LIBRARY_PATH环境变量(主要用于指定查找共享库,比如我们在安装Oracle时指定路径,exportLD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib:/usr/local/lib指定的目录中。顺便提一下,在这些库目录中找到的共享对象可能不是真正的文件;它们可能是指向位于其他位置的真实库文件的符号链接(但通常仍旧在标准库目录的一个目录中。至少从系统管理员的观点是在用于创建共享库文件的共享库软件包的名称和共享库文件的名称之间通常没有什么关系。例如,GLIBC.软件包用于创建libc.so.共享库文件。也从本示例中注意到,添加到共享库文件名结束的版本号(.)跟用于创建它的版本号(.)没有关系。这是由共享库软件包开发人员有意完成的,以便GLIBC的新版本可以重用相同的共享库文件名libc.so.。这允许您在系统上加载新版本的GLIBC,而不用中断动态链接到lib.so.共享库文件的所有程序,当然假定新版本的GLIBC向后与动态可执行文件最初所链接的老版本GLIBC兼容。因此,即使库文件或共享对象文件有与它们相关的版本号,这些版本号也不能帮助你确定他们来自哪个版本的共享软件包。注意:当将whatprovides选项用于rpm查询命令时,可以获得有关使用rpm软件包加载到系统的现有共享对象的信息。这种混乱是由下面的事实造成的:单个共享库文件可能支持某个范围的共享库软件包版本。例如,要检查soname库文件/lib/libc.so.支持的GLIBC共享库软件包,运行下面的命令:#objdump--all-headers/lib/libc.so.|less向下滚动此报告,直到到达Versiondefinitions:部分,以便查看libc.so.共享库文件支持哪些GLIBC版本:Versiondefinitions:xxfelibc.so.xxdGLIBC_.xxdGLIBC_.GLIBC_.xxfGLIBC_..GLIBC_.xxfGLIBC_..GLIBC_..xxfGLIBC_..GLIBC_..xxdGLIBC_.GLIBC_..xxaGLIBC_..GLIBC_.xxaGLIBC_..GLIBC_..xxaGLIBC_..GLIBC_..xxaGLIBC_..GLIBC_..xxaGLIBC_..GLIBC_..xxdGLIBC_.GLIBC_..xxGLIBC_..GLIBC_.xxGLIBC_..GLIBC_..xxGLIBC_..GLIBC_..xxdGLIBC_.GLIBC_..xxdGLIBC_.GLIBC_.xxcfGLIBC_PRIVATEGLIBC_.xxbG_.在本示例中,ibc.so.共享库文件支持原先为GLIBC版本.到.而开发的所有动态执行文件。注意:也可以使用objdump命令来从共享库文件中提取soname,命令如下所示:#objdump--all-headers/lib/libcrypto.so...b|grepSONAMESONAMElibcrypto.so.objdump:/lib/libcrypto.so...b:norecognizeddebugginginformation接下来,将讨论rpm软件包是如何生成的,以便在新系统上安装rpm软件包时,这些共库依赖性是己知的。三、Rpm软件包和共享库依赖性当程序员生成rpm软件包时,ldd命令用于报告动态可执行文件软件包中所有动态可执行文件使用的所有共享库。另一个混乱是由下面的事实带来的:相同软件包中的不同动态可执行文件可能与相同的共享库软件包的不同版本进行链接。例如,Heartbeat软件包中的不同程序可能已经进行了开发,并动态链接到libc.so.sonmae共享库文件的不同GLIBC版本。对rpm命令使用-q和--requires参数,可以看到rpm软件包需要的共享库的完整清单。例如,要看到Heartbeatrpm软件包所有的所需依赖性,请使用命令:#rpm-q--requires-pheartbeat-.x.x.i.rpm这产生了下面的报告:sysklogd/bin/sh/bin/sh/usr/bin/pythonld-linux.so.libapphb.so.libc.so.libc.so.(GLIBC_.)libc.so.(GLIBC_.)libc.so.(GLIBC_..)libc.so.(GLIBC_.)libc.so.(GLIBC_.)libmclient.so.libdl.so.libglib-..so.libhbclient.so.libpils.so.libplumb.so.libpthread.so.librt.so.libstonith.so.注意,在此报告中,libc.so.soname是所需要的,此共享库必须支持使用GLIBC共享软件包版本号.、.、..、.和.进行链接的动态可执行文件。这是由下面的事实决定的:Heartbeat软件包中的不同动态可执行文件是针对不同版本的libc.so.库的每个版本进行链接的。在了解了动态可执行文件、共享对象、soname和共享库软件包彼此是如何相关的后,下面准备来看这样的一个例子:当尝试安装rpm软件包,并且它由于依赖性错误而失败时,会发生什么。yum能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软体包,无须繁琐地一次次下载、安装。四、手工解决依赖性问题通常,当尝试安装发行版中没有包括的软件包(及不能由像update、apt-get或Yum一样的更新工具自动解决其依赖性的软件包时,将碰到rpm依赖性错误。例如,如果尝试在老的Linux发行版上使用rpm–ivh*rpm命令,例如所有的Heartbeatrpm包,那么在安装过程中就可能碰到下面的错误:error:faileddependencies:libc.so.(GLIBC_.)isneededbyheartbeat-.x.xlibc.so.(GLIBC_.)isneededbyheartbeat-pils-.x.xlibcrypto.so...isneededbyheartbeat-stonith-.x.xlibsnmp-....soisneededbyheartbeat-stonith-.x.x注意,rpm命令没有干扰报告所需的每个GLIBC共享库软件包版本号——它只报告所需的最高编号的版本号(GLIBC_.)。(假定原来的软件包开发人员不会将相同软件包中的可执行文件链接到不兼容版本的共享库软件包)所有的这些故障都报告所需的共享库名称或soname(而不是文件名称,soname始终以“lib”开始。但可以删除添加到rpm报告的soname结束的版本号,并快速检查以查看是否在系统中使用locate命令安装这些共享库(假设您的locate数据库是最新的,有关更多信息,请参阅locate或slocate的手册页)。例如,要查找libcrypto享库文件,要输入:#locatelibcrypto#locatelibcrypto/lib/libcrypto.so...b/lib/libcrypto.so./root/.Trash/vmware-tools-distrib/lib/lib/libcrypto.so.../root/.Trash/vmware-tools-distrib/lib/lib/libcrypto.so.../libcrypto.so.../root/.Trash/vmware-tools-distrib/lib/lib/libcrypto.so.../root/.Trash/vmware-tools-distrib/lib/lib/libcrypto.so.../libcrypto.so.../usr/lib/libcrypto.a/usr/lib/libcrypto.so/usr/lib/pkgconfig/libcrypto.pc/usr/lib/vmware-tools/lib/libcrypto.so.../usr/lib/vmware-tools/lib/libcrypto.so.../libcrypto.so.../usr/lib/vmware-tools/lib/libcrypto.so.../usr/lib/vmware-tools/lib/libcrypto.so.../libcrypto.so...如果此命令没有在系统上找到一个libcrypto共享库文件,将需要转到Inter并找出哪个共享库软件包包含此共享库文件。完成此项工具的一个快速和简便方式是只要在

  ⒚linux手册翻译——send()

  ⒛send,sendto,sendmsg-sendamessageonasocket

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

  仅当套接字处于连接状态时才可以使用send()调用(以便知道预期的接收者,也就是说send()仅仅用于数据流类型的数据发送,对于TCP,服务端和客户端都可以使用send/recv;但是对于UDP,只能是客户端使用send/recv,服务端只能使用sendto/recvfrom,因为客户端是进行了connect操作知道要发送和接受的地址。send()和write()之间的唯一区别是存在flags参数。此外,send(sockfd,buf,len,flags);等价于sendto(sockfd,buf,len,flags,NULL,);

  参数sockfd是发送者套接字的文件描述符。

  如果在连接模式的套接字(即套接字类型为SOCK_STREAM、SOCK_SEQPACKET)上使用sendto(),则参数dest_addr和addrlen将被忽略(当它们不是NULL和时可能返回错误EISCONN),若套接字没有实际连接(还没有三次握手建立连接)将返回错误ENOTCONN。否则,目标地址由dest_addr给出,addrlen指定其大小。对于sendmsg(),目标地址由msg.msg_name给出,msg.msg_namelen指定其大小。

  对于send()和sendto(),消息位于buf中,长度为len。对于sendmsg(),消息存放于msg.msg_iov元素指向数组数据区(见下)中。sendmsg()调用还允许发送辅助数据(也称为控制信息。

  如果消息太长而无法通过底层协议原子传递(toolongtopassatomicallythroughtheunderlyingprotocol),则返回错误EMSGSIZE,并且不会传输消息。

  Noindicationoffailuretodeliverisimplicitinasend().Locallydetectederrorsareindicatedbyareturnvalueof-.

  当消息不适合套接字的发送缓冲区时,send()通常会阻塞,除非套接字已置于非阻塞I/O模式。在这种情况下,在非阻塞模式下它会失败并显示错误EAGAIN或EWOULDBLOCK。select()调用可用于确定何时可以发送更多数据。

  上面的的描述还是很笼统的,以TCP为例,按我的理解,我认为只要发送缓冲区有空闲位置,且此时协议栈没有向网络发送数据,那么就可以写入,对于阻塞模式,直到所有数据写入到缓冲区,就会返回,否则一直阻塞,对于非阻塞模式,是有一个超时时间的,这个由SO_SNDTIMEO选项控制,详细见socket(),如果当前有空闲位置可以发即当前可写入,那么就写入到缓冲区,知道超时之前写入多少算多少,然后返回成功写入的字节数,如果超时时任何数据都没写出去,或者当前就是不可写入,那么返回-,并设置errno为EAGAIN或EWOULDBLOCK。

  TheflagsargumentisthebitwiseORofzeroormoreofthefollowingflags.

  sendmsg()使用的msghdr结构的定义如下:

  对于未连接的套接字msg_name指定数据报的目标地址,它指向一个包含地址的缓冲区;msg_namelen字段应设置为地址的大小。对于连接的套接字,这些字段应分别指定为NULL和。这里的未连接指的是数据报协议,连接指的是数据流协议

  Themsg_iovandmsg_iovlenfieldsspecifyscatter-gatherlocations,asforwritev().msg_iov是一个buffer数组:

  使用msg_control和msg_controllen成员发送控制信息(辅助数据。内核可以处理的每个套接字最大控制缓冲区长度由/proc/sys//core/optmem_max中的值限制;见socket()。有关在各种套接字域中使用辅助数据的更多信息,请参阅unix()和ip()。

  msg_flags字段被忽略。

  成功时,返回成功发送的字节数,这个字节数并不一定和我们的缓冲区大小相同。出错时,返回-,并设置errno以指示错误。

  这些是套接字层生成的一些标准错误。底层协议模块可能会产生和返回额外的错误;请参阅它们各自的手册页。

  BSD,SVr,POSIX.-.Theseinterfacesfirstappearedin.BSD.

  POSIX.-describesonlytheMSG_OOBandMSG_EORflags.POSIX.-addsaspecificationofMSG_NOSIGNAL.TheMSG_CONFIRMflagisaLinuxextension.

  根据POSIX.-,msghdr结构的msg_controllen字段应该是socklen_t类型,而msg_iovlen字段应该是int类型,但是glibc目前将两者都视为size_t。

  有关可用于在单个调用中传输多个数据报的Linux特定系统调用的信息,请参阅sendmmsg()。LinuxmayreturnEPIPEinsteadofENOTCONN.

  getaddrinfo()中显示了使用send()的示例。

  linux手册翻译——recv()

  recv,recvfrom,recvmsg-receiveamessagefromasocket

  recv()、recvfrom()和recvmsg()调用用于从套接字接收消息。它们可用于在UDP和TCP的套接字上接收数据。本页首先介绍了所有三个系统调用的共同特点,然后介绍了调用之间的区别。

  recv()和read()之间的唯一区别是flags的存在。使用零标志参数,recv()通常等效于read()(但请参阅NOTES),且recv(sockfd,buf,len,flags);等价于recvfrom(sockfd,buf,len,flags,NULL,NULL);

  所有三个调用都在成功完成时返回消息的长度。如果消息太长而无法放入提供的缓冲区,则可能会丢弃多余的字节,具体取决于接收消息的套接字类型,显然TCP是不可能丢弃的。

  如果套接字上没有可用消息,则接收调用将等待消息到达,除非套接字是非阻塞的(请参阅ftl(),在这种情况下,将返回值-并将errno设置为EAGAIN或EWOULDBLOCK。recv_()调用通常会返回任何可用的数据,只要拿到数据就会立马返回,最多返回指定缓冲区大小的数据,但是并不会等待到让缓冲区满,除非设置了MSG_WAITALL标志,见下。

  应用程序可以使用select()、poll()或epoll()来确定更多数据何时到达。

  TheflagsargumentisformedbyORingoneormoreofthefollowingvalues:

  ee_errnocontainstheerrnonumberofthequeuederror.ee_originistheorigincodeofwheretheerrororiginated.Theotherfieldsareprotocol-specific.ThemacroSOCK_EE_OFFENDERreturnsapointertotheaddressoftheworkobjectwheretheerrororiginatedfromgivenapointertotheancillarymessage.Ifthisaddressisnotknown,thesa_familymemberofthesockaddrcontainsAF_UNSPECandtheotherfieldsofthesockaddrareundefined.Thepayloadofthepacketthatcausedtheerrorispassedasnormaldata.Forlocalerrors,noaddressispassed(thiscanbecheckedwiththecmsg_lenmemberofthecmsghdr).Forerrorreceives,theMSG_ERRQUEUEflagissetinthemsghdr.Afteranerrorhasbeenpassed,thependingsocketerrorisregeneratedbasedonthenextqueuederrorandwillbepassedonthenextsocketoperation.

  recvfrom()将接收到的消息放入缓冲区buf。调用者必须在len中指定缓冲区的大小。

  如果调用者希望拿到消息的原地址,并且底层协议可以提供消息的源地址时,应将src_addr设置为指向用于接收消息原地址的缓冲区。在这种情况下,addrlen是一个value-result参数。在调用之前,它应该被初始化为与src_addr关联的缓冲区的大小。返回时,addrlen被更新以包含源地址的实际大小。如果提供的缓冲区太小,则截断返回的地址;在这种情况下,addrlen将返回一个大于提供给调用的值。

  如果调用者对源地址不感兴趣,则应将src_addr和addrlen指定为NULL。

  ssize_trecv(intsockfd,void*buf,size_tlen,intflags);recv()调用通常仅用于已连接的套接字(请参阅connect()。相当于调用:recvfrom(fd,buf,len,flags,NULL,);

  ssize_trecvmsg(intsockfd,structmsghdr*msg,intflags);recvmsg()调用使用msghdr结构来最小化直接提供的参数数量。这个结构在《sys/socket.h》中定义如下:

  msg_name字段指向调用者分配的缓冲区,如果套接字未连接(特指UDP的服务端,则该缓冲区用于返回源地址。调用者应在此调用之前将msg_namelen设置为此缓冲区的大小;从成功调用返回后,msg_namelen将包含返回地址的长度。如果应用程序不需要知道源地址,可以将msg_name指定为NULL。

  Thefieldsmsg_iovandmsg_iovlendescribescatter-gatherlocations,asdiscussedinreadv().需要注意的是msg_iov和msg_iovlen描述了一个structiovec类型的数组,msg_iovlen表示数组的元素个数,而structiovec则是描述了一个缓冲区

  字段msg_control指向用于其他协议控制相关消息或杂项辅助数据的缓冲区。当recvmsg()被调用时,msg_controllen为msg_control中可用缓冲区的长度;从成功调用返回时,它将被设置为控制消息序列的长度。

  只能通过cmsg()中定义的宏访问辅助数据。

  例如,Linux使用这种辅助数据机制通过UNIX域套接字传递扩展错误、IP选项或文件描述符。有关在各种套接字域中使用辅助数据的更多信息,请参阅unix()和ip()。

  msghdr中的msg_flags字段在recvmsg()返回时设置。它可以包含几个标志:

  这些调用返回接收到的字节数,如果发生错误,则返回-。如果发生错误,则设置errno以指示错误。

  当流套接字对等端执行有序关闭(orderlyshutdown)时,返回值将为(传统的“文件结束”返回。

  各种域(例如UNIX和Inter域中的数据报套接字允许零长度数据报。当收到这样的数据报时,返回值为。

  如果从流套接字接收的请求字节数为,则也可能返回值。

  这些是套接字层生成的一些标准错误。底层协议模块可能会产生和返回额外的错误;查看他们的手册页。

  POSIX.-,POSIX.-,.BSD(theseinterfacesfirstappearedin.BSD).

  POSIX.describesonlytheMSG_OOB,MSG_PEEK,andMSG_WAITALLflags.

  如果零长度数据报未决,则带有零标志参数的read()和recv()提供不同的行为。在这种情况下,read()不起作用(数据报保持挂起,而recv()消耗挂起的数据报。

  socklen_t类型是由POSIX发明的。另见aept()。

  根据POSIX.,msghdr结构的msg_controllen字段类型为socklen_t,而msg_iovlen字段类型为int,但glibc目前将两者设置为size_t。

  有关可用于在单个调用中接收多个数据报的Linux特定系统调用的信息,请参阅recvmmsg()。

  getaddrinfo()中显示了使用recv()的示例。

  linux手册翻译——fallocate()

  fallocate-manipulatefilespace这是一个不可移植的、特定于Linux的系统调用。Fortheportable,POSIX.-specifiedmethodofensuringthatspaceisallocatedforafile,seeposix_fallocate().fallocate()允许调用者直接操作fd引用的文件所分配的磁盘空间,操作的字节范围为。mode参数确定要在给定范围上执行的操作。支持的操作的详细信息在下面的小节中给出。fallocate()的默认操作(即mode=是在参数offset和len指定的范围内分配磁盘空间。如果offset+len大于文件的大小,则文件大小将被修改。超过原范围的区域将会被初始化为。此默认行为与posix_fallocate()库函数的行为非常相似,是实现posix_fallocate()的最佳实现方法。调用成功后,后续写入offset和len指定的范围不会因为磁盘空间不足而失败。注:这样做的有什么用呢?根据博客用fallocate进行“文件预留“或“文件打洞“,可以有以下好处:(可以让文件尽可能的占用连续的磁盘扇区,减少后续写入和读取文件时的磁盘寻道开销;(迅速占用磁盘空间,防止使用过程中所需空间不足。(后面再追加数据的话,不会需要改变文件大小,所以后面将不涉及metadata的修改如果在mode中指定了FALLOC_FL_KEEP_SIZE标志,调用的行为类似,即依然会为文件分配磁盘空间,但是不会修改文件大小。这种预分配的方式可以用来优化文件的append操作,也就是在执行append的时候不需要再额外申请磁盘空间了。如果在mode中指定了FALLOC_FL_UNSHARE_RANGE标志,则共享文件数据范围将成为文件私有的,以保证后续写入不会因空间不足而失败。通常,这将通过对文件中的所有共享数据执行写时复制操作来完成。并非所有文件系统都支持此标志。由于分配是以块大小的块完成的,fallocate()可能会分配比指定范围更大的磁盘空间。当mode指定为FALLOC_FL_PUNCH_HOLE时,会释放指定范围内的空间,即创建一个空洞。在指定的范围内,部分的文件块(即文件块部分属于该范围)将会被置为,全部的在范围内的文件块,将会被从文件系统中删除。成功调用后,后续的读取将会返回。FALLOC_FL_PUNCH_HOLE必须和FALLOC_FL_KEEP_SIZE通过或运算一起使用,换句话说,FALLOC_FL_PUNCH_HOLE是不能修改文件的大小的。并非所有文件系统都支持FALLOC_FL_PUNCH_HOLE;如果文件系统不支持该操作,则返回错误。至少以下文件系统支持该操作:当mode指定为FALLOC_FL_COLLAPSE_RANGE标志时,将从文件中删除指定的字节范围,而不会留下空洞。操作完成后,从offset+len开始位置的文件内容将会被追加到offset处。文件大小会减少len文件系统可能会限制操作的粒度,以确保有效实施。通常,offset和len必须是文件系统逻辑块大小的倍数,这取决于文件系统类型和配置。如果文件系统有这样的要求,如果违反了该要求,fallocate()将失败并显示错误EINVAL。Iftheregionspecifiedbyoffsetpluslenreachesorpassestheendoffile,anerrorisreturned;instead,useftruncate()totruncateafile.FALLOC_FL_COLLAPSE_RANGE标志和其他标志不兼容。在Linux.中,ext(onlyforextent-basedfiles和XFS支持FALLOC_FL_COLLAPSE_RANGE标志。当mode指定为FALLOC_FL_COLLAPSE_RANGE标志时,将会指定范围内分配磁盘空间,填补空洞。成功调用后后续读取将会返回。Zeroingisdonewithinthefilesystempreferablybyconvertingtherangeintounwrittenextents.Thisapproachmeansthatthespecifiedrangewillnotbephysicallyzeroedoutonthedevice(exceptforpartialblocksattheeitherendoftherange),andI/Ois(otherwise)requiredonlytoupdatemetadata.可能的意思是,最好不要将物理磁盘清零,而是配置一个为写入的状态,这样读取上来的pagecache就是。这种情况下,仅仅需要修改文件元数据就可有了。如果在mode中额外指定了FALLOC_FL_KEEP_SIZE标志,调用的行为类似,但即使offset+len大于文件大小,文件大小也不会改变。此行为与在指定FALLOC_FL_KEEP_SIZE的情况下预分配空间时相同。并非所有文件系统都支持FALLOC_FL_ZERO_RANGE;如果文件系统不支持该操作,则返回错误。至少以下文件系统支持该操作:如果在mode中额外指定了FALLOC_FL_INSERT_RANGE标志,那么将会在offset开始的位置插入一个大小为len的空洞,在不覆盖文件内容的前提下增加文件的空间。此模式在操作粒度方面与FALLOC_FL_COLLAPSE_RANGE具有相同的限制。如果不满足粒度要求,fallocate()将失败并显示错误EINVAL。如果偏移量等于或大于文件末尾,则返回错误。对于此类操作(即在文件末尾插入一个洞,应使用ftruncate()。FALLOC_FL_INSERT_RANGE标志与其他标志不兼容。目前只有XFS(sinceLinux.)和ext(sinceLinux.)支持此标志。nsuess,fallocate()returnszero.Onerror,-isreturnedanderrnoissettoindicatetheerror.fallocate()isavailableonLinuxsincekernel...Supportisprovidedbyglibcsinceversion..TheFALLOC_FL_*flagsaredefinedinglibcheadersonlysinceversion..fallocate()isLinux-specific.

  如何更新ubuntu的man手册

  一般会在有更新的时候自动提示你进行更新。如果想自己更新、系统设置里有个更新管理器、打开终端输入下面的命令sudoapt-getupdatesudoapt-getupgrade更新系统版本sudoapt-getupgrade-dist

  linux手册翻译——epoll_ctl()

  epoll_ctl一epll文件描述符的控制接口

  此操作用于要在epoll的interestlist中增、改、删entry(entry包括了fd和设定的事件),具体的操作由op参数指定:

  epoll-event结构:

  epoll_event的data成员指定内核应该保存的数据,并在epoll_wait准备好时返回,可用于标识触发event的fd是那个,这个很重要。epoll_event的events成员是位掩码,由以下个或多个可用事件类型组合到一起:

  成功时,epoll_ctl()返回零。发生错误时,epoll_ctl()返回-并设置errno以指示错误。

  epoll_ctl()在.版中被添加到内核中。从版本..开始,glibc中提供了库支持。

  epoll_ctl()isLinux-specific.

  Theepollinterfacesupportsallfiledescriptorsthatsupportpoll().

  Inkernelversionsbefore..,theEPOLL_CTL_DELoperationrequiredanon-nullpointerinevent,eventhoughthisargumentisignored.SinceLinux..,eventcanbespecifiedasNULLwhenusingEPOLL_CTL_DEL.Applicationsthatneedtobeportabletokernelsbefore..shouldspecifyanon-nullpointerinevent.

  IfEPOLLWAKEUPisspecifiedinflags,butthecallerdoesnothavetheCAP_BLOCK_SUSPENDcapability,thentheEPOLLWAKEUPflagissilentlyignored.Thisunfortunatebehaviorisnecessarybecausenovaliditycheckswereperformedontheflagsargumentintheoriginalimplementation,andtheadditionoftheEPOLLWAKEUPwithacheckthatcausedthecalltofailifthecallerdidnothavetheCAP_BLOCK_SUSPENDcapabilitycausedabreakageinatleastoneexistinguser-spaceapplicationthathappenedtorandomly(anduselessly)specifythisbit.ArobustapplicationshouldthereforedoublecheckthatithastheCAP_BLOCK_SUSPENDcapabilityifattemptingtousetheEPOLLWAKEUPflag.

  linux有API手册吗

  有命令行中输入manXXXXXX是包的名称或是命令名称或是程序库名称如:manglibc就是glibc(Gclib库中的函数介绍要看有什么程序包用新立得打开可以搜索,点击下面就有描述有些程序有开发包就会有dev包。如openoffice-dev就是开发openoffice插件的开发包,包含有相关函数库

您可能感兴趣的文章:

相关文章