160 likes | 323 Views
Today’s topic. Access and manipulate meta data for files File type, ownership, access permissions, access time, etc How to determine if a file is not there? How to find out the access permissions of a file? How to have the full control of permissions of the files you created in your program?
E N D
Today’s topic • Access and manipulate meta data for files • File type, ownership, access permissions, access time, etc • How to determine if a file is not there? • How to find out the access permissions of a file? • How to have the full control of permissions of the files you created in your program? • Operating on directories
How to determine if a file is not there? • Try ‘ls –l’, ‘lsaa’ • Get the meta data of a file: stat #include <sys/types.h> #include <sys/stat.h> int stat (const char *pathname, struct stat *buf) Intfstat(intfiledes, struct stat *buf) Intlstat(const char *filename, struct stat *buf) • This function fails when the file is not there • There are some other ways for it to fail, • man –a stat • When the function succeeds, buf stores the meta data for the file.
Struct stat { mode_t st_mode; /* file type & mode & permissions */ ino_t st_ino; /* file inode number */ dev_t st_dev; /* device number (file system) */ dev_t st_rdev; /* device number for special files */ nlink_t st_nlinks; /* number of links */ uid_t st_uid; /* owner user ID */ gid_t st_gid; /* owner group ID */ off_t st_size; /* size in bytes, for regular files */ time_t st_atime; /* time of the last access */ time_t st_mtime; /* time of the last modification */ time_t st_ctime; /* time of the last status change */ long st_blksize; /* best I/O block size */ long st_blocks; /* number of 512 byte blocks */ }; You can see most of the fields in the stat data structure with ls.
Files types (st_mode): • Regular (S_ISREG(buf.st_mode)) • Directory (S_ISDIR(..)) • Character special file (S_ISCHR(..)) • Block special file (S_ISBLK(..)) • FIFO (S_ISFIFO(..)) • Symbolic link (S_ISLNK(..)) • Socket (S_ISSOCK(..)) • See example1.c
Set-user-ID and set-group-ID (st_mode): • What permission should a process get when a program is executed? • The same permission as whoever runs it? • Not sufficient sometimes. Example? • Change effective user ID and group ID when executed. • The main use: allowing regular users to have root access. • Checking these bits (example1a.c) • S_ISUID & buf.st_mode, S_ISGID & buf.st_mode
File access permissions (st_mode) • user-read (S_IRUSR) • user-write (S_IWUSR) • user-execute(S_IXUSR) • group-read (S_IRGRP) • group-write (S_IWGRP) • group-execute(S_IXGRP) • other-read (S_IROTH) • other-write(S_IWOTH) • other-execute(S_IXOTH) • See example2.c
Creating file with customized permissions. • Can specify permission in the creat and open calls. • See example3.c • There is a default file mode creation mask. • Try ‘umask’ • The bits that are 1’s are turned-off. • The mask can be manipulated in the program, see example4.c. #include <sys/types.h> #include <sys/stat.h> Mode_t umask(mode_t cmask);
Change mode and change owner • chmod and chown, both as command lines and as system calls. • Remove a file without write perssion, see example5a.c • Read a file without the read permission, see example5.c (as long as you are the owner). • Remove and rename files: #include <stdio.h> int remove(const char *path); /* C function, same as link */ int rename(const char *oldname, const char *newname) /* also a C function */
Hard link and symbolic link of a file: • Hard link of a file is to create a new directory entry with the same inode number. • Hard link is not allowed for a directory (to avoid loops in the directory’s tree structure). • In struct stat, the st_nlinksfield records the number of directory entries pointing to the inode for the file. • Link/unlink are both command line and system calls #include <unistd.h> int link(const char *existingpath, const char *newpath) /* create a new entry in the directory with the same inode number */ /* similar to copy, what is the difference?*/ int unlink(const char *path);
Symbolic link • The link function creates a “hard link”: • (newname, inode number) in a directory • If not done carefully, can be a problem (destroy the tree structure of the directories) • Not allow to create a hard link on directories • Symbolic link, which is an indirect pointer to a file, gets around the problem • need to be careful whether a function follow the symbolic link • Unlink do not follow symbolic link (only the symbolic link is removed), open follow the symbolic link by default.
Symbolic link • Try the following ‘ln –s /no/such/file myfile’ ‘ls myfile’ ‘cat myfile’ ‘ls –l myfile’ • System calls: #include <unistd.h> int symlink(const char *actualpath, const char *sympath); int readlink(const char *pathname, char *buf, int bufsize);
File times • st_atime: last access time • st_mtime: last modification time • st_ctime: last status change time • Try: ‘ls –u -l’, ‘ls –c -l’ • The access time and modification time can be changed with the utime function. See example6.c.
Random access files • Current file offset can be manipulated with lseek calls, see example7.c. • Try ‘more hole001’ and ‘od –c hole001’. #include <sys/types.h> #include <unistd.h> off_t lssek(int filedes, off_t offset, int whence) whence = SEEK_SET, SEEK_CUR, SEEK_END
Operating on directories • Only root can write, all other can only read (or write implicitly through system calls). #include <sys/types.h> #include <dirent.h> DIR *opendir(const char *name) struct dirent *readdir(DIR *dp); void revinddir (DIR *dp); int closedir(DIR *dp)
Operating on directories #include <sys/types.h> #include <dirent.h> struct dirent *readdir(DIR *dp); struct dirent { ino_t d_ino; char *d_name[NAME_MAX+1]; } • Return NULL when reaching the end of the directory. • Example: implementing the ‘find’ command, see example8.c
Current Working Directory • Can be changed using • intchdir(const char *pathname); • intfchdir(intfiledes); • Note that they only affect the current process’ working directory • Obtaining current working directory • char *getcwd(char *buf, size_t size);