open() trả về một mô tả file nếu không có lỗi xảy ra. Khi có lỗi , nó trả về giá trị -1 và
đặt giá trị cho biến errno. Hàm create() cũng tương tự như open() với các cờ O_CREATE | O_WRONLY | O_TRUNC
Hàm close()
Chúng ta nên đóng mô tả file khi đã thao tác xong với nó. Chỉ có một đối số đó là số
mô tả file mà lời gọi open() trả về. Dạng của lời gọi close() là: #include <unistd.h>
int close(int fd);
Tất cả các khoá (lock) do tiến trình xử lý trên file được giải phóng, cho dù chúng được
đặt mô tả file khác. Nếu quá trình đóng file làm cho bộ đếm liên kết bằng 0 thì file sẽ bị
xoá. Nếu đây là mô tả file cuối cùng liên kết đến một file được mở thì bản ghi ở bảng file mởđược giải phóng. Nếu không phải là một file bình thường thì các hiệu ứng không mong muốn có thể xảy ra.
Hàm read()
Lời gọi hệ thống read() sử dụng đểđọc dữ liệu từ file tương ứng với một mô tả file. #include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
Đối sốđầu tiên là mô tả file mà được trả về từ lời gọi open() trước đó. Đối số thứ hai là một con trỏ tới bộ đệm để sao chép dữ liệu và đối số thứ ba là số byte sẽđược đọc. read() trả về số byte được đọc hoặc -1 nếu có lỗi xảy ra.
Hàm write()
Lời gọi hệ thống write() sử dụng để ghi dữ liệu vào file tương ứng với một mô tả file. #include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
Đối sốđầu tiên là số mô tả file được trả về từ lời gọi open() trước đó. Đối số thứ hai là con trỏ tới bộ đệm (để sao chép dữ liệu, có dung lượng đủ lớn để chứa dữ liệu) và đối số
thứ ba xác định số byte sẽđược ghi. write() trả về số byte đọc hoặc -1 nếu có lỗi xảy ra
Hàm ftruncate()
Lời gọi hệ thống ftruncate() cắt file tham chiếu bởi mô tả file fd với độ dài được xác
định bởi tham số length #include <unistd.h>
int ftruncate(int fd, size_t length);
Trả về giá trị 0 nếu thành công và -1 nếu có lỗi xảy ra.
Hàm lseek()
Hàm lseek() đặt vị trí đọc và ghi hiện tại trong file được tham chiếu bởi mô tả file files tới vị trí offset
#include <sys/types.h> #include <unistd.h>
off_t lseek(int fildes, off_t offset, int whence);
Phụ thuộc vào giá trị của whence, giá trị của offset là vị trí bắt đầu (SEEK_SET), vị trí hiện tại (SEEK_CUR), hoặc cuối file (SEEK_END). Giá trị trả về là kết quả của offset: bắt
đầu file, hoặc một giá trị của off_t , giá trị -1 nếu có lỗi.
Hàm fstat()
Hàm fstat () đưa ra thông tin về file thông qua việc mô tả các file, nơi kết quả của struct stat được chỉ ra ở con trỏ chỉđến buf().Kết quả trả về giá trị 0 nếu thành công và nhận giá trị -1 nếu sai ( kiểm tra lỗi).
#include <sys/stat.h> #include <unistd.h>
int fstat(int filedes, struct stat *buf); Sau đây là định nghĩa của struct stat:
struct stat {
dev_t st_dev; / * thiết bị */
int_t st_ino ; /* inode */
mode_t st_mode; /* chếđộ bảo vệ */
nlink_t st_nlink; /* số lượng các liên kết cứng */ uid_t st_uid; /* số hiệu của người chủ */ gid_t st_gid; /* số hiệu nhóm của người chủ*/ dev_t st_rdev; /* kiểu thiết bị */
off_t st_size;/* kích thước bytes */ unsigned long st_blksize; /* kích thước khối*/
unsigned long st_blocks; /* Số lượng các khối đã sử dụng*/ time_t st_atime; /* thời gian truy cập cuối cùng*/ time_t st_mtime; /* thời gian cập nhật cuối cùng */ time_t st_ctime; /* thời gian thay đổi cuối cùng */ };
Hàm fchown()
Lời gọi hệ thống fchown() cho phép tathay đổi người chủ và nhóm người chủ kết hợp với việc mở file.
#include <sys/types.h> #include <unistd.h>
int fchown(int fd, uid_t owner, gid_t group);
Tham sốđầu tiên là mô tả file, tham số thứ hai là sốđịnh danh của người chủ, và tham số thứ ba là sốđịnh danh của nhóm người chủ. Người dùng hoặc nhóm người dùng sẽđược
phép sử dụng khi giá trị -1 thay đổi. Giá trị trả về là 0 nếu thành công và –1 nếu gặp lỗi (kiểm tra biến errno).
Thông thường người dùng có thể thay đổi nhóm các file thuộc về họ. Chỉ root mới có quyền thay đổi người chủ sở hữu của nhiều nhóm.
Hàm fchdir( )
Lời gọi hàm fchdir( ) thay đổi thư mục bằng cách mở file được mô tả bởi biến fd. Giá trị trả về là 0 nếu thành công và –1 nếu có lỗi (kiểm tra biến errno).
#include <unistd.h> int fchdir(int fd); Một ví dụ về cách sử dụng các hàm thao tác với file: /* filedes_io.c */ #include <sys/types.h> #include <sys/stat.h> #include <sys/file.h> #include <fcntl.h> #include <unistd.h> #include < assert.h> #include <errno.h> #include <string.h>
#include <stdio.h> /*for print */
char sample1[] = “This is sample data 1\n”; char sample2[] = “This is sample data 2\n”; char data[16];
main ( ) {
int fd; int rc;
struct stat statbuf; printf( “Creating file\n”);
fd = open(“junk.out”, 0_WRONLY | 0_CREAT| 0_TRUNG, 0666); assert(fd>=0);
rc = write(fd, sample1, strlen(sample 1) ); assert(fd>=0);
rc = write(fd, sample1, strlen(sample1)); assert(rc == strlen(sample1));
printf(“ Appending to file\n”);
fd = open(“junk.out”, 0_WRONLY| 0_APPEND); assert(fd>=0);
printf( “ locking file\n”); rc = flock(fd, LOCK_EX); assert(rc == 0);
printf(“sleeping for 10 seconds\n”); sleep(10);
printf(“writing data\n”);
rc = write(fd, sample2, strlen(sample2)); assert(rc == strlen(sample2)); printf(“unlocking file\n”); rc = flock(fd, LOCK_UN); assert(rc == 0); close(fd); printf(“Reading file \n”); fd = open(“junk.out”, 0_RDONLY); assert (fd >=0); while (1) {
rc = read (fd, data, sizeof (data) ); if( rc > 0 )
{
data[rc] =0; /* kết thúc xâu */
printf (“ Data read (rc = %d): <%s>\n”, rc, data); }
else if (rc == 0) {
printf (“ End of file read \ n”); break;
} else {
perror ( “ read error ” ); break;
} }
close (fd);
printf (“ Fiddling with inode\n”); fd = open (“ junk.out”, 0_RDONLY);
assert (fd >= 0);
printf (“ changing file mode\n”); rc = fchmod ( fd, 0600);
assert (rc == 0);
if ( getuid ( ) == 0 ) {
printf ( “ changing file owner \n ” ); rc = fchown (fd, 99, 99);
assert (rc == 0); } else
{
printf ( “ not changing file owner\n”); }
fstat (fd, &statbuf);
printf (“ file mode = 0% ( octal ) \ n”, statbuf.st_mode); printf(“Owner uid = %d \ n”, statbuf.st_uid);
printf(“ Owner gid = %d \n”, statbuf.st_uid); close(fd);
}
7.3.4. Thư viện liên kết
Phần này sẽ giới thiệu cách tạo ra và sử dụng thư viện (các module chương trình đã
được viết và được tái sử dụng nhiều lần). Thư viện gốc của C/C++ trên Linux chính là
glibc, thư viện này cung cấp cho người dùng rất nhiều lời gọi hệ thống. Các thư viện trên Linux thường được tổ chức dưới dạng tĩnh (static library), thư viện chia sẻ (shared library) và động (dynamic library - giống như DLL trên MS Windows). Thư viện tĩnh được liên kết cố định vào trong chương trình trong quá trình liên kết. Thư viện dùng chung được nạp vào bộ nhớ trong khi chương trình bắt đầu thực hiện và cho phép các ứng dụng cùng chia sẻ loại thư viện này. Thư viện liên kết động được nạp vào bộ nhớ chỉ khi nào chương trình gọi tới.
7.3.4.1 Thư viện liên kết tĩnh
Thư viện tĩnh và các thư viện dùng chung (shared library) là các file chứa các file được gọi là các module đã được biên dịch và có thể sử dụng lại được. Chúng