I/O Functions
- man 2 cmd
- Open
- This is the most complex of the five operations we will study.
- It requires two header files
- #include <sys/stat.h>
- #include <fnctl.h>
- Open has two forms
- int open(const char *pathname, int flags);
- int open(const char *pathname, int flags, mode_t mode);
- In both cases a small non-negative integer is returned on success
- This is the file descriptor, used in future calls.
- This will be the lowest number descriptor available.
- So if I want to change stdin, I close 0 and open a new fd.
- A return value of -1 indicates a failure.
- The file descriptor will remain open across the creation of a child process unless flags are set.
- This also creates a new open file description in the system wide open files table.
- This stays open even if the name given is removed.
- The path must either be relative or absolute, no ~ expansion here.
- If the pathname is a symbolic link, the target of the link is openend (or the link is followed)
- The flags must include one of the following:
- O_RDONLY: open the file for reading
- O_WRONLY: open the file for writing
- O_RDWR: open the file for read/write
- There are many many other flags.
- O_CLOEXEC: causes the file descriptor to be closed if the program calls a member of the exec family.
- O_CREAT: create the file if it does not exist. This is the C++ stream open default.
- O_EXCL: used with create. Force the call to fail if the file exists.
- O_TRUNC: truncate the file if it does exist. This is the C++ stream default.
- O_APPEND: Before each write, move the file pointer to the end of the file.
- This can be a problem with multiple processes writing to a NFS mounted file.
- But no problem with a single file.
- O_LARGEFILE: large files.
- O_NOFOLLOW: Don't follow symbolic links, but write to the symbolic link file.
- O_TMPFILE: create a temporary file, expects the path name to be a directory, not a file.
- This one is strange and we will look at it later.
- There are more, and the list grows, but that will do for now.
- When a file is created, the mode flags
- S_IRWXU, S_IRWXG , S_IRWXO
- S_IRUSR, S_IWUSR, S_IXUSR, *GRP, *OTH
- LOTS of errors, worth looking at
- EACCES - no access
- EEXIST - already exists
- ELOOP - too many symbolic links.
- EMFILE - limit of open file descriptors has been reached.
- There is some variance on how the flags interact.
- read()
- #include < unistd.h>
- ssize_t read(int fd, void *buf, size_t count);
- Return
- Returns the number of bytes read.
- 0 indicates the end of file.
- -1 is an error.
- fd is the file descriptor
- from open,
- STD*_FILENO
- Or something else.
- buf is an array of characters at least count bytes long.
- count is the number of bytes to read.
- If count > return value, then
- Close to end of file
- In a situation where the data was not available.
- There are some errors, but not too many.
- Write is the same as read.
- The data is handed to the kernel, but may not be written to disk yet.
- int fsync(int fd); will accomplish this.
- If the file was opened with O_APPEND the data will always be written to the end of the file.
- Close
- int close(int fd);
- When a process terminates all open file descriptors are closed.
- But it is good practice to close them when you are finished with them.
- That way files will be flushed in the case of a system crash.
- And resources are free for use later.
- See reader and writer in the source code.