Title: UNIX directories
1Interprocess communication
21. Pipes
- A form of interprocess communication Between
processes that have a common ancestor - Typical use
- Pipe created by a process
- Process calls fork()
- Pipe used between parent and child
3Differences between versions
- All systems support half-duplex
- Data flows in only one direction
- Many newer systems support full duplex
- Data flows in two directions
- For portability, assume only half-duplex
4Creating a pipe
- include ltunistd.hgt
- int pipe(int filedes2)
- Returns 0 if ok, -1 on error
- Returns two file descriptors
- filedes0 is open for reading
- filedes1 is open for writing
- Output of filedes1 is input to filedes0
5After the pipe() call
0 stdin
1 stdout
2 stderr
3
4
5
Filedes 0 1
3 4
6The process then calls fork()
0 stdin
1 stdout
2 stderr
3
4
5
0 stdin
1 stdout
2 stderr
3
4
5
Child
Parent
7And then .
- We close the read end in one process
- And close the write end in the other process
- To get .
8Parent writing to child
0 stdin
1 stdout
2 stderr
3
4 X
5
0 stdin
1 stdout
2 stderr
3 X
4
5
Child
Parent
9Child writing to parent
0 stdin
1 stdout
2 stderr
3 X
4
5
0 stdin
1 stdout
2 stderr
3
4 X
5
Child
Parent
10After one end of the pipe is closed
- Reading from a empty pipe whose write end has
been closed returns 0 (indicating EOF) - Writing to a pipe whose read end has been closed
generates a SIGPIPE signal - If we ignore the signal or catch and return,
handler returns -1, and errno set to EPIPE
11Example
- include ltunistd.hgt
- include ltstdio.hgt
- int main(void)
- int n // to keep track of num
bytes read - int fd2 // to hold fds of both
ends of pipe - pid_t pid // pid of child process
- char line80 // buffer to hold text
read/written -
-
12Continued
- if (pipe(fd) lt 0) // create
the pipe - perror("pipe error")
- if ((pid fork()) lt 0) // fork
off a child - perror("fork error")
- else if (pid gt 0) //
parent process - close(fd0) // close
read end - write(fd1, "hello world\n", 12) //
write to it
13continued
- else // child
process - close(fd1) // close
write end - n read(fd0, line, 80) // read
from pipe - write(1, line, n) // echo
to screen -
- exit(0)
14 dup() and dup2
- include ltunistd.hgt
- int dup(int filedes)
- int dup2(int filedes, int filedes2)
- Both will duplicate an existing file descriptor
- dup() returns lowest available file descriptor,
now referring to whatever filedes refers to - dup2() - filedes2 (if open) will be closed and
then set to refer to whatever filedes refers to
15DUP
- Duplicate a file descriptor (system call)
- int dup( int fd )
- duplicates fd as the lowest unallocated
descriptor - Commonly used to redirect stdin/stdout
- Example redirect stdin to foo
- int fd
- fd open(foo, O_RDONLY, 0)
- close(0)
- dup(fd)
- close(fd)
16DUP2
- For convenience
- dup2( int fd1, int fd2 )
- use fd2(new) to duplicate fd1 (old)
- closes fd2 if it was in use
- Example redirect stdin to foo
- fd open(foo, O_RDONLY, 0)
- dup2(fd,0)
- close(fd)
17Pipes and Standard I/O
- int pid, p2
- if (pipe(p) -1)
- exit(1)
- pid fork()
- if (pid 0)
- close(p1)
- dup2(p0,0)
- close(p0)
- ... read from stdin ...
-
- else
- close(p0)
- dup2(p1,1)
- close(p1)
- ... write to stdout ...
- wait(status)
18Pipes and Exec()
- int pid, p2
- if (pipe(p) -1)
- exit(1)
- pid fork()
- if (pid 0)
- close(p1)
- dup2(p0,0)
- close(p0)
- execl(...)
-
- else
- close(p0)
- dup2(p1,1)
- close(p1)
- ... write to stdout ...
- wait(status)
19ls more example
- When command shells interprets ls more, it
- 1. Invokes the pipe( ) system call let us assume
that pipe( ) returns the file descriptors 3 (the
pipe's read channel ) and 4 (the write channel ). - 2. Invokes the fork( ) system call twice.
- 3. Invokes the close( ) system call twice to
release file descriptors 3 and 4.
20ls more example
- The first child process, which must execute
the ls program, performs the following
operations - 1. Invokes dup2(4,1) to copy file descriptor 4 to
file descriptor 1. From now on, file descriptor 1
refers to the pipe's write channel. - 2. Invokes the close( ) system call twice to
release file descriptors 3 and 4. - 3. Invokes the execve( ) system call to execute
the /bin/ls program. By default, such a program
writes its output to the file having file
descriptor 1 (the standard output), that is, it
writes into the pipe.
21ls more example
- The second child process must execute the more
program therefore, it performs the following
operations - 1. Invokes dup2(3,0) to copy file descriptor 3 to
file descriptor 0. From now on, file descriptor 0
refers to the pipe's read channel. - 2. Invokes the close( ) system call twice to
release file descriptors 3 and 4. - 3. Invokes the execve( ) system call to execute
/bin/more. By default, that program reads its
input from the file having file descriptor (the
standard input) that is, it reads from the pipe.
22popen and pclose
- include ltstdio.hgt
- FILE popen(const char cmdstring, const char
type) - The popen( ) function receives two parameters
- the cmdstring pathname of an executable file
- a type string specifying the direction of the
data transfer (r or w). - It returns the pointer to a FILE data structure
(fp). - popen runs cmdstring with output or input
directed to fp based on value of type parameter. - Handle the dirty work of creating pipe, forking
child, closing unused ends, executing shell to
run program, waiting for command to terminate - int pclose(FILE fp)
- The pclose( ) function, which receives the file
pointer returned by popen( ) as its parameter,
simply invokes the wait4( ) system call and waits
for the termination of the process created by
popen( ).
23Other techniques for IPC
- Socket programming
- We have seen this before in internet engineering.
- It is mainly used for IPC between two network
processes. - Semaphores
- Seen before.
- Shared memory
- shmget() for Create/Access Shared Memory
- shmat() for Accessing Shared Memory
- shmctl() for controlling shared memory
- shmdt() for deleting shared memory
- Messages
- msgget( KEY, IPC_CREATIPC_EXCL) for
Create/access - msgctl( id, IPC_RMID ) for Control
- Send/receive
- msgsnd( id, buf, text_size, flags )
- msgrcv( id, buf, max_size, flags )
- FIFO
- mkfifo( ) specifically to create a FIFO.
- Once created, a FIFO can be accessed through the
usual open( ), read( ), write( ), and close( )
system calls.
24Directory structure
25Directory Structure
- A directory file is a sequence of lines each
line holds an i-node number and a file name. - The data is stored as binary, so we cannot simply
use cat to view it
26- I-node
- The administrative information about a file is
kept in a structure known as an inode. - Inodes in a file system, in general, are
structured as an array known as an inode table. - An inode number, which is an index to the inode
table, uniquely identifies a file in a file
system.
27i-node and Data Blocks
282. Links
- 2.1 What is a Link?
- 2.2 Creating a Link
- 2.3 Seeing Links
- 2.4 Removing a Link
- 2.5 Symbolic Links
- 2.6 Implementation
292.1. What is a Link?
- A link is a pointer to a file.
- Useful for sharing files
- a file can be shared by giving each person their
own link (pointer) to it.
302.2. Creating a Link
- ln existing-file new-pointer
- Jenny types
- ln draft /home/bob/letter
/
/home/bob/draftand /home/jenny/letter
home
bob
jenny
memo
planning
31- Changes to a file affects every link cat
file_a This is file A. ln file_a file_b
cat file_b This is file A. - vi file_b
- cat file_bThis is file B after the change.
cat file_aThis is file B after the change.
322.3. Seeing Links
- Compare status information
- ls -l file_a file_b file_c file_d-rw-r--r--
2 dkl 33 May 24 1052 file_a-rw-r--r-- 2 dkl 33
May 24 1052 file_b-rw-r--r-- 1 dkl 16 May 24
1055 file_c-rw-r--r-- 1 dkl 33 May 24 1057
file_d - Look at inode number
- ls -i file_a file_b file_c file_d3534 file_a
3534 file_b 5800 file_c 7328 file_d
332.4. Removing a Link
- Deleting a link does not remove the file.
- Only when the file and every link is gone will
the file be removed.
342.5. Symbolic Links
- The links described so far are often called hard
links - a hard link is a pointer to a file which must be
on the same file system - A symbolic link is an indirect pointer to a file
- it stores the pathname of the pointed-to file
- it can link across file systems
35- Jenny types
- ln -s shared /home/dkl/project
/
/home/jenny/sharedand /home/dkl/project
home
dkl
jenny
separate file system
memo
planning
36- Symbolic links are listed differently
- ln -s pics /home/mh/img
- ls -lF pics /home/mh/img
- drw-r--r-- 1 dkl staff 981 May 24 1055 pics
- lrwxrwxrxw 1 dkl staff 4 May 24
1057/home/mh/img --gt pics
372.6 Link Creation, Update Removal
cp bob new
ln bob new
ln -s bob new
bob
abc
abc
abc
update new
delete new
?
new
bob
new
bob
bob
new
abc
XY
abc
XY
abc
abc
XY
continued
382.7 link() and unlink()
- include ltunistd.hgt
- int link( const char oldpath, const char
newpath ) - Meaning of link( abc, xyz )
fred.html
120
abc
207
135
bookmark.c
xyz
207
continued
39- unlink() clears the directory record
- usually means that the i-node number is set to 0
- The i-node is only deleted when the last link to
it is removed the data block for the file is
also deleted (reclaimed) no process have the
file opened
40Example unlink
- include ltstdio.hgt
- include ltsys/stat.hgt
- include ltsys/types.hgt
- include ltfcntl.hgt
- int main(void)
-
- if( open( "tempfile", O_RDWR ) lt 0 )
-
- perror( "open error )
- exit( 1 )
-
- if( unlink( "tempfile ) lt 0 )
-
- perror( "unlink error )
- exit( 1 )
-
- printf( "file unlinked\n )
- exit(0)
41symlink()
- include ltunistd.hgt
- int symlink(const char oldpath, const char
newpath) - Creates a symbolic link named newpath which
contains the string oldpath. - Symbolic links are interpreted at run-time.
- Dangling link may point to an non-existing
file. - If newpath exists it will not be overwritten.
42readlink()
- include ltunistd.hgt
- int readlink( const char path, char buf,
- size_t bufsiz )
- Read value of a symbolic link (does not follow
the link). - Places the contents of the symbolic link path in
the buffer buf, which has size bufsiz. - Does not append a NULL character to buf.
- Return value
- The count of characters placed in the buffer if
it succeeds. - -1 if an error occurs.
433. Subdirectory Creation
- mkdir uga causes
- the creation of a uga directory file and an
i-node for it - an i-node number and name are added to the parent
directory file
120
fred.html
207
abc
135
bookmark.c
201
uga
444. . and ..
- . and .. are stored as ordinary file names
with i-node numbers pointing to the correct
directory files. - Example
dkl
book
memos
continued
45In more detail
Directory ben
123
.
247
..
260
book
401
memos
Directory book
Directory memos
260
.
401
.
123
..
123
..
566
chap1
800
kh
567
chap2
810077
kd
chap3
590
mw
590
465. mkdir()
- include ltsys/types.hgtinclude
ltfcntl.hgtinclude ltunistd.hgtint mkdir(char
pathname, mode_t mode) - Creates a new directory with the specified mode
return 0 if ok, -1 on error
continued
47- . and .. entries are added automatically
- mode must include execute permissions so the
user(s) can use cd. - e.g. 0755
486. rmdir()
- include ltunistd.hgtint rmdir(char pathname)
- Delete an empty directoryreturn 0 if ok, -1 on
error. - Will delay until other processes have stopped
using the directory.
497. Reading Directories
- include ltsys/types.hgtinclude ltdirent.hgtDIR
opendir(char pathname)struct dirent
readdir(DIR dp)int closedir(DIR dp)
returns apointer if ok, NULL on error
returns apointer if ok, NULL at end or on error
50dirent and DIR
- struct dirent
- long d_ino / i-node number /char
d_nameNAME_MAX1 / fname /off_t d_off
/ offset to next rec /unsigned short
d_reclen / record length / -
- DIR is a directory stream (similar to FILE)
- when a directory is first opened, the stream
points to the first entry in the directory
51Example listdir.c
List the contents of the current directory.
- include ltstdio.hgtinclude ltdirent.hgtint
main() - DIR dp struct dirent dir if( (dp
opendir(.)) NULL ) - fprintf( stderr, Cannot open dir\n
) exit(1)
continued
52- / read entries / while( (dir
readdir(dp)) ! NULL ) - / ignore empty records / if(
dir-gtd_ino ! 0 ) printf( s\n,
dir-gtd_name ) - closedir( dp ) return 0 / end main
/
538. chdir()
- include ltunistd.hgt
- int chdir( char pathname )
- int fchdir( int fd )
- Change the current working directory (cwd) of the
calling process return 0 if ok, -1 on error.
54Example cd to /tmp
- Part of to_tmp.c
- if( chdir(/tmp ) lt 0 printf( chdir
error\n) else printf( In /tmp\n )
55Directory Change is Local
- The directory change is limited to within the
program. - e.g.
- pwd/usr/lib to_tmp / from last slide
/In /tmp pwd/usr/lib
569. getcwd()
- include ltunistd.hgtchar getcwd(char buf, int
size) - Store the cwd of the calling process in
bufreturn buf if ok, NULL on error. - buf must be big enough for the pathname string
(size specifies the length of buf).
57Example
- include ltstdio.hgtinclude ltunistd.hgtinclude
ltdirent.hgt / for NAME_MAX /int main() - char nameNAME_MAX1 if( getcwd( name,
NAME_MAX1 ) NULL ) printf( getcwd
error\n ) else printf( cwd s\n,
name )
5810. Walking over Directories
- 'Visit' every file in a specified directory and
all of its subdirectories - visit means get the name of the file
- Apply a user-defined function to every visited
file.
59Function Prototypes
- include ltftw.hgt/ ftw means file tree walk,
starting at directory /int ftw( char
directory, MyFunc fp, int depth )/
apply MyFunc() to each visited file /typedef
int MyFunc( const char file, struct stat
sbuf, int flag )
continued
60- depth is the maximum number of directories that
can be open at once. Safest value is 1, although
it slows down ftw(). - Result of ftw() 0 for a successful visit of
every file, -1 on error.
61MyFunc Details
- The file argument is the pathname relative to the
start directory - it will be passed to MyFunc() automatically by
ftw() as it visits each file - sbuf argument is a pointer to the stat
information for the file being examined.
continued
62- The flag argument will be set to one of the
following for the item being examined - FTW_F Item is a regular file.
- FTW_D Item is a directory.
- FTW_NS Could not get stat info for item.
- FTW_DNR Directory cannot be read.
- If the MyFunc function returns a non-zero value
then the ftw() walk will terminate.
63Example shower.c
Print the names of all the files found below the
current directory.
- include ltstdio.hgtinclude ltsys/types.hgtinclud
e ltsys/stat.hgtinclude ltftw.hgtint shower(const
char file, const struct stat sbuf, int
flag)void main() ftw(., shower, 1)
continued
64- int shower(const char file, const struct
stat sbuf, int flag) if (flag FTW_F)
/ is a file / printf("Found s\n",
file) return 0