client.c
#include<errno.h>
#include<semaphore.h>
#include<string.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<stdlib.h>
#include<unistd.h>
#include<stdio.h>
#include<sys/mman.h>
#include<sys/types.h>
#include<signal.h>
#include<pthread.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#define SERVER_PORT 8000
#define MAXLINE 4096
#define QLEN 10
#define CLI_PATH "/var/tmp/"
int cli_conn(const char* name){
int fd,len,err,rval;
struct sockaddr_un un;
if((fd=socket(AF_UNIX,SOCK_STREAM,0))<0)return -1;
unlink(name);
bzero(&un,sizeof(un));
un.sun_family=AF_UNIX;
sprintf(un.sun_path,"%s%05d",CLI_PATH,getpid());
len=offsetof(struct sockaddr_un,sun_path)+strlen(un.sun_path);
unlink(un.sun_path);
if(bind(fd,(struct sockaddr*)&un,len)<0){
rval=-2;
goto errout;
}
if(listen(fd,QLEN)<0){
rval=-3;
goto errout;
}
return (fd);
errout:
err=errno;
close(fd);
errno=err;
return (rval);
}
int serv_accept(int listenfd,uid_t* uidpr){
int clifd,len,err,rval;
time_t staletime;
struct sockaddr_un un;
struct stat statbuf;
len=sizeof(un);
if((clifd=accept(listenfd,(struct sockaddr*)&un,&len))<0)return -1;
len-=offsetof(struct sockaddr_un,sun_path);
un.sun_path[len]=0;
if(stat(un.sun_path,&statbuf)<0){
rval=-2;
goto errout;
}
if(S_ISSOCK(statbuf.st_mode)==0){
rval=-3;
goto errout;
}
if(uidptr!=NULL)
*uidptr=statbuf.st_uid;
unlink(un.sun_path);
return (clifd);
errout:
err=errno;
close(clifd);
errno=err;
return rval;
}
int main(){
char buf[1024];
int fd,n;
fd=cli_conn("foo.socket");
if(fd<0){
switch(fd){
case -4:perror("connect");break;
case -3:perror("listen");break;
case -2:perror("bind");break;
case -1:perror("socket");break;
}
exit(-1);
}
while(fgets(buf,sizeof(buf),stdin)!=NULL){
write(fd,buf,strlen(buf));
n=read(fd,buf,sizeof(buf));
write(STDOUT_FILENO,buf,n);
}
close(fd);
return 0;
}
server.c
#include<errno.h>
#include<semaphore.h>
#include<string.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<stdlib.h>
#include<unistd.h>
#include<stdio.h>
#include<sys/mman.h>
#include<sys/types.h>
#include<signal.h>
#include<pthread.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#define SERVER_PORT 8000
#define MAXLINE 4096
#define QLEN 10
int serv_listen(const char* name){
int fd,len,err,rval;
struct sockaddr_un un;
if((fd=socket(AF_UNIX,SOCK_STREAM,0))<0)return -1;
unlink(name);
bzero(&un,sizeof(un));
un.sun_family=AF_UNIX;
strcpy(un.sun_path,name);
len=offsetof(struct sockaddr_un,sun_path)+strlen(name);
if(bind(fd,(struct sockaddr*)&un,len)<0){
rval=-2;
goto errout;
}
if(listen(fd,QLEN)<0){
rval=-3;
goto errout;
}
return (fd);
errout:
err=errno;
close(fd);
errno=err;
return (rval);
}
int serv_accept(int listenfd,uid_t* uidpr){
int clifd,len,err,rval;
time_t staletime;
struct sockaddr_un un;
struct stat statbuf;
len=sizeof(un);
if((clifd=accept(listenfd,(struct sockaddr*)&un,&len))<0)return -1;
len-=offsetof(struct sockaddr_un,sun_path);
un.sun_path[len]=0;
if(stat(un.sun_path,&statbuf)<0){
rval=-2;
goto errout;
}
if(S_ISSOCK(statbuf.st_mode)==0){
rval=-3;
goto errout;
}
if(uidptr!=NULL)
*uidptr=statbuf.st_uid;
unlink(un.sun_path);
return (clifd);
errout:
err=errno;
close(clifd);
errno=err;
return rval;
}
int main(){
int lfd,cfd,n,i;
uid_t cuid;
char buf[1024];
lfd=serv_listen("foo.socket");
if(lfd<0){
switch(lfd){
case -3:perror("listen");break;
case -2:perror("bind");break;
case -1:perror("socket");break;
}
exit(-1);
}
cfd=serv_accept(lfd,&cuid);
if(cfd<0){
switch(cfd){
case -3:perror("not a socket");break;
case -2:perror("a bad filename");break;
case -1:perror("accept");break;
}
exit(-1);
}
while(1){
r_again:
n=read(cfd,buf,1024);
if(n==-1){
if(errno==EINTR)goto r_again;
}
else if(n==0){
printf("the other side has been closed.\n");
break;
}
for(i=0;i<n;i++){
buf[i]=toupper(buf[i]);
}
write(cfd,buf,n);
}
close(fd);
close(lfd);
return 0;
}