#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
int is_client;
int sp[ 2 ] ;
const char * hdr[ ] = { "S:" , "C:" } ;
const char * msg[ ] = { "Server says hello." , "Client says hello." } ;
void * reader ( void * arg) {
const char * err[ ] = { "S:reader" , "C:reader" } ;
char buf[ 1024 ] ;
( void ) arg;
for ( ;; ) {
ssize_t r = recv( sp[ is_client] , buf+ 2 , sizeof ( buf) - 2 , 0 ) ;
if ( r > 0 ) {
buf[ r+ 2 ] = '\0 ' ;
continue ;
}
if ( r
< 0 ) perror ( err
[ is_client
] ) ; break ;
}
shutdown( sp[ is_client] , SHUT_RD) ;
return 0 ;
}
void * writer ( void * arg) {
const char * err[ ] = { "S:writer" , "C:writer" } ;
ssize_t n
= strlen ( msg
[ is_client
] ) ; ssize_t x = 0 ;
( void ) arg;
while ( x < n) {
ssize_t r = send( sp[ is_client] , msg[ is_client] + x, n - x, 0 ) ;
if ( r > 0 ) {
x += r;
continue ;
}
if ( r
< 0 ) perror ( err
[ is_client
] ) ; break ;
}
shutdown( sp[ is_client] , SHUT_WR) ;
return 0 ;
}
void read_and_write ( int c) {
close( sp[ ! c] ) ;
is_client = c;
pthread_t t[ 2 ] ;
pthread_create( t+ 0 , 0 , reader, 0 ) ;
pthread_create( t+ 1 , 0 , writer, 0 ) ;
pthread_join( t[ 0 ] , 0 ) ;
pthread_join( t[ 1 ] , 0 ) ;
close( sp[ c] ) ;
}
int main ( ) {
socketpair( PF_UNIX, SOCK_STREAM, 0 , sp) ;
switch ( fork( ) ) {
default : read_and_write( 0 ) ;
break ;
case 0 : read_and_write( 1 ) ;
}
wait( 0 ) ;
return 0 ;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHB0aHJlYWQuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3dhaXQuaD4KI2luY2x1ZGUgPHN5cy9zb2NrZXQuaD4KCmludCBpc19jbGllbnQ7CmludCBzcFsyXTsKY29uc3QgY2hhciAqaGRyW10gPSB7ICJTOiIsICJDOiIgfTsKY29uc3QgY2hhciAqbXNnW10gPSB7ICJTZXJ2ZXIgc2F5cyBoZWxsby4iLCAiQ2xpZW50IHNheXMgaGVsbG8uIiB9OwoKdm9pZCAqIHJlYWRlciAodm9pZCAqYXJnKSB7CiAgICBjb25zdCBjaGFyICplcnJbXSA9IHsgIlM6cmVhZGVyIiwgIkM6cmVhZGVyIiB9OwogICAgY2hhciBidWZbMTAyNF07CiAgICAodm9pZClhcmc7CiAgICBzdHJjcHkoYnVmLCBoZHJbaXNfY2xpZW50XSk7CiAgICBmb3IgKDs7KSB7CiAgICAgICAgc3NpemVfdCByID0gcmVjdihzcFtpc19jbGllbnRdLCBidWYrMiwgc2l6ZW9mKGJ1ZiktMiwgMCk7CiAgICAgICAgaWYgKHIgPiAwKSB7CiAgICAgICAgICAgIGJ1ZltyKzJdID0gJ1wwJzsKICAgICAgICAgICAgcHV0cyhidWYpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaWYgKHIgPCAwKSBwZXJyb3IoZXJyW2lzX2NsaWVudF0pOwogICAgICAgIGJyZWFrOwogICAgfQogICAgc2h1dGRvd24oc3BbaXNfY2xpZW50XSwgU0hVVF9SRCk7CiAgICByZXR1cm4gMDsKfQoKdm9pZCAqIHdyaXRlciAodm9pZCAqYXJnKSB7CiAgICBjb25zdCBjaGFyICplcnJbXSA9IHsgIlM6d3JpdGVyIiwgIkM6d3JpdGVyIiB9OwogICAgc3NpemVfdCBuID0gc3RybGVuKG1zZ1tpc19jbGllbnRdKTsKICAgIHNzaXplX3QgeCA9IDA7CiAgICAodm9pZClhcmc7CiAgICB3aGlsZSAoeCA8IG4pIHsKICAgICAgICBzc2l6ZV90IHIgPSBzZW5kKHNwW2lzX2NsaWVudF0sIG1zZ1tpc19jbGllbnRdICsgeCwgbiAtIHgsIDApOwogICAgICAgIGFzc2VydChyICE9IDApOwogICAgICAgIGlmIChyID4gMCkgewogICAgICAgICAgICB4ICs9IHI7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBpZiAociA8IDApIHBlcnJvcihlcnJbaXNfY2xpZW50XSk7CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICBzaHV0ZG93bihzcFtpc19jbGllbnRdLCBTSFVUX1dSKTsKICAgIHJldHVybiAwOwp9Cgp2b2lkIHJlYWRfYW5kX3dyaXRlIChpbnQgYykgewogICAgY2xvc2Uoc3BbIWNdKTsKICAgIGlzX2NsaWVudCA9IGM7CiAgICBwdGhyZWFkX3QgdFsyXTsKICAgIHB0aHJlYWRfY3JlYXRlKHQrMCwgMCwgcmVhZGVyLCAwKTsKICAgIHB0aHJlYWRfY3JlYXRlKHQrMSwgMCwgd3JpdGVyLCAwKTsKICAgIHB0aHJlYWRfam9pbih0WzBdLCAwKTsKICAgIHB0aHJlYWRfam9pbih0WzFdLCAwKTsKICAgIGNsb3NlKHNwW2NdKTsKfQoKaW50IG1haW4gKCkgewogICAgc29ja2V0cGFpcihQRl9VTklYLCBTT0NLX1NUUkVBTSwgMCwgc3ApOwogICAgc3dpdGNoIChmb3JrKCkpIHsKICAgIGRlZmF1bHQ6IHJlYWRfYW5kX3dyaXRlKDApOwogICAgICAgICAgICAgYnJlYWs7CiAgICBjYXNlIDA6ICByZWFkX2FuZF93cml0ZSgxKTsKICAgICAgICAgICAgIGV4aXQoMCk7CiAgICBjYXNlIC0xOiBwZXJyb3IoImZvcmsiKTsKICAgICAgICAgICAgIGV4aXQoMCk7CiAgICB9CiAgICB3YWl0KDApOwogICAgcmV0dXJuIDA7Cn0K