+ All Categories
Home > Documents > System Programming

System Programming

Date post: 11-Jan-2016
Category:
Upload: jolie
View: 18 times
Download: 1 times
Share this document with a friend
Description:
System Programming. Chapter 4 Files and Directories. Fun Projects. Communicating intimacy vs. communicating verbal messages Lovers’ cups, drinking interfaces (MIT media Lab) Emotional (Crying) Décor (NYU) Interactive Pillow (TII, Sweden) Hand holding (Cornell). More Fun Project. - PowerPoint PPT Presentation
Popular Tags:
61
1 System Programming Chapter 4 Files and Directories
Transcript
Page 1: System Programming

1

System Programming

Chapter 4Files and Directories

Page 2: System Programming

2

Fun Projects

• Communicating intimacy vs. communicating verbal messages

• Lovers’ cups, drinking interfaces (MIT media Lab)

• Emotional (Crying) Décor (NYU)

• Interactive Pillow (TII, Sweden)

• Hand holding (Cornell)

Page 3: System Programming

3

More Fun Project

• Do you feel confused in the classroom?• Do you feel bored in the classroom?• Do you feel ignored in the classroom? • Do you feel unfairness that only the speaker has

control of the slides?

• Now … you can express frustration with the Active Slides!

Page 4: System Programming

4

Files and Directories

• Objectives– Additional Features of the File System– Properties of a File.

• Three major functions:

#include <sys/types.h>

#include <sys/stat.h>

int stat(const char *pathname, struct stat *buf);

int fstat(int filedes, struct stat *buf);

int lstat(const char *pathname, struct stat *buf);

Page 5: System Programming

5

Files and Directories

• Differences on stat(), fstat(), lstat():– lstat() returns info regarding the symbolic link, instead of the referen

ced file, if it happens.struct stat {

mode_t st_mode; /* type & mode */

ino_t st_ino; /* i-node number */

dev_t st_dev; /* device no (filesystem) */

dev_t st_rdev; /* device no for special file */

nlink_t st_nlink; /* # of links */

uid_t st_uid; gid_t st_gid;

off_t st_size; /* sizes in byes */

time_t st_atime; /* last access time */

time_t st_mtime; /* last modification time */

time_t st_ctime; /* time for last status change */

long st_blk_size; /* best I/O block size */

long st_blocks; /* number of 512-byte blocks allocated */

};

Page 6: System Programming

6

File Types

• Encoded in st_mode• Regular Files: text, binary, etc.• Directory Files: Only Kernel can update these files – { (f

ilename, pointer) }.• Character Special Files, e.g., tty, audio, etc.• Block Special Files, e.g., disks, etc.• FIFO – named pipes• Sockets – not POSIX.1 or SVR4

– SVR4 uses library of socket functions, instead. 4.3+BSD has a file type of socket.

• Symbolic Links – not POSIX.1 or SVR4

Page 7: System Programming

7

File Type Macro in <sys/stats.h>

S_ISREG() // regular file

S_ISDIR()

S_ISCHR()

S_ISBLK()

S_ISFIFO()

S_ISLNK()

S_ISSOCK()

Page 8: System Programming

8

Figure 4.3#include "apue.h"

Int main(int argc, char *argv[]){

int i;struct stat buf;char *ptr;

for (i = 1; i < argc; i++) {printf("%s: ", argv[i]);if (lstat(argv[i], &buf) < 0) {

err_ret("lstat error");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 special";

if (S_ISBLK(buf.st_mode))ptr = "block special";

else if (S_ISFIFO(buf.st_mode))ptr = "fifo";

else if (S_ISLNK(buf.st_mode))ptr = "symbolic link";

else if (S_ISSOCK(buf.st_mode))ptr = "socket";

elseptr = "** unknown mode **";

printf("%s\n", ptr);}exit(0);

}

Page 9: System Programming

9

File Access Permissions

• All files have access permissions– st_mode mask – owner, group, other

#define S_IRWXU 00700 /* read, write, execute: owner */

#define S_IRUSR 00400 /* read permission: owner */

#define S_IWUSR 00200 /* write permission: owner */

#define S_IXUSR 00100 /* execute permission: owner */

#define S_IRWXG 00070 /* read, write, execute: group */

#define S_IRGRP 00040 /* read permission: group */

#define S_IWGRP 00020 /* write permission: group */

#define S_IXGRP 00010 /* execute permission: group */

#define S_IRWXO 00007 /* read, write, execute: other */

#define S_IROTH 00004 /* read permission: other */

#define S_IWOTH 00002 /* write permission: other */

#define S_IXOTH 00001 /* execute permission: other */

Page 10: System Programming

10

File Operations vs. Access Permissions

• File Operations: read, write, execute, etc.• File Access Permissions: who (process) can perform what operations

• Directory file– X – pass through the dir (search bit), e.g., /usr/dict/words.– R – list of files under the dir.– W – update the dir, e.g., delete or create a file.

• Regular file– X – execute a file (which must be a regular file)– R – O_RDONLY or O_RDWR– W – O_WRONLY, O_RDWR, or O_TRUNC

• What are the needed file access permissions?– ls /home/professor/hchu– cd /home/professor/hchu– rm /home/professor/hchu/foo– cat /home/professor/hchu/foo– echo 123 >> /home/professor/hchu/foo

Page 11: System Programming

11

Process IDs

• How to check if a process can perform an operation on file access permissions?– File access test: check (process IDs, file APs, OP)

• A process can have more than one ID.– Real user/group ID // who we really are, e.g., hchu– Effective user/group ID // used for file access

// permission checks– Supplementary group IDs– Saved set-user/group-ID // saved by exec function

Page 12: System Programming

12

Access Permissions & UID/GID

• File Access Test – each time a process creates/opens/deletes a file– If the effective UID == 0 superuser!– If the effective UID == UID of the file

• Check appropriate access permissions!– If the effective GID == GID of the file

• Check appropriate access permissions!– Check appropriate access permissions for others!

• Related Commands: chmod & umask

Page 13: System Programming

13

hchu@linux1:/> ls -l /etc/shadow-rw-r----- 1 root shadow 843 2006-03-07 10:01 /etc/shadowhchu@linux1:/> cat /etc/shadow

hchu@linux1:/> ls -al .drwxr-xr-x 22 root root 4096 2006-01-20 13:33 ./drwxr-xr-x 22 root root 4096 2006-01-20 13:33 ../drwxr-xr-x 2 root root 4096 2006-03-13 18:23 bin/

hchu@linux1:/> cd bin

hchu@linux1:/usr/include> which passwd/usr/bin/passwd

hchu@linux1:/usr/include> ls -l /usr/bin/passwd-rwsr-xr-x 1 root root 28224 2006-02-22 14:05 /usr/bin/passwd

hchu@linux1:/usr/include> rm /usr/bin/passwd hchu@linux1:/usr/include> passwd

Page 14: System Programming

14

Set-User-ID/Set-Group-ID

• st_mode: st_uid/st_gid– Setting user/group ID of the owner.

• How can a user change his/her password without having the write permission to /etc/passwd and /etc/shadow?

• A process can have more than one ID. – Real user/group ID– Effective user/group ID– Supplementary group IDs– Saved set-user/group-ID

-rw-r--r-- 1 root root 1746 2/21 13:00 /etc/passwd-r-------- 1 root root 1142 2/21 13:01 /etc/shadow

Page 15: System Programming

15

Ownership of a New File

• Rules:– UID of a file = the effective UID of the creating pro

cess– GID of a file – options under POSIX

1. GID of the file = the effective GID of the process2. GID of the file = the GID of the residing dir

– 4.3BSD and Mac OS X do (2).– SVR4 needs to set the set-group-ID bit of the residing

dir (mkdir)!

Page 16: System Programming

16

Function – access • Test a file accessibility before accessing it.

#include <unistd.h>int access(const char *pathname, int mode);

– R_OK // test for read permission– W_OK– X_OK– F_OK– Check the real UID/GID!

Page 17: System Programming

17

Figure 4.8 Program#include "apue.h"#include <fcntl.h>

intmain(int argc, char *argv[]){

if (argc != 2)err_quit("usage: a.out <pathna

me>");if (access(argv[1], R_OK) < 0)

err_ret("access error for %s", argv[1]);else

printf("read access OK\n");if (open(argv[1], O_RDONLY) < 0)

err_ret("open error for %s", argv[1]);else

printf("open for reading OK\n");exit(0);

}

>ls -l fig4.8.exe-rwxr-xr-x 1 hchu users 9487 200

6-03-21 19:53 fig4.8.exe>fig4.8.exe fig4.8.exeread access OKopen for reading OK>ls -l /etc/shadow-rw-r----- 1 root shadow 843 200

6-03-07 10:01 /etc/shadow>fig4.8.exe /etc/shadowaccess error for /etc/shadow: Pe

rmission deniedopen error for /etc/shadow: Per

mission denied

Page 18: System Programming

18

Function – umask• Set file mode creation mask (default file permissions)

#include <sys/types.h>#include <sys/stat.h>mode_t umask(mode_t cmask);

– Any bits that are on in the cmask are turned off in the file’s mode

• cmask = bitwise-OR file access permissions (e.g., S_I[RWX]USR) • Examples: cmask = S_IRWXO, cmask = S_IWOTH | S_IWGRP

– The mask goes with the process only.• Inheritance from the parent!

Page 19: System Programming

19

Figure 4.9 Program

#include "apue.h"#include <fcntl.h>

#define RWRWRW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)

intmain(void){

umask(0);if (creat("foo", RWRWRW) < 0)err_sys("creat error for foo");umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);if (creat("bar", RWRWRW) < 0)err_sys("creat error for bar");exit(0);

}

>umask22>fig4.9.exe>ls -al foo bar-rw------- 1 hchu users 0 2006-03-21 20:

14 bar-rw-rw-rw- 1 hchu users 0 2006-03-21

20:14 foo>umask22

Page 20: System Programming

20

Function – chmod & fchmod• Change file access permissions for an existing file.

#include <sys/types.h>#include <sys/stat.h>int chmod(const char *pathname, mode_t mode);int fchmod(int filedes, mode_t mode);

– fchmod() is not in POSIX.1, but in SVR4/4.3+BSD– Callers must be a superuser or effective UID = file UID.– Mode = bitwise-OR S_I[RWX]USR, S_ISVTX (sticky bit), S_IS[U

G]ID, etc (Fig 4.6).

Page 21: System Programming

21

Figure 4.10 Program#include "apue.h"

Int main(void){

struct stat statbuf;

/* turn on set-group-ID and turn off group-execute */

if (stat("foo", &statbuf) < 0)err_sys("stat error for foo");

if (chmod("foo", (statbuf.st_mode & ~S_IXGRP) | S_ISGID) < 0)

err_sys("chmod error for foo");

/* set absolute mode to "rw-r--r--" */

if (chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0)

err_sys("chmod error for bar");

exit(0);}

>ls -al foo bar-rw------- 1 hchu users 0 2006-03-2

1 20:14 bar-rw-rw-rw- 1 hchu users 0 2006-0

3-21 20:14 foo>fig4.12.exe>ls -al foo bar-rw-r--r-- 1 hchu users 0 2006-03-2

1 20:14 bar-rw-rwSrw- 1 hchu users 0 2006-0

3-21 20:14 foo

// what is strange here?

Page 22: System Programming

22

Function – chmod & fchmod

• set-group-ID – If the GID of a newly created file is not equal to the

effective GID of the creating process (or one of the supplementary GID’s), or the process is not a superuser, clear the set-group-ID bit!

– Clear up set-user/group-ID bits if a non-superuser process writes to a set-uid/gid file.

Page 23: System Programming

23

Function – chmod & fchmod

• Sticky Bit (S_ISVTX) – saved-text bit– For frequently executed binaries– Not POSIX.1 – by SVR4 & 4.3+BSD– Only superusers can set it!– S_ISVTX executable file

• Used to save a copy of a S_ISVTX executable in the swap area to speed up the execution next time.

– S_ISVTX directory file, e.g., /tmp• Remove/rename its file only if w permission of the dir is se

t, and the process is belonging to superusers/owner of the file/dir

Page 24: System Programming

24

Function – chown, fchown, lchown

• Change the user/group ID of a file

#include <sys/types.h>#include <unistd.h>int chown(const char *pathname, uid_t owner, gid_t, grp);int fchown(int filedes, uid_t owner, gid_t, grp);int lchown(const char *pathname, uid_t owner, gid_t, grp);

– lchown() is unique to SVR4. Under non-SVR4 systems, if the pathname to chown() is a symbolic link, only the ownership of the symbolic link is changed.

– -1 for owner or grp if no change is wanted.

• Why would one want to give away file ownership?

Page 25: System Programming

25

Function – chown, fchown, lchown

• _POSIX_CHOWN_RESTRICTED is in effect (check pathconf())– Superuser the UID of the file can be changed!– The GID of the file can be changed if

• the process owns the file, and• Parameter owner = UID of the file & Parameter grp = the pr

ocess GID or is in supplementary GID’s• set-user/group-ID bits would be cleared if chown is called b

y non-super users.

Page 26: System Programming

26

File Size

• File Sizes – st_size– Regular files – 0~max (off_t)– Directory files – multiples of 16/512– Symbolic links – pathname length– /* a pipe’s file size for SVR4 */

• File Holes– st_blocks vs st_size (st_blksize)– Commands:

• “ls –l file.hole” == “wc –c file.hole”• du –s file.hole actual size• cat file.hole > file.hole.copy

Page 27: System Programming

27

Functions – truncate & ftruncate

#include <sys/types.h>#include <unistd.h>int truncate(const char *pathname, off_t length);int ftruncate(int filedes, off_t length);

– Not POSIX.1– SVR4 creates a hole if length > fsize.– 4.3+BSD only truncates files.– Portability?

Page 28: System Programming

28

System ProgrammingChapter 4

朱浩華教授 / 施吉昇教授臺灣大學資訊工程系

Page 29: System Programming

29

Administration Misc. (4/12)

• The mid-term will be held on April 26, 2006 in class. It will cover Chapter 1 to 6.

• MP2 is out today and due on April 28, 2006 (Friday).

• Some of your email address on website have been deleted due to a bug for the web site. Please visit the site to update your email address.

Page 30: System Programming

30

Playing with Shadow(Tokyo University)

Page 31: System Programming

31

Filesystem• A disk can be divided into logical partitions.• Each partition has a filesystem.• Each filesystem contains a list of inodes (i-list) as well as the actu

al directory- and data blocks• Every inode has a link count (st_nlink): it shows how many “thin

gs” point to this inode. Only if this link count is 0 are the data blocks freed. Each name <-> inode association is called a hard link.

• inode contains most of information found in the stat structure.• inode number in a directory entry must point to an inode on the

same file system (no hardlinks across filesystems)• To move a file within a single filesystem, we can just ”move” th

e directory entry (actually done by creating a new entry, and deleting the old one).

Page 32: System Programming

32

BSD UNIX File System (UFS)

Page 33: System Programming

33

BSD UNIX File System (UFS)Figure 4.14 (hard links)

Page 34: System Programming

34

Filesystem – 4.4BSD i-node

* “Operating system concept”, Silberschatz and Galvin, Addison Wesley, pp. 380.

mode

owner

timestamp

size block

ref-count

triple indirect

double indirect

single indirect

direct blocks

data

data

data

data

data

data…

data

data…

data…

• 4KB block size• 12 direct pointers

• 48KB• 1 single indirect

• 4-byte block ptr• 1K * 4KB = 4MB

• >> 4GB for the largest file! (offset = 32 bits, 4G=232)

Page 35: System Programming

35

BSD UNIX File System (UFS)(> mkdir testdir ; link count, leaf vs. intermediate dirs)

Page 36: System Programming

36

Hard Link v.s. Soft Link• Hard Link

– Cannot link to different mounted file system. – is a different name for the same set of data blocks.– Only superuser can create a link to a directory.

• Soft Link (or Symbolic link)– Can be a directory or file– Is a pointer to a set of data blocks. – File type is S_IFLINK

• What’s the difference on their i-nodes?

Page 37: System Programming

37

Hard vs. Soft Links• Hard Link

– Each directory entry creates a hard link of a filename to the i-node that describes the file’s contents.

– Normally require that link & file on the same file system

• Symbolic Link (Soft Link)– It is implemented as a file

that contains a pathname.– Filesize = pathname length– Example: Shortcut on

Windows– Get around with filesystem li

mitation & linking dirs

foo

bar

/usr/joe

/usr/sueFile i-node:

#Reference = 2

foo

bar

/usr/sue

File i-node:#Reference = 1

/usr/joe

File i-node:#Reference = 1

data block:“ /usr/joe/foo”

Page 38: System Programming

38

Hard vs. Soft Links• Problems with links

– Infinite loops– Dangling pointers– Unable to remove

foo

bar

/usr/joe

/usr/sueFile i-node:

Reference = 2

foo

bar

/usr/sue

File i-node:Reference = 1

/usr/joe

File i-node:Reference = 1

data block:“ /usr/joe/foo”

Page 39: System Programming

39

Symbolic Links: infinite loops

> mkdir foo> touch foo/a> ln –s ../foo foo/testdir> ls –l foo> ls –R • List subdirectories recursive

ly

foofoo/afoo/testdirfoo/testdir/?

foo

a testdir

Page 40: System Programming

40

BSD UNIX File System (UFS)(> mv testdir testdir2 -> only update inode)

Page 41: System Programming

41

Functions – link, unlink, rename, remove

#include <unistd.h>int link(const char *existingpath, const char *newpath);int unlink(const char *pathname);

– Atomic action for link – hard link• POSIX.1 allows linking across filesystems• Only superusers could create a link to a dir

– Error if newpath exists– Unlink – WX right at the residing dir

• Remove the dir entry & delete the file if link count reaches zero and no one still opens the file (Remark: sticky bit & dir rights).

Page 42: System Programming

42

Functions – link, unlink, rename, remove

• Program 4.16 – Page 110– Open & unlink a file

#include "apue.h"#include <fcntl.h>

intmain(void){

if (open("tempfile", O_RDWR) < 0)err_sys("open error");

if (unlink("tempfile") < 0)err_sys("unlink error");

printf("file unlinked\n");sleep(15);printf("done\n");exit(0);

}

Page 43: System Programming

43

Functions – link, unlink, rename, remove

• Unlink a file– Sticky bits set for a residing dir, we must have

the write permission for the directory and either owner of the file, the dir, or super users.

– If pathname is a symbolic link, unlink references the symbolic link.

Page 44: System Programming

44

Functions – link, unlink, rename, remove

#include <stdio.h>int remove(const char *pathname);int rename(const char *oldname, const char *newname);

– remove = rmdir if pathname is a dir. (ANSI C)– Rename – ANSI C

• File: both files, newname is removed first, WX permission for both residing directories

• Directory: both dir, newname must be empty, newname could not contain oldname.

– > rename /usr/foo /usr/foo/testdir ???

Page 45: System Programming

45

Symbolic Links

#include <unistd.h>int symlink(const char *actualpath, const char *s

ympath);int readlink(const char *pathname, char *buf, int

bufsize);– actualpath does not need to exist!

• They do not need to be in the same file system.– readlink is an action consisting of open, read, and c

lose – not null terminated.

Page 46: System Programming

46

File Times

• Three Time Fields:

• Changing the access permissions, user ID, link count, etc, only affects the i-node!

• ctime is modified automatically! (stat, access)• Example: reading/writing a file only affects the file, instead of th

e residing dir (Fig4.13).

Field Description Example ls-optionst_atime last-access-time Read -u

st_mtime last-modification-time Write default

st_ctime last-i-node-change-time chmod, chown -c

Page 47: System Programming

47

File Times

#include <sys/types.h>#include <utime.h>int utime(const char *pathname, const struct uti

mbuf *times);– time values are in seconds since the Epoch– times = null set as the current time

• Effective UID = file UID or W right to the file– times != null set as requested

• Effective UID = (file UID or superuser) and W right to the file.

– Program 4.21

struct utimbuf { time_t actime; time_t modtime; }

Page 48: System Programming

48

#include "apue.h"#include <fcntl.h>#include <utime.h>

Int main(int argc, char *argv[]){

int i, fd;struct stat statbuf;struct utimbuf timebuf;

for (i = 1; i < argc; i++) {if (stat(argv[i], &statbuf) < 0) { /* fetch curr

ent times */err_ret("%s: stat error", argv[i]);continue;

}if ((fd = open(argv[i], O_RDWR | O_TRUNC)) <

0) { /* truncate */err_ret("%s: open error", argv[i]);continue;

}close(fd);timebuf.actime = statbuf.st_atime;timebuf.modtime = statbuf.st_mtime;if (utime(argv[i], &timebuf) < 0) { /

* reset times */err_ret("%s: utime error", argv[i]);continue;

}}exit(0);

}

• Change: atime, mtime, ctime?

> ls -l changemod -rw-r--r-- 1 hchu professor 0 Apr 12 00:35

changemod

> ls -lu changemod-rw-r--r-- 1 hchu professor 0 Apr 12 00:36

changemod

> dateWed Apr 12 00:40:55 CST 2006

> ./fig4.21.exe changemod

> ls -l changemod-rw-r--r-- 1 hchu professor 0 Apr 12 00:35

changemod

> ls -lu changemod-rw-r--r-- 1 hchu professor 0 Apr 12 00:36

changemod

> ls -lc changemod-rw-r--r-- 1 hchu professor 0 Apr 12 00:41

changemod

Page 49: System Programming

49

Functions – mkdir and rmdir#include <sys/types.h>#include <sys/stat.h>int mkdir(const char *pathname, mode_t mode);

– umask, UID/GID setup (Sec 4.6)– From 4.2BSD & SVR3 (SVR4 – inheritance of the S_ISGI

D bit)#include <unistd.h>int rmdir(const char *pathname);

– An empty dir is deleted.– Link count reaches zero, and no one still opens the di

r.

Page 50: System Programming

50

Functions – opendir, readdir, rewinddir, closedir

#include <sys/types.h>#include <dirent.h>DIR *opendir(const char *pathname);struct dirent *readdir(DIR *dp); void rewinddir(DIR *dp); int closedir(DIR *dp);

– Only the kernel can write to a dir!!!– WX for creating/deleting a file!– Implementation-dependent!

Page 51: System Programming

51

Functions – opendir, readdir, rewinddir, closedir

• dirent struct is very implementation-dependent, e.g.,struct dirent {

ino_t d_ino; /* not in POSIX.1 */char d_name[NAME_MAX+1];

} /* fpathconf() */

• Program 4.22: traverse a file hierarchy and count # of files for each file type

Page 52: System Programming

52

#include "apue.h"#include <dirent.h>#include <limits.h>

/* function type that is called for each filename */typedef int Myfunc(const char *, const

struct stat *, int);

static Myfunc myfunc;static int myftw(char *, Myfunc *);static int dopath(Myfunc *);

static long nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot;

intmain(int argc, char *argv[]){

int ret;

if (argc != 2)err_quit("usage: ftw <starting-pathnam

e>");

ret = myftw(argv[1], myfunc); /* does it all */

ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock;if (ntot == 0)

ntot = 1; /* avoid divide by 0; print 0 for all counts */printf("regular files = %7ld, %5.2f %%\n", nreg, nreg*100.0/ntot);

printf("directories = %7ld, %5.2f %%\n", ndir, ndir*100.0/ntot);printf("block special = %7ld, %5.2f %%\n", nblk, nblk*100.0/ntot);printf("char special = %7ld, %5.2f %%\n", nchr, nchr*100.0/ntot);printf("FIFOs = %7ld, %5.2f %%\n", nfifo, nfifo*100.0/ntot);printf("symbolic links = %7ld, %5.2f %%\n", nslink, nslink*100.0/ntot);printf("sockets = %7ld, %5.2f %%\n", nsock, nsock*100.0/ntot);

exit(ret);}

Page 53: System Programming

53

/* * Descend through the hierarchy, starting at "pathnam

e". * The caller's func() is called for every file. */#define FTW_F 1

/* file other than directory */#define FTW_D 2

/* directory */#define FTW_DNR 3

/* directory that can't be read */#define FTW_NS 4

/* file that we can't stat */

static char *fullpath; /* contains full pathname for every file */

static int/* we return whatever fu

nc() returns */myftw(char *pathname, Myfunc *func){

int len;fullpath = path_alloc(&len); /* malloc's for PATH_MAX+1 bytes */

/* ({Prog pathalloc}) */strncpy(fullpath, pathname, len); /* protect against */fullpath[len-1] = 0;

/* buffer overrun */

return(dopath(func));}

Page 54: System Programming

54

/* * Descend through the hierarchy, starting at "fullpath". * If "fullpath" is anything other than a directory, we lsta

t() it, * call func(), and return. For a directory, we call ourself * recursively for each name in the directory. */static int

/* we return whatever func() returns */

dopath(Myfunc* func){

struct stat statbuf;struct dirent *dirp;DIR

*dp;int

ret;char *ptr;

if (lstat(fullpath, &statbuf) < 0) /* stat error */

return(func(fullpath, &statbuf, FTW_NS));if (S_ISDIR(statbuf.st_mode) == 0) /* not a directory */

return(func(fullpath, &statbuf, FTW_F));

/* * It's a directory. First call func() for the directory, * then process each filename in the directory. */if ((ret = func(fullpath, &statbuf, FTW_D)) != 0)

return(ret);

ptr = fullpath + strlen(fullpath); /* point to end of fullpath */*ptr++ = '/';*ptr = 0;

if ((dp = opendir(fullpath)) == NULL) /* can't read directory */

return(func(fullpath, &statbuf, FTW_DNR));

while ((dirp = readdir(dp)) != NULL) {if (strcmp(dirp->d_name, ".") == 0 || strcmp(dirp->d_name, "..") == 0)

continue; /* ignore dot and dot-dot */

strcpy(ptr, dirp->d_name); /* append name after slash */

if ((ret = dopath(func)) != 0) /* recursive */

break; /* time to leave */}ptr[-1] = 0; /* erase everything from slash onwards */

if (closedir(dp) < 0)err_ret("can't close directory %s", fu

llpath);

return(ret);}

Page 55: System Programming

55

static intmyfunc(const char *pathname, const struct st

at *statptr, int type){

switch (type) {case FTW_F:

switch (statptr->st_mode & S_IFMT) {

case S_IFREG: nreg++;break;

case S_IFBLK: nblk++;break;

case S_IFCHR: nchr++;break;

case S_IFIFO: nfifo++;break;case S_IFLNK: nslink++;break;case S_IFSOCK: nsock++;break;case S_IFDIR:

err_dump("for S_IFDIR for %s",

pathname);

/* directories should have type = FTW_D */

}break;

case FTW_D:ndir++;break;

case FTW_DNR:err_ret("can't read directory %

s", pathname);break;

case FTW_NS:err_ret("stat error for %s", pat

hname);break;

default:err_dump("unknown type %d f

or pathname %s", type, pathname);}

return(0);}

Page 56: System Programming

56

Functions – chdir, fchdir, getcwd

#include <unistd.h>int chdir(const char *pathname);int fchdir(int filedes);

– Every process has its own current working directory– Per-process attribute – working dir!– chdir must be built into shells (pwd)!– The kernel only maintains the i-node number and dev ID for t

he current working directory!• Program 4.23

Page 57: System Programming

57

#include "apue.h"

intmain(void){

if (chdir("/tmp") < 0)err_sys("chdir failed");

printf("chdir to /tmp succeeded\n");exit(0);

}

> pwd/usr/lib> mycd>chdir to /tmp succeeded> pwd?

Page 58: System Programming

58

Functions – chdir, fchdir, getcwd

#include <unistd.h>char *getcwd(char *buf, size_t size);

– The buffer must be large enough, or an error returns!

– chdir follows symbolic links, and getcwd has not idea of symbolic links!

• Program 4.24 – getcwd

Page 59: System Programming

59

Special Device Files

• Device Number – dev_t– Major and minor numbers: 8 bit each under 4.3+BSD– macro definition <sysmacros.h> @ntucsa#define L_BITSMINOR 18 /* # of SVR4 minor device bits */#define L_MAXMAJ 0x3fff /* SVR4 max major value */#define major(x) (int)((unsigned)((x)>>O_BITSMINOR) & O_MAXMAJ)

• Program 4.25– st_dev vs st_rdev

Page 60: System Programming

60

Major Number vs. Minor Number

Driver

Controller 1Major #1

Controller 2Major #2

Controller 3Major #3

Device 1Minor #1

Device 2Minor #2

Device 1Minor #1

Device 2Minor #2

Device 1Minor #1

Device 2Minor #2

USB Controller

USB KB USB Cam

Page 61: System Programming

61

#include "apue.h"#ifdef SOLARIS#include <sys/mkdev.h>#endif

intmain(int argc, char *argv[]){

int i;struct stat buf;

for (i = 1; i < argc; i++) {printf("%s: ", argv[i]);if (stat(argv[i], &buf) < 0) {

err_ret("stat error");continue;

}

printf("dev = %d/%d", major(buf.st_dev), minor(buf.st_dev));

if (S_ISCHR(buf.st_mode) || S_ISBLK(buf.st_mode)) {printf(" (%s) rdev = %d/%d",

(S_ISCHR(buf.st_mode)) ? "character" : "block",major(buf.st_rdev), minor(buf.st_rdev));

}printf("\n");

}

exit(0);}


Recommended