<<

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter- Communication

Risto Järvinen

October 14, 2019 Lecture contents

This lecture: Different ways processes can affect each other Classic IPC Stevens: ch10 (again), ch15 (except 15.7-15.10), ch16-17 (except internet sockets) Kerrisk: ch22, ch44, ch49-50, ch56-57,60-61 (ch58-59 = internet sockets) Internet sockets are covered in Network Programming course, so they are informative and useful to study, but not required on this course. Next lecture: System V IPC POSIX IPC

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 2/25 Risto Järvinen 14.10.2019 How can one process affect another?

Use of same resources (CPU time, memory, I/O bandwidth,..) Fork() and ()ing for children. Signals. Using same filesystem, shared files and directories. locks. Memory mapped files (()) Terminals/pseudoterminals. Pipes and sockets. Dedicated IPC mechanisms: Message queues, , Semaphores.

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 3/25 Risto Järvinen 14.10.2019 Classic IPC

Filesystem and Filelocks. (lect5) Pipes, named and unnamed. (today) Sockets, -domain and network. (today) Terminals. (lect3) Shared memory via mmap(). (lect3, briefly today) Signals, real-time signals. (lect4, RTS today) Some topics already partially covered.

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 4/25 Risto Järvinen 14.10.2019 Signals

Covered before. Basic idea is the have asynchronous notification to the process. Implemented as a function ( handler) that can be called at any time. Limited usability (few signals, no ordering, may lose signals, etc..)

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 5/25 Risto Järvinen 14.10.2019 POSIX Real-Time Signals (RTS)

Extension to signals: More signals. Queueing model, with priorities. Sender is identified. Can deliver data. Doesn’t lose multiple signals, though there is limit on how many times a signal can arrive.

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 6/25 Risto Järvinen 14.10.2019 Real-Time Signals limitations

Amount of signals is implementation specific. Standard doesn’t specify whether RTS operation may be used with normal signals. Delivered data is only an integer or a pointer. And a pointer usually has no meaning across processes. Limits available via sysconf() and signal.h: SIGRTMIN to SIGRTMAX, min _POSIX_RTSIG_MAX. _POSIX_SIGQUEUE_MAX, _SC_SIGQUEUE_MAX, RLIMIT_SIGPENDING.

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 7/25 Risto Järvinen 14.10.2019 Real-Time Signals API 1/2

#include

sigqueue(pid_t pid , int sig , const union sigval value);

int sigaction( int signum , const struct sigaction ∗act , struct sigaction ∗oldact ); void sa_sigaction( int signum, siginfo_t ∗info , void ∗context );

”value” is union of integer (int) and pointer (void *). RTS mode handler is defined by setting SA_SIGINFO flag in struct sigaction.

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 8/25 Risto Järvinen 14.10.2019 Real-Time Signals API 2/2

#include

i n t sigwaitinfo( const sigset_t ∗set, siginfo_t ∗ info ); i n t sigtimedwait( const sigset_t ∗set, siginfo_t ∗ info , const struct timespec ∗ timeout );

Synchronous reception of signals, no need to asynchronous handler. Blocks until a signal is received (or timeout occurs). If signal arrives between calls to sigwaitinfo(), it’s handled by the given disposition. To avoid surprises, block signals with sigprocmask().

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 9/25 Risto Järvinen 14.10.2019 Pipes

Mentioned briefly before. Data in from one end, out from the other end. Two types: Unnamed and Named The most common use: stdin/stdout/stderr pipes between processes ” | less” type command chaining in shell

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 10/25 Risto Järvinen 14.10.2019 Unnamed pipes API

#include

int pipe( int pipefd [2]); FILE ∗popen( const char ∗command , const char ∗ type ); int pclose(FILE ∗stream ); Creates two special file descriptors: fd[0] can be , fd[1] can be written. Pipe is unidirectional. Two-way communications need two pipes. No name or presense besides the FDs. Popen() wraps pipe creation, forking and exec()ing command.

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 11/25 Risto Järvinen 14.10.2019 Unnamed pipes semantics

For communication between processes within same : creates a pipe and gives the other end to the children. Within single process: f.ex. signal handler hack, or between threads. Pipe can hold at least PIPE_BUF bytes. (defined 4kiB on , but actual default maxsize is 1MiB and it’s adjustable.) Read operation: If data in buffer, returns data. If no data, blocks. If other end has been closed, returns remaining data and then returns EOF (0). Write operation: If space in buffer, writes atomically. If not enough, blocks until there is. If other end has closed, returns errno=EPIPE and process receives SIGPIPE.

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 12/25 Risto Järvinen 14.10.2019 Named pipes (FIFO) API

int mkfifo( const char ∗pathname, mode_t mode);

Pipe that is represented by a special type of file in the filesystem. is used like a file; it has access rights, it’s opened with open(), deleted with unlink(). Two-way communication still needs two pipes.. Also command-line utility of the same name.

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 13/25 Risto Järvinen 14.10.2019 Named pipe semantics

Usable between unrelated processes. Create with mkfifo(), delete with unlink() Open operation: Open with O_WRONLY blocks until other end has opened it the pipe for reading. Open with O_RDONLY blocks until other end has opened the pipe for writing. Read operation: If data in buffer, returns data. If no data, blocks. If other end has been closed, returns remaining data and then returns EOF (0). Write operation: If space in buffer, writes atomically. If not enough, blocks until there is. If other end has closed, returns errno=EPIPE and process receives SIGPIPE.

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 14/25 Risto Järvinen 14.10.2019 Sockets

BSD-derived communication method, basis of Internet communication. We’ll stick to particular type of sockets: UNIX Domain sockets. Actual Internet communication will be covered in S-38.3610. Basic idea: socket is a file descriptor, with a bunch of additional calls. List of ”domains” that Linux supporst on sockets: UNIX Domain, IPv4, IPv6, IPX, (kernel), X.25/AX.25, Appletalk and mechanisms to access raw frames of ATM and IP.

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 15/25 Risto Järvinen 14.10.2019 Socket semantics 1/2

Sockets also have different types: SOCK_DGRAM is message-based, unreliable, connectionless. ("UDP") SOCK_STREAM is stream-based, reliable, connected. ("TCP") SOCK_RAW provides access to raw protocol frames. SOCK_RDM is message-based, reliable, connectionless. SOCK_SEQPACKET is message-based, reliable, connected...... SOCK_DGRAM and SOCK_STREAM are only commonly available. Others are for specialized protocols, like TIPC (Transparent Inter-Process Communication).

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 16/25 Risto Järvinen 14.10.2019 Socket semantics 2/2

Connectionless server: socket(), bind(), recvfrom()*N, () Connectionless client: socket(), (bind(),) sendto()*N, close() Connected server: socket(), bind(), listen(), accept(), read/recv/write/send*N, close() Connected client: socket(), (bind(),) connect(), read/recv/write/send*N, close()

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 17/25 Risto Järvinen 14.10.2019 Socket API 1/2

#include i n t socket( i n t domain , i n t type , i n t protocol ); i n t bind( i n t sockfd , const struct sockaddr ∗addr , socklen_t addrlen); i n t listen( i n t sockfd , i n t backlog ); i n t accept ( i n t sockfd , struct sockaddr ∗addr , socklen_t ∗ addrlen); i n t connect( i n t sockfd , const struct sockaddr ∗addr , socklen_t addrlen);

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 18/25 Risto Järvinen 14.10.2019 Socket API 2/2

ssize_t recv( int sockfd , void ∗buf, size_t len, int flags ); ssize_t recvfrom( int sockfd , void ∗buf, size_t len, int flags , struct sockaddr ∗src_addr , socklen_t ∗addrlen ); ssize_t recvmsg( int sockfd , struct msghdr ∗msg, int flags ); ssize_t send( int sockfd , const void ∗buf, size_t len, int flags ); ssize_t sendto( int sockfd , const void ∗buf, size_t len, int flags , const struct sockaddr ∗dest_addr , socklen_t addrlen ); ssize_t sendmsg( int sockfd , const struct msghdr ∗msg , int flags );

sendto(fd,buf,len,flags,NULL,0) equals send(fd,buf,len,flags). send(fd,buf,len,0) equals write(fd,buf,len).

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 19/25 Risto Järvinen 14.10.2019 UNIX Domain Sockets

Socket that communicates inside a UNIX system. Can be datagram or stream based. (Or even reliable datagram.) Address is a path, with a file (type = socket). If a regular file of the same name exists, EADDRINUSE. Can do both SOCK_DGRAM and SOCK_STREAM.

struct sockaddr_un { unsigned short sun_family; /∗ Address family ∗/ char sun_path[108]; /∗ Path name ∗/ } ;

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 20/25 Risto Järvinen 14.10.2019 UNIX Domain Sockets, the pipe edition

#include

int socketpair ( int domain , int type , int protocol , int sv[2]);

Creates a pair of connected sockets, kind of like pipe(). Unlike pipes, sockets are bidirectional. Could create sockets of any type, but in practice only UNIX Domain is supported.

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 21/25 Risto Järvinen 14.10.2019 UNIX Domain magic: Passing file descriptors

It’s possible to pass file descriptors and credentials from process to another, using sendmsg()/recvmsg(), as ancillary messages. Rights: Socket must have SO_PASSCRED. and then sendmsg() with SCM_RIGHTS. File descriptors: sendmsg() with SCM_CREDENTIALS.

struct msghdr { void ∗msg_name ; /∗ optional address ∗/ socklen_t msg_namelen; /∗ size of address ∗/ struct iovec ∗msg_iov; /∗ scatter /gather array ∗/ size_t msg_iovlen; /∗ # elements in msg_iov ∗/ void ∗msg_control; /∗ ancillary data, see below ∗/ size_t msg_controllen; /∗ ancillary data buffer len ∗/ int msg_flags ; /∗ flags on received message ∗/ } ;

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 22/25 Risto Järvinen 14.10.2019 Casualties of evolution

Sockaddr types are commonly cast according to sockaddr_. Largest type is sockaddr_storage, that is defined to be large enough to hold all other socket types, and that is cast around to other types. But.. breaks strict-aliasing rules. C language structures have no actual relations between each other, and compiler is free to pad fields as it likes to optimize access. Solution: put structures in union. ref http://www.mail-archive.com/[email protected]/msg01647.html

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 23/25 Risto Järvinen 14.10.2019 Shared memory, classic

Remember mmap()? Using MAP_SHARED flag allows mapped memory to be shared between processes, thus a IPC method. Anonymous mapped memory can be shared over fork(). File mapped memory can be shared by just mapping the same file. Synchronization? You do it. Or use some other IPC method to handle it. Cache coherency? Special situations may require manual flushing. How special? Between different CPUs. CPU and DSP on OMAP3 (N900, OpenPandora). Between CPU and GPU. Raspberry Pi, Sony PSP.

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 24/25 Risto Järvinen 14.10.2019 To be continued..

Next time: Rest of the IPC. System V and POSIX IPC: Message queues. Semaphores. Shared memory. More in second period: Threads also include some IPC.

ELEC-C7310 Sovellusohjelmointi Lecture 6: Inter-process Communication 25/25 Risto Järvinen 14.10.2019