X-Git-Url: https://git.jankratochvil.net/?a=blobdiff_plain;f=src%2Funixtcp.c;fp=src%2Funixtcp.c;h=f728f53b56f2b28cb475ada62103d15f1488819f;hb=99fa422f22f367a97118216b705ea5448842b784;hp=0000000000000000000000000000000000000000;hpb=82e0aa5676ee5e3f4b4b06c850294c2ec04d51ec;p=nethome.git diff --git a/src/unixtcp.c b/src/unixtcp.c new file mode 100644 index 0000000..f728f53 --- /dev/null +++ b/src/unixtcp.c @@ -0,0 +1,139 @@ +/* $Id$ */ + +FIXME: Check and tidy it up first! + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +int main(int argc,char **argv) +{ +int fdunix,fdtcp,fdtcplisten; +struct sockaddr_un sockaddr_unix; +struct sockaddr_in sockaddr_tcp; +const char *pathnameunix,*nametcp; +struct pollfd pollfds[2]; +int fdi,fdo; +socklen_t sockaddr_tcp_len; +int setsockopt_SO_REUSEADDR_on; + + if (argc!=3) { + fprintf(stderr,"%s: \n",argv[0]); + exit(EXIT_FAILURE); + } + pathnameunix=argv[1]; + nametcp=argv[2]; + + if (-1==(fdunix=socket(PF_UNIX,SOCK_STREAM,0))) { + fprintf(stderr,"socket(PF_UNIX,SOCK_STREAM,0)=%d: %m\n",fdunix); + exit(EXIT_FAILURE); + } + memset(&sockaddr_unix,0,sizeof(sockaddr_unix)); + sockaddr_unix.sun_family=AF_UNIX; + strncpy(sockaddr_unix.sun_path,pathnameunix,sizeof(sockaddr_unix.sun_path)); + if (connect(fdunix,(const struct sockaddr *)&sockaddr_unix,sizeof(sockaddr_unix))) { + fprintf(stderr,"connect(UNIX socket,\"%s\"): %m\n",pathnameunix); + exit(EXIT_FAILURE); + } + + if (-1==(fdtcplisten=socket(PF_INET,SOCK_STREAM,0))) { + fprintf(stderr,"socket(PF_INET,SOCK_STREAM,0)=%d: %m\n",fdtcplisten); + exit(EXIT_FAILURE); + } + setsockopt_SO_REUSEADDR_on=1; + if (setsockopt(fdtcplisten,SOL_SOCKET,SO_REUSEADDR,&setsockopt_SO_REUSEADDR_on,sizeof(setsockopt_SO_REUSEADDR_on))) { + fprintf(stderr,"setsockopt(TCP socket,SOL_SOCKET,SO_REUSEADDR,&1,sizeof(1)): %m\n"); + exit(EXIT_FAILURE); + } + memset(&sockaddr_tcp,0,sizeof(sockaddr_tcp)); + sockaddr_tcp.sin_family=AF_INET; + sockaddr_tcp.sin_addr.s_addr=htonl(INADDR_LOOPBACK); + sockaddr_tcp.sin_port=htons(atoi(nametcp)); + if (bind(fdtcplisten,(const struct sockaddr *)&sockaddr_tcp,sizeof(sockaddr_tcp))) { + fprintf(stderr,"bind(TCP socket,127.0.0.1:%s): %m\n",nametcp); + exit(EXIT_FAILURE); + } + if (listen(fdtcplisten,1)) { + fprintf(stderr,"listen(TCP socket,1): %m\n"); + exit(EXIT_FAILURE); + } + sockaddr_tcp_len=sizeof(sockaddr_tcp); + fprintf(stderr,"accept... "); + if (-1==(fdtcp=accept(fdtcplisten,(struct sockaddr *)&sockaddr_tcp,&sockaddr_tcp_len))) { + fprintf(stderr,"accept(TCP socket): %m\n"); + exit(EXIT_FAILURE); + } + fprintf(stderr,"done\n"); + if (close(fdtcplisten)) { + fprintf(stderr,"close(TCP listen socket): %m\n"); + exit(EXIT_FAILURE); + } + + for (;;) { + pollfds[0].fd=fdunix; + pollfds[0].events=POLLIN; + pollfds[1].fd=fdtcp; + pollfds[1].events=POLLIN; + if (0>=poll(pollfds,sizeof(pollfds)/sizeof(*pollfds),-1)) { + fprintf(stderr,"poll(UNIX socket,PIPE socket): %m\n"); + exit(EXIT_FAILURE); + } + if (pollfds[0].revents & (POLLERR|POLLHUP|POLLNVAL)) { + fprintf(stderr,"poll(UNIX socket): revents=0x%X\n",(unsigned)pollfds[0].revents); + exit(EXIT_FAILURE); + } + if (pollfds[1].revents & (POLLERR|POLLHUP|POLLNVAL)) { + fprintf(stderr,"poll(PIPE socket): revents=0x%X\n",(unsigned)pollfds[1].revents); + exit(EXIT_FAILURE); + } + for (fdi=0;fdi"))); + exit(EXIT_FAILURE); + } + got=read(pollfds[fdi].fd,buf,sizeof(buf)); + if (got<0) { + if (errno==EAGAIN) + break; + fprintf(stderr,"read(%s socket): %m\n", + (fdi==0 ? "UNIX" : (fdi==1 ? "PIPE" : ""))); + exit(EXIT_FAILURE); + } + if (got==0) + exit(EXIT_SUCCESS); + for (fdo=0;fdo"))); + exit(EXIT_FAILURE); + } + if (got!=write(pollfds[fdo].fd,buf,got)) { + fprintf(stderr,"write(%s socket,%ld): %m\n", + (fdo==0 ? "UNIX" : (fdo==1 ? "PIPE" : "")), + (long)got); + exit(EXIT_FAILURE); + } + } + } + } + } + return EXIT_SUCCESS; +}