Linux系统编程 40 open函数
学习笔记
函数原型:
int open(const char *pathname, init flags);
int open(const char *pathname, int flags,mode_t mode);
int close(int fd);
open 成功的时候,会返回一个整数
失败的时候,会返回-1
pathname : 文件路径
flags : 读写权限
mode : 用户 用户组 其他用户的权限 八进制形式
权限同时受umask的影响
文件权限=mode&~umask
两个版本的区别:
第一个open用于打开已经存在的文件
第二个open用于打开不存在的文件
常用的参数
O_RDONLY
O_WRONLY
O_RDWR
O_APPEND 防止清空,在末尾添加
O_CREAT
O_EXCL 是否存在
O_TRUNC 把文件截断成0.就是把文件清零
O_NONBLOCK 不阻塞
先创建文件
$touch dict.txt
小细节:
#include <sys/types.h>
#include <sys/stat.h>
这两个头文件可以用#include<unistd.h> //#unix stdandard 来替换
$cat open.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<unistd.h> //#unix stdandard
int main(int argc, char *argv[])
{
int fd;
fd = open("./dict.txt",O_RDONLY);
printf("fd = %d\n",fd);
close(fd);
return 0;
}
$gcc open.c -o open
open.c: In function ‘main’:
open.c:10:25: error: ‘O_RDONLY’ undeclared (first use in this function)
fd = open("./dict.txt",O_RDONLY);
^
open.c:10:25: note: each undeclared identifier is reported only once for each function it appears in
添加头文件
#include<fcontl.h>
$gcc open.c -o open
$./open
fd = 3
打开一个不存在的文件
修改代码如下:
$cat open.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<unistd.h> //#unix stdandard
#include<fcntl.h>
int main(int argc, char *argv[])
{
int fd;
//fd = open("./dict.txt",O_RDONLY);
fd = open("./dict.cpp",O_RDONLY | O_CREAT,0644);//rw -r-r-
printf("fd = %d\n",fd);
close(fd);
return 0;
}
可以看到dict.cpp的权限和设计意图一样。
$gcc open.c -o open
$ls
dict.txt open open.c
$./open
fd = 3
$ls
dict.cpp dict.txt open open.c
$ll
total 24
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 13 22:36 ./
drwxrwxrwx 10 root root 4096 Dec 13 22:16 ../
-rw-r--r-- 1 ubuntu ubuntu 0 Dec 13 22:36 dict.cpp
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 13 22:23 dict.txt
-rwxrwxr-x 1 ubuntu ubuntu 8621 Dec 13 22:36 open*
-rw-rw-r-- 1 ubuntu ubuntu 860 Dec 13 22:35 open.c
O_TRUNC 用于清空文件内容
现在在dict.cpp文件中添加内容
$cat dict.cpp
sfajfljlfjasdflas
eerqewr
e
sad
f
asdfdfasdfadsg
as
fs
df
ads
fsad
f
as
gagadsaghfjk
$vi dict.cpp
$ll
total 28
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 14 08:58 ./
drwxrwxrwx 10 root root 4096 Dec 13 22:16 ../
-rw-r--r-- 1 ubuntu ubuntu 598 Dec 14 08:58 dict.cpp
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 13 22:23 dict.txt
-rwxrwxr-x 1 ubuntu ubuntu 8621 Dec 13 22:36 open*
-rw-rw-r-- 1 ubuntu ubuntu 934 Dec 14 08:56 open.c
修改程序 open.c
$vi open.c
$cat open.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<unistd.h> //#unix stdandard
#include<fcntl.h>
int main(int argc, char *argv[])
{
int fd;
//fd = open("./dict.txt",O_RDONLY);
//fd = open("./dict.cpp",O_RDONLY | O_CREAT,0644);//rw -r-r-
fd = open("./dict.cpp",O_RDONLY | O_CREAT| O_TRUNC,0644);//rw -r-r-
printf("fd = %d\n",fd);
close(fd);
return 0;
}
fd = open("./dict.cpp",O_RDONLY | O_CREAT| O_TRUNC,0644);//rw -r-r-
这个函数的意思是
1.如果文件不存在,这以指定的权限创建一个文件
2.如果文件存在,以只读方式打开,并截断成0.则该文件清空
$gcc open.c -o open
l$ls
dict.cpp dict.txt open open.c
$./open
fd = 3
$ll
total 24
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 14 09:01 ./
drwxrwxrwx 10 root root 4096 Dec 13 22:16 ../
-rw-r--r-- 1 ubuntu ubuntu 0 Dec 14 09:01 dict.cpp
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 13 22:23 dict.txt
-rwxrwxr-x 1 ubuntu ubuntu 8621 Dec 14 09:01 open*
-rw-rw-r-- 1 ubuntu ubuntu 928 Dec 14 09:00 open.c
文件被清空(没有内容)
$cat dict.cpp
$
查看文件权限
$umask
0002
修改程序
$cat open.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<unistd.h> //#unix stdandard
#include<fcntl.h>
int main(int argc, char *argv[])
{
int fd;
//fd = open("./dict.txt",O_RDONLY);
//fd = open("./dict.cpp",O_RDONLY | O_CREAT,0644);//rw -r--r--
// fd = open("./dict.cpp",O_RDONLY | O_CREAT| O_TRUNC,0644);//rw -r--r--
fd = open("./dict.cp2",O_RDONLY | O_CREAT| O_TRUNC,0777);//rwxrwxrwx
printf("fd = %d\n",fd);
close(fd);
return 0;
}
$gcc open.c -o open
$ls
dict.cpp dict.txt open open.c
$./open
fd = 3
$ls
dict.cp2 dict.cpp dict.txt open open.c
$ll
total 24
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 14 12:43 ./
drwxrwxrwx 10 root root 4096 Dec 13 22:16 ../
-rwxrwxr-x 1 ubuntu ubuntu 0 Dec 14 12:43 dict.cp2*
-rw-r--r-- 1 ubuntu ubuntu 0 Dec 14 09:01 dict.cpp
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 13 22:23 dict.txt
-rwxrwxr-x 1 ubuntu ubuntu 8621 Dec 14 12:43 open*
-rw-rw-r-- 1 ubuntu ubuntu 1007 Dec 14 12:42 open.c
777&(~002)=775 rwxrwx-wx 符合设计意图
open常见的错误
1.打开的文件不存在,返回值为-1
$cat open.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<unistd.h> //#unix stdandard
#include<errno.h>
#include<fcntl.h>
int main(int argc, char *argv[])
{
int fd;
//fd = open("./dict.txt",O_RDONLY);
//fd = open("./dict.cpp",O_RDONLY | O_CREAT,0644);//rw -r-r-
// fd = open("./dict.cpp",O_RDONLY | O_CREAT| O_TRUNC,0644);//rw -r-r-
//fd = open("./dict.cp2",O_RDONLY | O_CREAT| O_TRUNC,0777);//rwx -rwx-wxr-
fd = open("./dict.cp4",O_RDONLY);
printf("fd = %d errno=%d\n",fd,errno);
close(fd);
return 0;
}
$gcc open.c -o open
$./open
fd = -1 errno=2
errno =2的含义可以通过
char *strerror(int errnum);(要加string.h)翻译出来
$cat open.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<unistd.h> //#unix stdandard
#include<errno.h>
#include<fcntl.h>
int main(int argc, char *argv[])
{
int fd;
//fd = open("./dict.txt",O_RDONLY);
//fd = open("./dict.cpp",O_RDONLY | O_CREAT,0644);//rw -r-r-
// fd = open("./dict.cpp",O_RDONLY | O_CREAT| O_TRUNC,0644);//rw -r-r-
//fd = open("./dict.cp2",O_RDONLY | O_CREAT| O_TRUNC,0777);//rwx -rwx-wxr-
fd = open("./dict.cp4",O_RDONLY);
printf("fd = %d errno=%d %s \n",fd,errno,strerror(errno));
close(fd);
return 0;
}
$gcc open.c -o open
$./open
fd = -1 errno=2 No such file or directory
2.以写方式打开只读文件(打开文件没有对应的权限)
$touch dict.cp3
$ll
total 24
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 14 12:59 ./
drwxrwxrwx 10 root root 4096 Dec 13 22:16 ../
-rwxrwxr-x 1 ubuntu ubuntu 0 Dec 14 12:43 dict.cp2*
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 14 12:59 dict.cp3
-rw-r--r-- 1 ubuntu ubuntu 0 Dec 14 09:01 dict.cpp
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 13 22:23 dict.txt
-rwxrwxr-x 1 ubuntu ubuntu 8737 Dec 14 12:57 open*
-rw-rw-r-- 1 ubuntu ubuntu 1102 Dec 14 12:56 open.c
$chmod u-w dict.cp3
$ll
total 24
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 14 12:59 ./
drwxrwxrwx 10 root root 4096 Dec 13 22:16 ../
-rwxrwxr-x 1 ubuntu ubuntu 0 Dec 14 12:43 dict.cp2*
-r--rw-r-- 1 ubuntu ubuntu 0 Dec 14 12:59 dict.cp3
-rw-r--r-- 1 ubuntu ubuntu 0 Dec 14 09:01 dict.cpp
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 13 22:23 dict.txt
-rwxrwxr-x 1 ubuntu ubuntu 8737 Dec 14 12:57 open*
-rw-rw-r-- 1 ubuntu ubuntu 1102 Dec 14 12:56 open.c
$vim open.c
$cat open.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<unistd.h> //#unix stdandard
#include<errno.h>
#include<fcntl.h>
int main(int argc, char *argv[])
{
int fd;
//fd = open("./dict.txt",O_RDONLY);
//fd = open("./dict.cpp",O_RDONLY | O_CREAT,0644);//rw -r-r-
// fd = open("./dict.cpp",O_RDONLY | O_CREAT| O_TRUNC,0644);//rw -r-r-
//fd = open("./dict.cp2",O_RDONLY | O_CREAT| O_TRUNC,0777);//rwx -rwx-wxr-
//fd = open("./dict.cp4",O_RDONLY);
fd = open("./dict.cp3",O_WRONLY);
printf("fd = %d errno=%d %s \n",fd,errno,strerror(errno));
close(fd);
return 0;
}
$gcc open.c -o open
$./open
fd = -1 errno=13 Permission denied
$
3.以只写方式打开目录
程序为
$cat open.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<unistd.h> //#unix stdandard
#include<errno.h>
#include<fcntl.h>
int main(int argc, char *argv[])
{
int fd;
//fd = open("./dict.txt",O_RDONLY);
//fd = open("./dict.cpp",O_RDONLY | O_CREAT,0644);//rw -r-r-
// fd = open("./dict.cpp",O_RDONLY | O_CREAT| O_TRUNC,0644);//rw -r-r-
//fd = open("./dict.cp2",O_RDONLY | O_CREAT| O_TRUNC,0777);//rwx -rwx-wxr-
//fd = open("./dict.cp4",O_RDONLY);
//fd = open("./dict.cp3",O_WRONLY);
fd = open("./mydir",O_WRONLY);
printf("fd = %d errno=%d %s \n",fd,errno,strerror(errno));
close(fd);
return 0;
}
$mkdir mydir
$vim open.c
$gcc open.c -o open
$./open
fd = -1 errno=21 Is a directory