system commands and interprocess communication. chroot int chroot(const char *path); chroot changes...

15
System Commands and Interprocess Communication

Upload: donald-lynch

Post on 02-Jan-2016

227 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: System Commands and Interprocess Communication. chroot int chroot(const char *path); chroot changes the root directory to that specified in path. This

System Commands and Interprocess Communication

Page 2: System Commands and Interprocess Communication. chroot int chroot(const char *path); chroot changes the root directory to that specified in path. This

chroot• int chroot(const char *path);• chroot changes the root directory to that

specified in path. • This directory will be used for path names

beginning with /. • The root directory is inherited by all children

of the current process.• Why might you want to do this before the

exec for a CGI program?

Page 3: System Commands and Interprocess Communication. chroot int chroot(const char *path); chroot changes the root directory to that specified in path. This

Pipes• A special file that can store a limited amount of data

in a first-in-first-out (FIFO) manner• The include file <limits.h> or <sys/param.h> contains

a defined constant PIPE_BUF that specifies the maximum number of bytes a pipe may hold

• One process will write to the pipe (as if it were a file), while another process will read from the pipe

• The system provides the synchronization between writing and reading processes

Page 4: System Commands and Interprocess Communication. chroot int chroot(const char *path); chroot changes the root directory to that specified in path. This

Pipes• By default, if a writing process attempts to write to a

full pipe, the system will automatically block the process until the pipe is able to receive the data

• Likewise, if a read is attempted on an empty pipe, the process will block until data is available

• In addition, the process will block if a specified pipe has been opened for reading, but another process has not opened the pipe for writing

• Data is written to the pipe and read from the pipe using the unbuffered I/O write and read system calls

Page 5: System Commands and Interprocess Communication. chroot int chroot(const char *path); chroot changes the root directory to that specified in path. This

Read and WriteInclude File(s) <unistd.h>

Summary ssize_t write( int fildes, const void *buf, size_t nbyte );

Return Success Failure Sets errno

Number of bytes written

-1 Yes

Include File(s)<sys/types><sys/uio.h><unistd.h>

Summary ssize_t read( int fildes, const void *buf, size_t nbyte );

Return Success Failure Sets errno

Number of bytes read -1 Yes

Page 6: System Commands and Interprocess Communication. chroot int chroot(const char *path); chroot changes the root directory to that specified in path. This

PIPES• A call to the pipe() function returns a pair of file

descriptors. • One of these descriptors is connected to the write end

of the pipe, and the other is connected to the read end. • int pipe( int fildes[2] );

Page 7: System Commands and Interprocess Communication. chroot int chroot(const char *path); chroot changes the root directory to that specified in path. This

pipe() Example#include <stdio.h>#include <stdlib.h> #include <sys/types.h> #include <unistd.h>

int main() { int pfds[2]; char buf[30]; pipe(pfds); if (fork()==0) {

printf(" CHILD: writing to the pipe\n"); write(pfds[1], "test", 5); //close pfds[0]printf(" CHILD: exiting\n"); exit(0);

} else { printf("PARENT: reading from pipe\n"); read(pfds[0], buf, 5); //close pfds[1]printf("PARENT: read \"%s\"\n", buf); wait(NULL);

} }

Page 8: System Commands and Interprocess Communication. chroot int chroot(const char *path); chroot changes the root directory to that specified in path. This

popen() Example#include <stdio.h> #include <unistd.h>

int main () {

// creates a pipe and changes it to a file pointer// only works one way.FILE* stream = popen (“sort”, “w”);

fprintf (stream, “This is a test.\n”); fprintf (stream, “Hello, world.\n”); fprintf (stream, “My dog has fleas.\n”); fprintf (stream, “This program is great.\n”); fprintf (stream, “One fish, two fish.\n”);

return pclose (stream); }

Page 9: System Commands and Interprocess Communication. chroot int chroot(const char *path); chroot changes the root directory to that specified in path. This

dup and dup2• The dup system call duplicates an original open file descriptor

– int dup(int fd)

– The new descriptor, fildes, references the system file table entry for the next available non-negative file descriptor.

• The dup2 system call duplicates a file descriptor (fd1) onto a specific file descriptor (fd2)– int dup2(int fd1, int fd2)

– if fd2 is already open, it will be closed first

• The new descriptor will – Share the same file pointer(offset)– Have the same access mode as the original and– Will be set to remain open across an exec call

Page 10: System Commands and Interprocess Communication. chroot int chroot(const char *path); chroot changes the root directory to that specified in path. This

dup2#include <fcntl.h>#include <unistd.h>#include <iostream>#include <stdio.h>#include <stdlib.h>using namespace std;

main() { int fd; fd = open("tmp360", O_CREAT|O_WRONLY, 00777); dup2(fd, 1); close(fd); cout << "what is going on?\n"; cerr << "1111111\n";}

Page 11: System Commands and Interprocess Communication. chroot int chroot(const char *path); chroot changes the root directory to that specified in path. This

#include <stdio.h>#include <sys/types.h>#include <sys/wait.h>#include <unistd.h>int main (){ int fds[2]; pid_t pid; pipe (fds); /* Create a pipe. File descriptors for the two ends of the pipe are placed in fds. */

pid = fork (); /* Fork a child process. */ if (pid == (pid_t) 0) { close (fds[1]); /* This is the child process. Close our copy of the write end of the file descriptor. */ dup2 (fds[0], STDIN_FILENO); /* Connect the read end of the pipe to standard input. */ execlp ("sort", "sort", 0); /* Replace the child process with the sort program. */ } else { /* This is the parent process. */ FILE* stream; close (fds[0]); /* Close our copy of the read end of the file descriptor. */

/* Convert the write file descriptor to a FILE object, and write to it. */ stream = fdopen (fds[1], "w"); fprintf (stream, "This is a test.\n"); fprintf (stream, "Hello, world.\n"); fprintf (stream, "My dog has fleas.\n"); fprintf (stream, "This program is great.\n"); fprintf (stream, "One fish, two fish.\n"); fflush (stream); close (fds[1]);

/* Wait for the child process to finish. */ waitpid (pid, NULL, 0); } return 0;}

Page 12: System Commands and Interprocess Communication. chroot int chroot(const char *path); chroot changes the root directory to that specified in path. This

Web Servers & Pipes

Client

WebServer

CGIprogram

stdin

stdout

http

use dup2 to redirectstdin and stdout backto the web server

use dup2 to redirectstdin and stdout backto the web server

CGI programs are definedto only read from stdin and write to stdout

CGI programs are definedto only read from stdin and write to stdout

Page 13: System Commands and Interprocess Communication. chroot int chroot(const char *path); chroot changes the root directory to that specified in path. This

Steps for CGI launching• Create two pipes using the pipe system call

– childin and childout

• fork– now both the parent and child have the pipes

• Child– use dup2 to dup the pipe onto stdin and stdout appropriately– dup2( childin[0], 0);// Change stdin to come from the parent– dup2(childout[1], 1);// Change stdout to go back to the parent– close the unused parts of childin and childout– exec the CGI process – It will inherit the new stdin and stdout

• Parent– write the body of the HTTP message to childin[1] (the write side of childin)– read from childout[0] (the read side of childout) and send it back to client on the socket– You will know how much to read based on the Content-Length header coming back from the

child process

Page 14: System Commands and Interprocess Communication. chroot int chroot(const char *path); chroot changes the root directory to that specified in path. This

FIFO• A FIFO is sometimes known as a named pipe. That is, it's like a

pipe, except that it has a name! • In this case, the name is that of a file that multiple processes

can open() and read and write to. • Has to be open at both ends simultaneously before you can

proceed to do any input or output operations on it .

– int mkfifo(const char *path,mode_t mode); – mkfifo("/tmp/namedpipe" , 0666);

Page 15: System Commands and Interprocess Communication. chroot int chroot(const char *path); chroot changes the root directory to that specified in path. This

#include <stdio.h>#include <sys/types.h>#include <sys/wait.h>#include <unistd.h>int main (){ int pid; char *namedpipe = “/tmp/MyNamedPipe”;

mkfifo(namedpipe, 0660); /* Create a fifo. */

pid = fork (); /* Fork a child process. */ if (pid == (pid_t) 0) { /* This is the child process. */ FILE *input; char str[256]; input = fopen(namedpipe, "r"); /* Open the fifo just like any FILE and read from it */ while(fgets(str, 255, input)) { printf("CHILD: %s", str); } fclose(input); } else { /* This is the parent process. */ FILE* stream;

stream = fopen (namedpipe, "w"); /* Open the fifo just like any FILE and write to it */ fprintf (stream, "This is a test.\n"); fprintf (stream, "Hello, world.\n"); fprintf (stream, "My dog has fleas.\n"); fprintf (stream, "This program is great.\n"); fprintf (stream, "One fish, two fish.\n"); fflush (stream); fclose (stream);

waitpid (pid, NULL, 0); /* Wait for the child process to finish. */ } return 0;}