本章讨论了不带缓存IO的各文件操作。
1. stat 函数族。
int stat(const char* pathname, struct stat* buf)
int fstat(int fd, struct stat* buf)
int lstat(const char* pathname,struct stat* buf) //lstat 返回连接的属性
struct stat 结构体成员:
struct stat
{
mode_t st_mode; // file type & mode, permittion
ino_t st_ino ; //文件系统i节点号
dev_t st_dev ;//文件设备号
dev_t st_rdev; //特殊文件的文件设备号
nlink_t st_nlink; //链接数量
uid_t st_uid; // uid
gid_t st_gid; //gid
off_t st_size; //文件bytes.
time_t st_atime; //上次访问时间, read操作便可
time_t st_mtime; //修改时间
time_t st_ctime; // chown, chmod,文件夹操作等
long st_blksize; //文件块大小
long st_blocks; //512 byte 的块数目
}
普通文件, 目录,FIFO,socket, 字符特殊文件, 块特殊文件,符号链接。
测试文件类型的demo.
#include
#include
#include
#include
#include
int main(int argc, char* argv[])
{
struct stat buf;
char* ptr;
int i;
for(i=1;i< argc;i++)
{
if (lstat(argv[i],&buf)==-1)
{
printf("can not lstat file. %s", argv[i]);
continue;
}
if (S_ISREG(buf.st_mode)) ptr="regular";
else if (S_ISDIR(buf.st_mode)) ptr="directory";
else if(S_ISCHR(buf.st_mode)) ptr="character";
else if (S_ISBLK(buf.st_mode)) ptr="bulk";
else if (S_ISFIFO(buf.st_mode)) ptr="FIFO";
else if (S_ISLNK(buf.st_mode)) ptr="LINK";
else if (S_ISSOCK(buf.st_mode)) ptr="SOCKET";
else
ptr ="unknown";
printf("file %s is %s\n",argv[i],ptr);
}
exit(0);
}
用户ID分为实际用户ID, 有效用户ID,设置用户ID。
文字描述苍白无力,套用以前某领导一句话,上代码。
#include
#include
int main()
{
printf("uid is %d\n", getuid());
printf("euid is %d\n", geteuid());
}
以非root用户编译,执行。
得到结果504 504
执行chown root:root a.out; chmod u+s a.out
再以非root 用户运行
得到结果 504 0
4. 文件许可权限
st_mode 包含了9位的文件许可权限。
文件许可权限的6个规则:
#include
#include
#include
#include
#include
int main(int argc, char* argv[])
{
if(argc<2)
{
printf("need two argument\n");
exit(-1);
}
if(access(argv[1],O_RDONLY)<0)
{
printf("read %s not ok\n", argv[1]);
}
else
printf("read %s ok\n", argv[1]);
}
#include
#include
#include
#include
#include
int main()
{
umask(0);
if(creat("foo", S_IRUSR| S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)<0)
{
printf("create file error\n");
}
umask(S_IRUSR| S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if(creat("bar", S_IRUSR| S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)<0)
{
printf("create file error\n");
}
}
#include
#include
int chmod(const char* pathname, mode_t mode)
int fchmod(int fileds, mode_t mode)
#include
#include
#include
#include
#include
int main()
{
struct stat buf;
if(stat("foo", &buf)<0)
{
printf("stat error. %d\n",errno);
exit(-1);
}
if(chmod("foo",buf.st_mode & ~ S_IWGRP)<0)
{
printf("chmode error. %d\n",errno);
exit(-1);
}
}
粘住位的简单demo
mkdir stick
chmod 777 stick
cd stick/
touch 1.txt
chmod 777 1.txt
su test
rm -rf 1.txt //成功
mkdir stick
chmod 777 stick
chmod +t stick/
cd stick/
touch 1.txt
chmod 777 1.txt
su test
rm -rf 1.txt //失败
#include
#include
int chown(const char* pathname,uid_t owner,gid_t group)
int fchown(int fd, uid_t owner, gid_t group)
int lchown(const char* pathname, uid_t owner, gid_t group)
#include
#include
#include
int main()
{
if (truncate("1.log",0)<0)
printf("truncate error\n");
}
文件自举块和超级块作用:
超级快存储了整个文件系统的信息。填满和空的块。
两种经典的unix v系统文件系统的概图
14. unlink和link函数
#include
#include
#include
#include
#include
#include
int main()
{
if(open("/tmp/t.log", O_RDWR | O_CREAT)<0)
{
printf("open file error\n");
exit(-1);
}
if(unlink("/tmp/t.log")<0)
{
printf("unlink file error\n");
exit(-1);
}
printf("unlink file \n");
sleep(15);
exit(0);
}
#include
int rename(const char* oldname, const char* newname)
int remove(const char* pathname)
int syslink(const char* actualpath,const char* syspath)
int readlink(const char* syspath, char* buf, int bufsize)
#include
#include
int utime(const char* pathname,const struct utimebuf* buf)
struct utimbuf
{
time_t actime;
time_t modtime;
}
#include
#include
#include
#include
#include
int main()
{
const char* filepath = "/tmp/1.log";
struct stat buf;
if(stat(filepath,&buf)<0)
{
printf("stat error\n");
return -1;
}
if(open(filepath, O_RDWR|O_TRUNC)<0)
{
printf("truncate file error\n");
return -1;
}
struct utimbuf ub;
ub.actime = buf.st_atime;
ub.modtime= buf.st_mtime;
if(utime(filepath,&ub)<0)
{
printf("utmie error\n");
return -1;
}
}
#include
#include
#include
#include
int mkdir(const char* path, mode_t mode)
int rmdir(const char* path)
DIR* opendir(const char* pathname)
struct dirent *readdir(DIR* dp)
void rewinddir(DIR* dp)
int closedir(DIR* dp)
#include
int chdir(const char* pathname)
int fchdir(int filedes)
char* getcwd(char* buf,size_t size)
获得当前目录demo:
#include
#include
char buf[1024];
int main()
{
if(chdir("/tmp/")<0)
{
printf("change directory error\n");
return (-1);
}
if(getcwd(buf,1024)<0)
{
printf("getcwd directory error\n");
return (-1);
}
printf("directory is %s\n",buf);
}