<<

Agenda

• Working with files and directories – lseek – stat, fstat, lstat – access Working with Files and – link, , rename – symlink, readlink – , – chdir, fchdir, getcwd • Bibliography – Stevens chapter 4 – man pages

lseek() offset reposition read/ file offset • Every open file has an associated “current file • off_t lseek(int fildes, off_t offset, int whence) offset” • whence can be • This is a nonnegative integer that measure the – SEEK_SET : the offset is set to offset bytes – SEEK_CUR : the offset is set to its current location plus offset number of bytes from the beginning of the file butes • Read and Write operations normally starts the – SEEK_END : the offset is set to the size of the file plus offset current file offset and cause the offset to be bytes • It is possible to set the file offset beyond the size of the incremented file. This is referred to as creating a hole in a file. • By default the current file offset is set to 0 when • Any bytes that have not been written are read back as 0 the file is opened (except when the O_APPEND option is used) offset 0 end of file data hole data

Files with holes Seek (cont …)

char buff1[]="abcdefghij"; char buff2[]="ABCDEFGHIJ";

int main() • It is not possible to perform seek on every file, for { int fd; example on terminals it is not possible to seek

if ((fd = open("/tmp/file.hole", O_CREAT | O_TRUNC | O_WRONLY, 0755)) == -1) • The following program if seek can be done { perror("Error in open\n"); (1); int }

if (write(fd, buff1, 10) != 10) main()

4 4 4

{ abcdefghij 1212131213121 ABCDEFGHIJ

576 8 8:9 ;:< 836 < { 5

perror("Error in write\n");

=2>3?

8 8:9 if(lseek(STDIN_FILENO, 0, SEEK_CUR) == -1) <@6

exit(1);

>

D2D 82E DF6 82839

perror("Cant seek\n"); ACB

¡ ¢ ¢ £ £ ¤ ¤ ¥ ¥ ¦ ¦ £ £ § § ¨ ¨ © ©           £ £ § § § §   ¦ ¦   ¡ ¡   § § ££       ¦ ¦     ¢ ¢ ¡ ¡       £ £ ¡ ¡  

} ¡

¡ ¡ ¢ ¢ £ £ ¤ ¤ ¥ ¥ ¦ ¦ £ £ § § ¨ ¨ © ©           £ £ § § § §   ¦ ¦   ¡ ¡   § § ££         ¦ ¦     ¢ ¢ ¡ ¡       £ £ ¡ ¡  

        ! ! ¢#"%$¢#" $ $ $ $ $ $ $ $ $ $ $

                         

        ! ! ¢#"¢#" $ $ $ $ $ $ $ $ $ $ $ $

                        

if (lseek(fd, 40, SEEK_SET) == -1)  else

¨ ¨ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $

                                           

¨ ¨ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $

                                          

{  >>seek_test < /etc/fstab

$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $

                           &' ( &' ( ) ) * * +#,+#, - -

$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $

                          &' ( &' ( ) ) * * +#,+#, - -

perror("Error in lseek()\n");  ("seek OK\n");

          . .   / / 0 0

         . .   / / 0 0

exit(1);  seek OK

¨ ¨

          . .

¨ ¨

          . . } return 0; >> if (write(fd, buff2, 10) != 10) { } perror("Error in write\n"); exit(1); } return 0;

}

stat(), fstat() and lstat() stat() fstat() and lstat() (continued) file information • int stat(const char *file_name, struct stat *buf); • stat() return information about the named file • int fstat(int filedes, struct stat *buf); • int lstat(const char *file_name, struct stat *buf); • fstat() return information about an open file

• lstat() return information about the ,

¡ ¢ £ ¤ ¥ ¢¦¡ ¢ § ¢ ¨

© ©   ©   

¡ ¢ ¥

¢ not the file referenced by the symbolic link

          ©  

¢ ¡ ¢

 ©  ©        

 ¢ ¡ ¢  £ ¢ ¥ ¢

           ¦  ¦ ©     

¢ ¡ ¢ ¤   £ §£ ¡

 ©  ©!     %   

¤ ¢ ¡ ¢ ¤ ¤ ¡ £#" $ £

 ©  ©!       %  

& ¢ ¡ ¢ & & £ ¤ " $ £

© © '  ©   *)     © ©  + 

¢ ¡ ¢ £ ¥ ¢ ( ¥

  ,       , -.   

¢ ¡ ¢ ¡ ¢ ¢ § ¡  ( ¢ ¡

   ©      , ! /      ,      0¦ 

¤ ¡ & &¦¡ ¢  ¡  ¥ ¡ £ ¡ ( ¡ ¢ ¦"

   ©      1 ¦        © 

¤ ¡ & &¦¡ ¢  ¥ ¡ ¤   £  ¥ ¡§ ¥ § ¢

  !       

¢  ¢ ¡ ¢ § ¢  ¢  § ¡ ¢§ ¥ ¥ ¡ ¡

  !       ©      

¢  ¢ ¡ ¢  ¢  ¢  § ¡ ¢ ¥ § ¢

  !        

¢  ¢ ¡ ¢ ¥ ¢  ¢  § ¡ ¢¥ § & 2

File types File types (cont…)

• Regular file : The most common of file, there is no • The type of a file is encoded in the st_mode distinction to the Unix kernel whether the data is text or member of the stat structure binary • The following macros can be used to determine • Directory file : A file that contains the names of other files the file type: and pointers to information on these files – S_ISREG(m) is it a regular file? • Character special file : A type of file used for certain – S_ISDIR(m) directory? types of devices – S_ISCHR(m) character device? • Block special file : A type of file used for disk devices – S_ISBLK(m) block device? • FIFO : A type of file used for interprocess communication – S_ISFIFO(m) fifo? between processes (also known as named pipe) – S_ISLNK(m) symbolic link? (Not in POSIX.1-1996.) • Socket : A type of file used for network communication – S_ISSOCK(m) socket? (Not in POSIX.1-1996.) between processes • Symbolic link : A type of file that points to another file

Set-User-ID and Set-Group-ID Set-User-ID (cont..)

• Every process has six IDs associated with it • This feature is useful when we want a user to execute a certain

ACBDEA=6/467'8'8FG7C4 6

35467'8:9<;6=4?>@ program in super-user permission D'9'J:>@

35467'8EHI4 • For example passwd is a set-uid file

                  % ©

£ Y  ¡ Z [ \'] ^ ¢ § ¥ ¡ ¡ §  ¡ _ ¡` § ¤ ¡ £  § ¡ ¡

3/6'K'K6'L!M@ 9<;6!PQKDC4EKN'86:7'LL'6<;;

   

` £ ` a a ` ` b ` ` bc[d£ ¢e£ ¢ [ f \ g hji ¤ &kglZ m m [

a a

3/6'K'K6'L!M

      % © 

¤ ¡ £  § ¡ ¡

3R;!7O<6PG;6!M=S!9<;6=4!S!>@ ;!7O<6PQTF/6U=6LQK9V'LM'ND'V

3R;!7O<6PG;6!M=SWX4 D'9'J'S>!@ • Normally the effective user id equal the real user id • The set-user-id (set-group-id) bit are contained in the st_mode • Every file has an owner, the owner is specified by the st_uid member of the stat structure member • The constant S_ISUID (S_ISGID) can be used to test this bit • There is a capability to set a special flag in the file’s mode word (st_mode) that says “when the file is executed set the effective uid of

the process to the owner of the file”

File Access Permissions access()

• The st_mode also encode the st_mode mask Meaning • int access(const char *pathname, int mode); file permissions bits S_IRUSR User read • from the shell the command • access checks whether the process would be allowed to can be used to change S_IWUSR User write read, write, execute the file or test for existence file permissions S_IXUSR User execute • mode is a mask of one or more of: • whenever we want to open any type of file by name, we must S_IRGRP Group read – R_OK test for read permission have execute permissions on – W_OK test for write permission S_IWGRP Group write the directories in the name – X_OK test for execute permission • we cannot create a new file in S_IXGRP Group execute – F_OK test for existence of file a directory unless we have write and execute permissions S_IROTH Other read • The check is done with the process’s real uid and gid, in the directory S_IWOTH Other write rather then with the effective id’s. This is to allow set-UID • to delete a file we need write programs to easily determine the invoking user authority and execute permission in the S_IXOTH Other execute directory

umask() File system structure

• mode_t umask(mode_t cmask); disk partition partition partition • Every process has a file mode creation mask drive • The umask() function set the file mode creation mask for the process and return the previous value file • The file mode creation mask is used whenever the i-list directory blocks and data blocks system process creates a new file or a new directory • recall that the open() functions get a mode argument boot block • Any bits that are on in the file mode creation mask are super block turned off in the file’s mode

i-node i-node ¡¢¡¢¡ i-node i-node

File System structure (cont…) Hard Links

i-list data data directory directory block block block block • i-nodes are fixed-length entries that contain most of the information about a file k ck c blo lo ta b da • directory entry contain the i-node number and the file- ta t a irs d f t name rs fi i-node file name • we can see 2 directory entries that point to the same i- i-node i-node i-node i-node number node entry. This is a • from the shell the command “” can be used to create hard links i-node file name number • Every i-node has a link-count , which is the number of directory entries that point to this i-node • Only when the link count reach 0 the file can be deleted

• What is the initial link-count of a new empty directory??

link(), unlink() and rename() Temporary files

• int link(const char *oldpath, const char *newpath); • A process can open a temporary file, unlink it and continue to work • int unlink(const char *pathname); with it. • int rename(const char *oldpath, const char *newpath); • The files data will be removed only when the process exit • This feature can be used by programs to assure that temporary files • link() create a new directory entry that point to the same inode won’t be left around in case the program crashes

oldpath is pointing

©¢¡   ) £       £ - 0 ¤ ¤§¦I0 ¨ ¤ © ¦ 0 ¤ ¨- +

 ¢  $ ¥ i m g

• The creation of the directory entry and the increment of the link ¢

 ) ©¢¡ ¡ + [

count must be atomic why?? `

© ¤ ¤ 0 ¤ ) £ ©   j     £ +

  

£ £ £

 )      ) £       £ +¢¡ ¡ +

¢  ¢  ` [

• unlink() remove a directory entry and decrement the i-node link ¤

© ¤ ¤ 0 ¤ ) £ ©         £ +

  

£ £ ¤

count £

      %  #%       

£ & £ § ¦¥ ¢ ¤ ¢ £ ¢ ¢ • If the link count reach 0 the i-node is removed ¢ • not exactly, only when no process holds the file open that file can be removed

Symbolic Links Symbolic Links (cont…)

• Hard links have several limitations • Functions that follow symbolic links – hard links can not exists across file systems – access(), chdir(), exec(), link(), open(), stat() … – Only the super user can create hard links to directories (in Linux • Functions that does not follow symbolic links even this is not possible) – (), lstat(), rename(), unlink() • A symbolic link is an indirect pointer to a file

The file • Symbolic links can exists to files that do not /tmp/big_file content – ln –s /no/such/file myfile (this is legal) • Symbolic links can point to directories and create loops • When using functions that refer to files by name we – mkdir foo foo always need to know whether the function follow a – foo/a symbolic link or not (written in the function manually) – ln –s ../foo foo/testdir

a testdir

Symbolic links (cont …) File Times

• int symlink(const char *oldpath, const char *newpath); • Tree fields are maintained for each file • symlink() is used to create symbolic links Field Description Example option • It is not required that oldpath exists when the symbolic st_atime Last-access time of file data read -u link is created st_mtime Last-modification time of file data write default • Also oldpath and newpath need not reside in the same file system st_ctime Last-change time of i-node status chmod -c • int readlink(const char *path, char *buf, size_t bufsiz); • Since open follow symbolic links we need a way to open • Note the deference between ctime and mtime the link itself and read the name in the link • Which time field access() and stat() change???

• The function combine open(), read() and close()

utime() mkdir() and rmdir()

• int utime(const char *filename, struct utimbuf *buf); • int mkdir(const char *pathname, mode_t mode); • struct utimbuf { • mkdir() created new empty directory time_t actime; /* access time */ • . and .. are automatically added to the new dir time_t modtime; /* modification time */ }; • int rmdir(const char *pathname); • An empty directory is deleted with rmdir() • utime() change the access and modification time of a file • If buf is NULL the time is set to the current time • There is no way to change ctime

chdir(), fchdir() and getcwd() statfs() and fstatfs()

• Every process has a current working directory • int statfs(const char *path, struct statfs *buf); • int fstatfs(int fd, struct statfs *buf); • This directory is where the search for all relative

pathnames starts • Those functions return information about the file system

>

<¢¡ £ ¤ <@6 < <¦¥26¨§

• 6

?

© E ¥ ;3< 8  < 8©¦¥¨¥¦2D 836 :6 < 8  6 8 8¨ 82D © ¢¨ 

– A relative path name is a path name that do not start with a “/” D

? > >2?

D © E ¥ ;¢26  28 ©¢ <   DF<¢¡ 6 ¥28 ¡ D © ¤39 6   8¨ 

> > > ?

• We can change the current working directory using ?

D © E ¥ ;¢2D ©¢¤39 6   < ©2< D! < 2D ©¢¤39 6" ¥¦2D 8@6 36 < 8 # 

? ?

© E ¥ ;¢ ¥¢¡ 828 ¥ ¡ 828¨ D ©¢¤29 6" ¥26" 

– int chdir(const char *pathname) D

? > $3> > $3> ? ? %

D © E ¥ ;¢  D  ¥ ¡ 828¨ D ©¢¤29 6  D < © © 6 £¦ 8 ¡ £26 8 ¡ 

> ? ?

– int fchdir(int filedes); ?

D © E ¥ ; ¥  D 836&  < ©2< D¥ 2D 8 ©¦!2836" ¥  D 8@6 :6 <28 # 

? ? ?

© E ¥ ; ¥¦¥¢¡ 828 ¥ ¡ 828"¥¦2D 8 © ! 836" ¥26" 

• We can get the current working directory using D

¥36  ! ;:<'¥ ; ¥36  ! ¥  D 8@6 :6 < 8 # !# 

? ? > ? > ) ? ? >

© E ¥ ; 383D 8 (   ¢£  D 8 E2<¦*©¦¥"¥  D 8 3826" 

– char *getcwd(char *buf, size_t size); D

? > > >

D © E ¥ ;:6¦ ¡ 8+ , -. F6¦ ¡ 8"¥ ©&¡%D < 8 ¡ 

/