📄 llio.texi
字号:
systems. This is when the stream is doing input from a file that is notrandom-access. Such streams typically read ahead, and when the file isnot random access, there is no way to give back the excess data alreadyread. When an input stream reads from a random-access file,@code{fflush} does clean the stream, but leaves the file pointer at anunpredictable place; you must set the file pointer before doing anyfurther I/O. On the GNU system, using @code{fclean} avoids both ofthese problems.Closing an output-only stream also does @code{fflush}, so this is avalid way of cleaning an output stream. On the GNU system, closing aninput stream does @code{fclean}.You need not clean a stream before using its descriptor for controloperations such as setting terminal modes; these operations don't affectthe file position and are not affected by it. You can use anydescriptor for these operations, and all channels are affectedsimultaneously. However, text already ``output'' to a stream but stillbuffered by the stream will be subject to the new terminal modes whensubsequently flushed. To make sure ``past'' output is covered by theterminal settings that were in effect at the time, flush the outputstreams for that terminal before setting the modes. @xref{TerminalModes}.@node Waiting for I/O@section Waiting for Input or Output@cindex waiting for input or output@cindex multiplexing input@cindex input from multiple filesSometimes a program needs to accept input on multiple input channelswhenever input arrives. For example, some workstations may have devicessuch as a digitizing tablet, function button box, or dial box that areconnected via normal asynchronous serial interfaces; good user interfacestyle requires responding immediately to input on any device. Anotherexample is a program that acts as a server to several other processesvia pipes or sockets.You cannot normally use @code{read} for this purpose, because thisblocks the program until input is available on one particular filedescriptor; input on other channels won't wake it up. You could setnonblocking mode and poll each file descriptor in turn, but this is veryinefficient.A better solution is to use the @code{select} function. This blocks theprogram until input or output is ready on a specified set of filedescriptors, or until a timer expires, whichever comes first. Thisfacility is declared in the header file @file{sys/types.h}.@pindex sys/types.hIn the case of a server socket (@pxref{Listening}), we say that``input'' is available when there are pending connections that could beaccepted (@pxref{Accepting Connections}). @code{accept} for serversockets blocks and interacts with @code{select} just as @code{read} doesfor normal input.@cindex file descriptor sets, for @code{select}The file descriptor sets for the @code{select} function are specifiedas @code{fd_set} objects. Here is the description of the data typeand some macros for manipulating these objects.@comment sys/types.h@comment BSD@deftp {Data Type} fd_setThe @code{fd_set} data type represents file descriptor sets for the@code{select} function. It is actually a bit array.@end deftp@comment sys/types.h@comment BSD@deftypevr Macro int FD_SETSIZEThe value of this macro is the maximum number of file descriptors that a@code{fd_set} object can hold information about. On systems with afixed maximum number, @code{FD_SETSIZE} is at least that number. Onsome systems, including GNU, there is no absolute limit on the number ofdescriptors open, but this macro still has a constant value whichcontrols the number of bits in an @code{fd_set}.@end deftypevr@comment sys/types.h@comment BSD@deftypefn Macro void FD_ZERO (fd_set *@var{set})This macro initializes the file descriptor set @var{set} to be theempty set.@end deftypefn@comment sys/types.h@comment BSD@deftypefn Macro void FD_SET (int @var{filedes}, fd_set *@var{set})This macro adds @var{filedes} to the file descriptor set @var{set}.@end deftypefn@comment sys/types.h@comment BSD@deftypefn Macro void FD_CLR (int @var{filedes}, fd_set *@var{set})This macro removes @var{filedes} from the file descriptor set @var{set}.@end deftypefn@comment sys/types.h@comment BSD@deftypefn Macro int FD_ISSET (int @var{filedes}, fd_set *@var{set})This macro returns a nonzero value (true) if @var{filedes} is a memberof the the file descriptor set @var{set}, and zero (false) otherwise.@end deftypefnNext, here is the description of the @code{select} function itself.@comment sys/types.h@comment BSD@deftypefun int select (int @var{nfds}, fd_set *@var{read-fds}, fd_set *@var{write-fds}, fd_set *@var{except-fds}, struct timeval *@var{timeout})The @code{select} function blocks the calling process until there isactivity on any of the specified sets of file descriptors, or until thetimeout period has expired.The file descriptors specified by the @var{read-fds} argument arechecked to see if they are ready for reading (or if a server socket, foraccepting a connection); the @var{write-fds} file descriptors arechecked to see if they are ready for writing; and the @var{except-fds}file descriptors are checked for exceptional conditions. You can pass anull pointer for any of these arguments if you are not interested inchecking for that kind of condition.``Exceptional conditions'' does not mean errors---errors are reportedimmediately when an erroneous system call is executed, and do notconstitute a state of the descriptor. Rather, they include conditionssuch as the presence of an urgent message on a socket. (@xref{Sockets},for information on urgent messages.)The @code{select} function checks only the first @var{nfds} filedescriptors. The usual thing is to pass @code{FD_SETSIZE} as the valueof this argument.The @var{timeout} specifies the maximum time to wait. If you pass anull pointer for this argument, it means to block indefinitely until oneof the file descriptors is ready. Otherwise, you should provide thetime in @code{struct timeval} format; see @ref{High-ResolutionCalendar}. Specify zero as the time (a @code{struct timeval} containingall zeros) if you want to find out which descriptors are ready withoutwaiting if none are ready.The normal return value from @code{select} is the total number of ready filedescriptors in all of the sets. Each of the argument sets is overwrittenwith information about the descriptors that are ready for the correspondingoperation. Thus, to see if a particular descriptor @var{desc} has input,use @code{FD_ISSET (@var{desc}, @var{read-fds})} after @code{select} returns.If @code{select} returns because the timeout period expires, it returnsa value of zero.Any signal will cause @code{select} to return immediately. So if yourprogram uses signals, you can't rely on @code{select} to keep waitingfor the full time specified. If you want to be sure of waiting for aparticular amount of time, you must check for @code{EINTR} and repeatthe @code{select} with a newly calculated timeout based on the currenttime. See the example below. See also @ref{Interrupted Primitives}.If an error occurs, @code{select} returns @code{-1} and does not modifythe argument file descriptor sets. The following @code{errno} error conditions are defined for this function:@table @code@item EBADFOne of the file descriptor sets specified an invalid file descriptor.@item EINTRThe operation was interrupted by a signal. @xref{Interrupted Primitives}.@item EINVALThe @var{timeout} argument is invalid; one of the components is negativeor too large.@end table@end deftypefun@strong{Portability Note:} The @code{select} function is a BSD Unixfeature.Here is an example showing how you can use @code{select} to establish atimeout period for reading from a file descriptor. The @code{input_timeout}function blocks the calling process until input is available on thefile descriptor, or until the timeout period expires.@smallexample@include select.c.texi@end smallexampleThere is another example showing the use of @code{select} to multiplexinput from multiple sockets in @ref{Server Example}.@node Control Operations@section Control Operations on Files@cindex control operations on files@cindex @code{fcntl} functionThis section describes how you can perform various other operations onfile descriptors, such as inquiring about or setting flags describingthe status of the file descriptor, manipulating record locks, and thelike. All of these operations are performed by the function @code{fcntl}.The second argument to the @code{fcntl} function is a command thatspecifies which operation to perform. The function and macros that namevarious flags that are used with it are declared in the header file@file{fcntl.h}. (Many of these flags are also used by the @code{open}function; see @ref{Opening and Closing Files}.)@pindex fcntl.h@comment fcntl.h@comment POSIX.1@deftypefun int fcntl (int @var{filedes}, int @var{command}, @dots{})The @code{fcntl} function performs the operation specified by@var{command} on the file descriptor @var{filedes}. Some commandsrequire additional arguments to be supplied. These additional argumentsand the return value and error conditions are given in the detaileddescriptions of the individual commands.Briefly, here is a list of what the various commands are.@table @code@item F_DUPFDDuplicate the file descriptor (return another file descriptor pointingto the same open file). @xref{Duplicating Descriptors}.@item F_GETFDGet flags associated with the file descriptor. @xref{Descriptor Flags}.@item F_SETFDSet flags associated with the file descriptor. @xref{Descriptor Flags}.@item F_GETFLGet flags associated with the open file. @xref{File Status Flags}.@item F_SETFLSet flags associated with the open file. @xref{File Status Flags}.@item F_GETLKGet a file lock. @xref{File Locks}.@item F_SETLKSet or clear a file lock. @xref{File Locks}.@item F_SETLKWLike @code{F_SETLK}, but wait for completion. @xref{File Locks}.@item F_GETOWNGet process or process group ID to receive @code{SIGIO} signals.@xref{Interrupt Input}.@item F_SETOWNSet process or process group ID to receive @code{SIGIO} signals.@xref{Interrupt Input}.@end table@end deftypefun@node Duplicating Descriptors@section Duplicating Descriptors@cindex duplicating file descriptors@cindex redirecting input and outputYou can @dfn{duplicate} a file descriptor, or allocate another filedescriptor that refers to the same open file as the original. Duplicatedescriptors share one file position and one set of file status flags(@pxref{File Status Flags}), but each has its own set of file descriptorflags (@pxref{Descriptor Flags}).The major use of duplicating a file descriptor is to implement@dfn{redirection} of input or output: that is, to change thefile or pipe that a particular file descriptor corresponds to.You can perform this operation using the @code{fcntl} function with the@code{F_DUPFD} command, but there are also convenient functions@code{dup} and @code{dup2} for duplicating descriptors.@pindex unistd.h@pindex fcntl.hThe @code{fcntl} function and flags are declared in @file{fcntl.h},while prototypes for @code{dup} and @code{dup2} are in the header file@file{unistd.h}.@comment unistd.h@comment POSIX.1@deftypefun int dup (int @var{old})This function copies descriptor @var{old} to the first availabledescriptor number (the first number not currently open). It isequivalent to @code{fcntl (@var{old}, F_DUPFD, 0)}.@end deftypefun@comment unistd.h@comment POSIX.1@deftypefun int dup2 (int @var{old}, int @var{new})This function copies the descriptor @var{old} to descriptor number@var{new}.If @var{old} is an invalid descriptor, then @code{dup2} does nothing; itdoes not close @var{new}. Otherwise, the new duplicate of @var{old}replaces any previous meaning of descriptor @var{new}, as if @var{new}were closed first.If @var{old} and @var{new} are different numbers, and @var{old} is avalid descriptor number, then @code{dup2} is equivalent to:@smallexampleclose (@var{new});fcntl (@var{old}, F_DUPFD, @var{new})@end smallexampleHowever, @code{dup2} does this atomically; there is no instant in themiddle of calling @code{dup2} at which @var{new} is closed and not yet aduplicate of @var{old}.@end deftypefun@comment fcntl.h@comment POSIX.1@deftypevr Macro int F_DUPFDThis macro is used as the @var{command} argument to @code{fcntl}, tocopy the file descriptor given as the first argument.The form of the call in this case is:@smallexamplefcntl (@var{old}, F_DUPFD, @var{next-filedes})@end smallexampleThe @var{next-filedes} argument is of type @code{int} and specifies thatthe file descriptor returned should be the next available one greaterthan or equal to this value.The return value from @code{fcntl} with this command is normally the valueof the new file descriptor. A return value of @code{-1} indicates anerror. The following @code{errno} error conditions are defined forthis command:@table @code@item EBADFThe @var{old} argument is invalid.@item EINVALThe @var{next-filedes} argument is invalid.@item EMFILEThere are no more file descriptors available---your program is alreadyusing the maximum. In BSD and GNU, the maximum is controlled by aresource limit that can be changed; @pxref{Limits on Resources}, formore information about the @code{RLIMIT_NOFILE} limit.@end table@code{ENFILE} is not a possible error code for @code{dup2} because@code{dup2} does not create a new opening of a file; duplicatedescriptors do not count toward the limit which @code{ENFILE}indicates. @code{EMFILE} is possible because it refers to the limit ondistinct descriptor numbers in use in one process.@end deftypevr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -