Hello, and welcome back to CS631 "Advanced Programming in the UNIX Environment". This is week 09, segment 1, and we're continuing our discussion of Interprocess Communication. In this short video segement, we'll cover the socketpair(2) system call and compare it to the pipe(2) syscall we discussed in our last video. --- As a reminder, the pipe(2) syscall took as its argument a two element array of integers, connecting them to the newly created kernel structure. --- This is what this looks like: a pipe is a pair of connected sockets for one-way stream communication, and so to perform IPC, a process calls pipe(2) --- forks --- and then has both child and parent close their respectively unused file descriptors to allow data to flow from one process to the other. But as we noted, this communication is unidirectional. If you wanted bi-directional communications, you'd have to create _two_ pipes before you fork, then use one for data to flow in one direction and the other for data going in the other direction. That's cumbersome, so instead we can use --- a socketpair(2). A socketpair is just that: a pair of connected sockets that allow for two-way communication. Their use closely resembles that of a pipe, which is by design -- in fact, nowadays, a typical unix pipe may actually be implemented using a socketpair. - These sockets are created in the specified _domain_, of the specified _type_, and using the specified _protocol_. We'll go into more details about domains and protocols, but in a nutshell, a domain is a specific address format that implies certain conventions, such as what types of communications are supported and what protocols may be spoken. By passing 0 as the protocol, you let the system pick the default for the given domain and type. Again, we'll discuss this in more detail in our next video. - For socketpairs, this selection is particularly limited anyway, since socketpairs are only implemented in the "UNIX" or "local" domain, using the AF_UNIX or PF_LOCAL identifier. --- So after calling socketpair(2), we find ourselves in a situation similar to after having called pipe(2), only this time both file descriptors can be used to read from and write to. --- As before, we call fork(2)... --- ...and then close the unused file descriptors. Now we can perform bidirectional I/O in both the child and the parent on our respective descriptors. --- Here, let's look at an example. This program does almost the same as what we did with our pipe example in the last video, but this time we are using the sample code from the BSD IPC tutorial shipped with the OS. See our last Tool Tip video for more information on these docs. So in the beginning, we call socketpair(2) in the AF_UNIX domain; then we fork(2). In the parent, we close one of the file descriptors, write some data into the other, then read data from the same file descriptor and print out what we found. In the child process, we do just about the same. Here we go: Both parent and child begin by sending data, and once again, we have no guarantee for which process executes first. Then each reads some data and prints it to stdout. And that's really all there is to it - easy peasy. --- So let's take a quick break here before we continue with generic sockets. The example was simple enough, but perhaps use it to try to answer these questions here: - Suppose you want to perform bidirectional IPC, but you only have a pipe, no socketpair? Can you change the pipe program example from the last video to do the same thing we just did here with the socketpair? You'll have to create two pipes before forking... - Play around with the different protocols and types in the socketpair call. What, if anything, changes? - In our example, after creating a socketpair, each parent and child closed one file descriptor. Update the program to instead use the second connection to also exchange data. - And finally, what happens if you change the order of calling read(2) and write(2) in the two processes? - Alright, good luck playing around with this. Next time, we'll talk about regular sockets in the local domain -- perhaps give the BSD IPC tutorial here a read to prepare. Until then - thanks for watching. Cheers!