قصه: Linux Programming Interface
در این قصه
- فهرست کتاب Linux Programming Interface
- فصل ۴ - Uinversal I/O Model (همین پست)
- فصل ۵ - File I/O: Further Details
- فصل ۸ - Users and Groups
- فصل ۱۰ - Time
- فصل ۲۰ -Signals: Fundamental Concepts
- فصل ۲۴ − Process Creation
- فصل ۲۵− Process Termination
- فصل ۲۶ − Monitoring Child Processes
- تمرینهای کتاب Linux Programming Interface
فصل ۴ - Uinversal I/O Model
- disk files
- terminal files
- pipe files
----> buffered I/O
----> unbuffered I/O
file descriptors are used to refer to all types of open files, including pipes,
FIFOs, sockets, terminals, devices, and regular files. Each process has its
own set of file descriptors.
I/O redirection
# POSIX name stdion stream
----------------------------------
0 STDIN_FILENO stdin
1 STDOUT_FILENO stdout
2 STDERR_FILENO stderr
! freopen() may change the file descriptor underlying the reopened stream
mode_t
-------
S_IRUSR S_IRGRP S_IROTH S_ISUID
S_IWUSR S_IWGRP S_IWOTH S_ISGID
S_IXUSR S_IXGRP S_IXOTH S_ISVTX
S_IRWXU S_IRWXG S_IRWXO
mode_t tests
--------------
S_ISREG(m) S_ISFIFO(m) // named pipe?
S_ISDIR(m) S_ISLNK(m)
S_ISCHR(m) S_ISSOCK(m)
S_ISBLK(m)
mode_t ifs (used by mode & S_IFMT=0170000)
----------------------------------
S_IFREG S_IFIFO
S_IFDIR S_IFLNK
S_IFCHR S_IFSOCK
S_IFBLK
when access to specific features of a file system or device is required, a
program can use the catchall ioctl() system call, which provides an interface
to features that fall outside of the universal I/O model.
! Universal I/O Model: implementing open(), read(), write(), close()
! for all types of the file.
Open or create a file
+-----------------------------------------------------------------------+
| #include <sys/stat.h> |
| #include <fcntl.h> |
| |
| int open(const char *pathname, int flags, ... /* mode_t mode */); |
| |
| fd or success or -1 on error |
+-----------------------------------------------------------------------+
In code below inline /* comment */ is correctly TRUE.
+-----------------------------------------------------------------------+
| int |
| main(void) |
| { |
| if (1 /* true */) |
| return 0; |
| return 1; |
| } |
+-----------------------------------------------------------------------+
The mode_t data type is an integer type specified in SUS3. If the open() system
call doesn't specify O_CREAT, mode can be ommitted.
? resize array dynamically
! C doesn't check array boundaries.
+***************************+
| $ getconf -a |
| $ getcinf MAX_INT |
+***************************+
st_mode in OCTAL format
S_IXOTH 000 001
S_IWOTH 000 002
S_IROTH 000 004
S_IRWXO 000 007
S_IXGRP 000 010
S_IWGRP 000 020
S_IRGRP 000 040
S_IRWXG 000 070
S_IXUSR 000 100
S_IWUSR 000 200
S_IRUSR 000 400
S_IRWXU 000 700
S_ISVTX 001 000
S_ISGID 002 000
S_ISUID 004 000
S_IFIFO 010 000
S_IFCHR 020 000
S_IFDIR 040 000
S_IFBLK 060 000
S_IFREG 100 000
S_IFLNK 120 000
S_IFSOCK 140 000
S_IFMT 170 000
open() flags in HEX format
O_RDONLY 00 0000 retrievable and settable
O_LARGEFILE 00 0000
O_WRONLY 00 0001 *
O_RDWR 00 0002 *
O_CREAT 00 0040
O_EXCL 00 0080
O_NOCTTY 00 0100
O_TRUNC 00 0200
O_APPEND 00 0400 *+
O_NONBLOCK 00 0800 *+ /* O_NDELAY */
O_DSYNC 00 1000 *
O_ASYNC 00 2000 *+
O_DIRECT 00 4000 +
O_DIRECTORY 01 0000
O_NOFOLLOW 02 0000
O_NOATIME 04 0000 +
O_CLOEXEC 08 0000
O_SYNC 10 1000 *
O_PATH 20 0000
O_TMPFILE 41 0000
SUSv3 specifies that if open() successed, it is guaranteed to use the lowest
numbered unused file descriptor for the process.
O_APPEND makes that all writes happend at the end of the file. even after
changing file offset with lseek() function.
O_ASYNC (signal driven I/O) flag in linux in open function has no effect.
use fcntl() function with F_SETFL operation.
O_EXEC is used with O_CREAT. if file already exists open will return EERROR.
in other words O_EXEC makes sure that it is the current process that
has created the file. in this case pathname must not be symbolic link.
O_NOATIME is for backup and indexing program beacause they don't need to update
inodes repeatedly. _GNU_SOURCE must be set.
It is not permitted to modify (i.e. open for writting) the executable file
associated with a running program.
+---------------------------------------------------------------------------+
| #include <fcntl.h> |
| |
| int creat(const char *pathname, mode_t mode) |
+---------------------------------------------------------------------------+
create(pathname, mode) == open(pathname, O_WRONLY | O_CREAT | O_TRUNC, mode)
System calls don't allocate memory for buffers that are used to return
information to the caller. Instead we must path a pointer to a previously
allocated memory buffer of the correct size.
ssize_t and size_t both are (long) integer data types
read() doesn't place a terminating null byte at the end of the string that
printf() needs.
+---------------------------------------------------------------------------+
| #include <unistd.h> |
| |
| ssize_t read(int fd, void *buffer, size_t count) |
| |
| return number of nytes read, 0 on EOF, -1 on ERROR |
+---------------------------------------------------------------------------+
+---------------------------------------------------------------------------+
| #include <unistd.h> |
| |
| ssize_t write(int fd, void *buffer, size_t count); |
| |
| returns number of bytes written, or -1 on error |
+---------------------------------------------------------------------------+
Kernel performs buffering of disk I/O in order to reduce disk activity,
therefore successful return from write doesn't guarantee that the data has
been transfered to disk.
+---------------------------------------------------------------------------+
| #include <sys/types.h> |
| #include <dirent.h> |
| |
| int dirfd(DIR *dirp); |
| |
| return directory file descriptor on success, -1 on error |
+---------------------------------------------------------------------------+
+---------------------------------------------------------------------------+
| #include <unistd.h> |
| |
| int close(int fd) |
| |
| retunrs 0 on success, -1 on error |
+---------------------------------------------------------------------------+
+---------------------------------------------------------------------------+
| #include <unistd.h> |
| |
| off_t lseek(int fd, off_t offset, int whence); |
| |
| Returns new file offset if succesful, or -1 on error |
+---------------------------------------------------------------------------+
off_t data type is a signed (long) integer type specified by SUS3.
whence: SEEK_SET, SEEK_CUR, SEEK_END (next byte after the last byte)
calling lseek() simply adjusts the kernels record of the file offset associated
with a file descriptor. It does not cause any physical device access.
linux has not a system call that tell us current file offset!
not all files are seekables. pipe, fifo, socket, or terminals are not seekable.
they return with ESPIPE error.
The null character '\0' is not printable.
File holes don't take up any disk space. The file system doesn't allocate any
disk blocks for a hole until at some later point, data is written into it. core
dump files are common examples of files that conatin large holes.
The existence of holes means that a file's nominal size may be larger than the
amount of disk storage it utilizes.
+---------------------------------------------------------------------------+
| #include <fcntl.h> |
| |
| int posix_fallocate(int fd, off_t offset, off_t len); |
| |
| Returns zero on success or an error number on failure |
+---------------------------------------------------------------------------+
none portable, linux-specific system call:
+---------------------------------------------------------------------------+
| #include <fcntl.h> |
| |
| int fallocate(int fd, int mode, off_t offset, off_t len); |
| |
| Return 0 on success, -1 on error |
+---------------------------------------------------------------------------+
! \n and \t are not printable.
The ioctl() system call is a general purpose mechanism for performing file and
device operations that fall outside the universal I/O model.
+---------------------------------------------------------------------------+
| #include <sys/ioctl.h> |
| |
| int ioctl(int fd, int request, ... /* argp */); |
| |
| value returned on success depends on request, or -1 on error |
+---------------------------------------------------------------------------+
device specific header files define constants that can be passed in the
request argument.
question: write a program like cp that, when used to copy a regular file that
contains holes (sequence of null bytes), also creates corresponding holes in
the target file.
مثالهای این فصل
نوشته شده در:
1405-03-10
(1 هفته 21 ساعت 40 دقیقه پیش)
من محسن هستم؛ برنامهنویس تفننی!
برای ارتباط با من یا در همین سایت کامنت بگذارید و یا به dokaj.ir(at)gmail.com ایمیل بزنید.
پست قبلی:
فصل ۵ - File I/O: Further Details
پست بعدی:
خانوادهی توابع کتابخانهای getopt(3)
در مورد این مطلب یادداشتی بنویسید.