Daemon Processes Long lived utility processes Often started at system boot and ended when system shuts down Run in the background with no controlling terminal Daemon Processes Coding rules (see page 425) Call umask and set the file mode creation mask to 0 Call fork and let the parent die Call setsid Change current working directory to root directory Close unneeded file descriptors Advanced I/O Nonblocking I/O I/O Multiplexing The poll() function call The select() function call File record locking Memory mapped I/O “Slow” I/O Reads of certain file types that can block forever if data is not ready (pipes, terminal devices, network devices) Writes on those same file types where data can’t be accepted immediately (pipe full, network flow control, etc) Opens of certain file types that block until some condition becomes true (terminal device that waits on a modem, open of a FIFO for writing only when no other process has it open for reading) “Slow” I/O Reads and writes of files with mandatory record locking enabled Some ioctl operations Some IPC functions Nonblocking I/O We can specify nonblocking I/O when we open a file by providing the O_NONBLOCK flag open(file,O_RDONLY | O_NONBLOCK); If the file is already open, we can use fcntl to set the O_NONBLOCK flag Nonblocking I/O flags = fcntl(fd, F_GETFL, 0); flags = flags | O_NONBLOCK; fcntl(fd, F_SETFL, flags); F_GETFL – get flags F_SETFL – set flags Check if file has nonblocking I/O enabled if(flags & O_NONBLOCK) Turn off nonblocking I/O flags = flags & ~O_NONBLOCK; fcntl(fd, F_SETFL, flags); I/O Multiplexing Avoids the busy waiting loop common with simple nonblocking I/O Using multiplexing we can block on multiple file descriptors simultaneously poll function int poll(struct pollfd *fds, nfds_t nfds, int timeout); struct pollfd { int fd; /* file descriptor */ short events; /* requested events */ short revents; /* returned events */ }; fds is an array of pollfd elements nfds is the number of elements in the array timeout specifies how long the function should block timeout = 0 – don’t block timeout = -1 - wait forever timeout > 0 - wait timeout miliseconds select function int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); struct timeval { long tv_sec; /* seconds */ long tv_usec; /* microseconds */ }; timeout specifies how long to block NULL – wait forever, or until a signal is caught tv_sec = 0 and tv_usec = 0 – don’t block tv_sec != 0 or tv_usec != 0 – block until a descriptor is ready or the timeout is reached. Can also be interrupted by a signal select function readfds, writefds, exceptfds are pointers to descriptor sets telling the system which file descriptors we are interested in for reading, writing and exceptions The type for descriptor sets is fd_set. This type can not be directly manipulated Use the following functions with fd_set void FD_CLR(int fd, fd_set *set); int FD_ISSET(int fd, fd_set *set); void FD_SET(int fd, fd_set *set); void FD_ZERO(fd_set *set); nfds is the number of file descriptors (usually the highest number plus one) Scatter Read and Gather Write ssize_t readv(int fd, const struct iovec *vector, int count); ssize_t writev(int fd, const struct iovec *vector, int count); struct iovec { void *iov_base; /* Starting address */ size_t iov_len; /* Number of bytes */ }; readv and writev allows us to read or write to multiple non contiguous buffers at the same time fd is the file descriptor to read from or write to vector is a pointer to an array of iovec structures count is the number of elements in the array Memory Mapped I/O Reading/Writing a memory address actually causes I/O to another device Functions are provided to memory map an open file Memory Mapped I/O void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset); Maps an open file to an area of memory start lets us request a given starting point in memory. length is the number of bytes to read from the file Memory Mapped I/O offset is the location within the file to begin fd is the file descriptor to be mapped prot specifies the protection of the mapped region PROT_READ - region can be read PROT_WRITE – region can be written PROT_EXEC – region can be executed PROT_NONE – region cannot be accessed flags – sets attributes of the mapped region. See page 488 for values and descriptions Memory Mapped I/O int munmap(void *start, size_t length); A mapped region is automatically unmapped when the process terminates munmap can be used to unmap a region earlier start – beginning address of mapped region length – number of bytes in region Note: closing the file descriptors does not unmap a region. File (Record) Locking Allows a process to lock a portion of a file to prevent access by another process Advisory Locking A convention that all processes accessing the file must follow Mandatory Locking Enforced by the Kernel. Other processes suspended if they try to read/write the locked section Mandatory Locking enabled by turning on the Set Group ID bit and turning off the group execute bit File (Record) Locking Locking Functions lockf - System V flock – BSD fcntl - POSIX fcntl Record Locking int fcntl(int fd, int cmd, struct flock *lock); struct flock { short l_type; short l_whence; off_t l_start; off_t l_len; pid_t l_pid; }; fd an open file descriptor fcntl Record Locking lock – a pointer to a flock struct l_type – F_RDLCK, F_WRLCK or F_UNLCK l_start – starting byte offset of locked region l_whence – same as for lseek: SEEK_SET, SEEK_CUR, SEEK_END l_len – length in bytes to lock. 0 means lock until EOF l_pid – used to return a pid with F_GETLK fcntl Record Locking cmd F_GETLK – checks to see if we can acquire the requested lock. If another process has a conflicting lock the information about that lock is passed back through lock F_SETLK – set a lock F_SETLKW – set a lock, but wait if there is a conflict. May be interrupted by a signal fcntl Record Locking Lock type must be consistent with the opened mode of the file F_RDLCK for O_RDONLY or O_RDWR F_WRLCK for O_WRONLY or O_RDWR Lock Compatibility Any number of processes may have shared read locks on a region of a file Only one processes at a time can have an exclusive write lock on a region We can not obtain a write lock on a region that already has a read lock We can not obtain a read lock on a region that already has a write lock Lock Combining If a process attempts to acquire a lock on a region it already has a lock on the old lock is replaced by the new lock The system will split and combine locks automatically Lock acquired from byte 100 to 200 Lock released for bytes 125 to 150 We now have 2 locks for bytes 100 to 125 and 150 to 200 Implied Inheritance and Release of Locks Locks are associated with a process and a file If the process terminates, its locks are released When a file is closed, any locks on it for that process are released Locks are not inherited across a fork Locks are inherited across an exec unless the close-on-exec flag is set