MPX(2) UNIX Programmer's Manual MPX(2) NAME mpx - create and manipulate multiplexed files SYNOPSIS mpx(name, access) char *name; join(fd, xd) chan(xd) extract(i, xd) attach(i, xd) detach(i, xd) connect(fd, cd, end) npgrp(i, xd, pgrp) ckill(i, xd, signal) #include mpxcall(cmd, vec) int *vec; DESCRIPTION mpxcall(cmd, vec) is the system call shared by the library routines described below. _C_m_d selects a command using values defined in <_s_y_s/_m_x._h>. _V_e_c is the address of a structure containing the arguments for the command. mpx(name, access) _M_p_x creates and opens the file _n_a_m_e with access permission _a_c_c_e_s_s (see _c_r_e_a_t(2)) and returns a file descriptor avail- able for reading and writing. A -1 is returned if the file cannot be created, if _n_a_m_e already exists, or if the file table or other operating system data structures are full. The file descriptor is required for use with other routines. If _n_a_m_e designates a null string, a file descriptor is returned as described but no entry is created in the file system. Once created an mpx file may be opened (see _o_p_e_n(2)) by any process. This provides a form of interprocess communication whereby a process B can `call' process A by opening an mpx file created by A. To B, the file is ordinary with one exception: the _c_o_n_n_e_c_t primitive could be applied to it. Otherwise the functions described below are used only in process A and descendants that inherit the open mpx file. Printed 9/10/82 1 MPX(2) UNIX Programmer's Manual MPX(2) When a process opens an mpx file, the owner of the file receives a control message when the file is next read. The method for `answering' this kind of call involves using _a_t_t_a_c_h and _d_e_t_a_c_h as described in more detail below. Once B has opened A's mpx file it is said to have a _c_h_a_n_n_e_l to A. A channel is a pair of data streams: in this case, one from B to A and the other from A to B. Several processes may open the same mpx file yielding multiple chan- nels within the one mpx file. By accessing the appropriate channel, A can communicate with B and any others. When A reads (see _r_e_a_d(2)) from the mpx file data written to A by the other processes appears in A's buffer using a record format described in _m_p_x_i_o(5). When A writes (see _w_r_i_t_e(2)) on its mpx file the data must be formatted in a similar way. The following commands are used to manipulate mpx files and channels. _j_o_i_n- adds a new channel on an mpx file to an open file F. I/O on the new channel is I/O on F. _c_h_a_n- creates a new channel. _e_x_t_r_a_c_t- file descriptor maintenance. _c_o_n_n_e_c_t- similar to join except that the open file F is connected to an existing channel. _a_t_t_a_c_h and _d_e_t_a_c_h- used with call protocol. _n_p_g_r_p- manipulates process group numbers so that a channel can act as a control terminal (see _t_t_y(4)). _c_k_i_l_l- send signal (see _s_i_g_n_a_l(2)) to process group through channel. A maximum of 15 channels may be connected to an mpx file. They are numbered 0 through 14. _J_o_i_n may be used to make one mpx file appear as a channel on another mpx file. A hierarchy or tree of mpx files may be set up in this way. In this case one of the mpx files must be the root of a tree where the other mpx files are interior nodes. The maximum depth of such a tree is 4. An _i_n_d_e_x is a 16-bit value that denotes a location in an mpx tree other than the root: the path through mpx `nodes' from the root to the location is expressed as a sequence of 4-bit nibbles. The branch taken at the root is represented by the low-order 4-bits of an index. Each succeeding branch is specified by the next higher-order nibble. If the length of a path to be expressed is less than 4, then the illegal channel number, 15, must be used to terminate the sequence. This is not strictly necessary for the simple case of a tree consisting of only a root node: its channels can be expressed by the numbers 0 through 14. An index _i and file descriptor _x_d for the root of an mpx tree are required as arguments to most of the commands described below. Indices Printed 9/10/82 2 MPX(2) UNIX Programmer's Manual MPX(2) also serve as channel identifiers in the record formats given in _m_p_x_i_o(5). Since -1 is not a valid index, it can be returned as a error indication by subroutines that normally return indices. The operating system informs the process managing an mpx file of changes in the status of channels attached to the file by generating messages that are read along with data from the channels. The form and content of these messages is described in _m_p_x_i_o(5). join(fd, xd) establishes a connection (channel) between an mpx file and another object. _F_d is an open file descriptor for a character device or an mpx file and _x_d is the file descriptor of an mpx file. _J_o_i_n returns the index for the new channel if the operation succeeds and -1 if it does not. Following join, _f_d may still be used in any system call that would have been meaningful before the join operation. Thus a process can read and write directly to _f_d as well as access it via _x_d. If the number of channels required for a tree of mpx files exceeds the number of open files permitted a process by the operating system, some of the file descrip- tors can be released using the standard _c_l_o_s_e(2) call. Fol- lowing a close on an active file descriptor for a channel or internal mpx node, that object may still be accessed through the root of the tree. chan(xd) allocates a channel and connects one end of it to the mpx file represented by file descriptor _x_d. _C_h_a_n returns the index of the new channel or a -1 indicating failure. The _e_x_t_r_a_c_t primitive can be used to get a non-multiplexed file descriptor for the free end of a channel created by _c_h_a_n. Both _c_h_a_n and _j_o_i_n operate on the mpx file specified by _x_d. File descriptors for interior nodes of an mpx tree must be preserved or reconstructed with _e_x_t_r_a_c_t for use with _j_o_i_n or _c_h_a_n. For the remaining commands described here, _x_d denotes the file descriptor for the root of an mpx tree. Extract(i, xd) returns a file descriptor for the object with index _i on the mpx tree with root file descriptor _x_d. A -1 is returned by extract if a file descriptor is not available or if the arguments do not refer to an existing channel and mpx file. attach(i, xd) detach(i, xd). If a process A has created an mpx file represented by file descriptor _x_d, then a process B can open (see _o_p_e_n(2)) the mpx file. The purpose is to establish a channel between A and B through the mpx file. _A_t_t_a_c_h and Printed 9/10/82 3 MPX(2) UNIX Programmer's Manual MPX(2) _D_e_t_a_c_h are used by A to respond to such opens. An open request by B fails immediately if a new channel can- not be allocated on the mpx file, if the mpx file does not exist, or if it does exist but there is no process (A) with a multiplexed file descriptor for the mpx file (i.e. _x_d as returned by _m_p_x(2)). Otherwise a channel with index number _i is allocated. The next time A reads on file descriptor _x_d, the WATCH control message (see _m_p_x_i_o(5)) will be delivered on channel _i. A responds to this message with _a_t_t_a_c_h or _d_e_t_a_c_h. The former causes the open to complete and return a file descriptor to B. The latter deallocates chan- nel _i and causes the open to fail. One mpx file may be placed in `listener' mode. This is done by writing _i_o_c_t_l(_x_d, _M_X_L_S_T_N, _0) where _x_d is an mpx file descriptor and MXLSTN is defined in /_u_s_r/_i_n_c_l_u_d_e/_s_g_t_t_y._h. The semantics of listener mode are that all file names discovered by _o_p_e_n(2) to have the syntax _s_y_s_t_e_m!_p_a_t_h_n_a_m_e (see _u_u_c_p(1)) are treated as opens on the mpx file. The operating system sends the listener process an OPEN message (see _m_p_x_i_o(5)) which includes the file name being opened. _A_t_t_a_c_h and _d_e_t_a_c_h then apply as described above. _D_e_t_a_c_h has two other uses: it closes and releases the resources of any active channel it is applied to, and should be used to respond to a CLOSE message (see _m_p_x_i_o(5)) on a channel so the channel may be reused. connect(fd, cd, end). _F_d is a character file descriptor and _c_d is a file descriptor for a channel, such as might be obtained via _e_x_t_r_a_c_t( _c_h_a_n(_x_d), _x_d) or by _o_p_e_n(2) followed by _a_t_t_a_c_h. _C_o_n_n_e_c_t splices the two streams together. If _e_n_d is negative, only the output of _f_d is spliced to the input of _c_d. If _e_n_d is positive, the output of _c_d is spliced to the input of _f_d. If _e_n_d is zero, then both splices are made. npgrp(i, xd, pgrp). If _x_d is negative _n_p_g_r_p applies to the process executing it, otherwise _i and _x_d are interpreted as a channel index and mpx file descriptor and _n_p_g_r_p is applied to the process on the non-multiplexed end of the channel. If _p_g_r_p is zero, the process group number of the indicated process is set to the process number of that process, other- wise the value of _p_g_r_p is used as the process group number. _N_p_g_r_p normally returns the new process group number. If _i and _x_d specify a nonexistant channel, _n_p_g_r_p returns -1. ckill(i, xd, signal) sends the specified signal (see _s_i_g_- _n_a_l(2)) through the channel specified by _i and _x_d. If the channel is connected to anything other than a process, _c_k_i_l_l is a null operation. If there is a process at the other end Printed 9/10/82 4 MPX(2) UNIX Programmer's Manual MPX(2) of the channel, the process group will be interrupted (see _s_i_g_n_a_l(2), _k_i_l_l(2)). _C_k_i_l_l normally returns _s_i_g_n_a_l. If _c_h and _x_d specify a nonexistent channel, _c_k_i_l_l returns -1. FILES /usr/include/sys/mx.h /usr/include/sgtty.h SEE ALSO mpxio(5) BUGS Mpx files are an experimental part of the operating system more subject to change and prone to bugs than other parts. Maintenance programs, e.g. _i_c_h_e_c_k(1), diagnose mpx files as an illegal mode. Channels may only be connected to objects in the operating system that are accessible through the line discipline mechanism. Higher performace line disciplines are needed. The maximum tree depth restriction is not really checked. A non-destructive _d_i_s_c_o_n_n_e_c_t primitive (inverse of _c_o_n_n_e_c_t) is not provided. A non-blocking flow control strategy based on messages defined in _m_p_x_i_o(5) should not be attempted by novices; the enabling _i_o_c_t_l com- mand should be protected. The _j_o_i_n operation could be sub- sumed by _c_o_n_n_e_c_t. A mechanism is needed for moving a channel from one location in an mpx tree to another. Printed 9/10/82 5