mocksetup: /unsafe+/hdd -> /quad
[nethome.git] / src / unixpipe.c
1 /* $Id$ */
2
3 FIXME: Check and tidy it up first!
4
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <sys/types.h>
9 #include <sys/socket.h>
10 #include <sys/un.h>
11 #include <sys/poll.h>
12 #include <fcntl.h>
13 #include <unistd.h>
14 #include <sys/stat.h>
15 #include <errno.h>
16
17
18 int main(int argc,char **argv)
19 {
20 int fdunix,fdpipe;
21 struct sockaddr_un sockaddr_unix;
22 const char *pathnameunix,*pathnamepipe;
23 struct pollfd pollfds[2];
24 int fdi,fdo;
25
26         if (argc!=3) {
27                 fprintf(stderr,"%s: <pathname UNIX socket> <pathname PIPE>\n",argv[0]);
28                 exit(EXIT_FAILURE);
29                 }
30         pathnameunix=argv[1];
31         pathnamepipe=argv[2];
32         if (unlink(pathnamepipe) && errno!=ENOENT) {
33                 fprintf(stderr,"unlink(\"%s\"): %m\n",pathnamepipe);
34                 exit(EXIT_FAILURE);
35                 }
36         if (mkfifo(pathnamepipe,0600)) {
37                 fprintf(stderr,"mkfifo(\"%s\",0600): %m\n",pathnamepipe);
38                 exit(EXIT_FAILURE);
39                 }
40         if (-1==(fdpipe=open(pathnamepipe,O_WRONLY))) {
41                 fprintf(stderr,"open(\"%s\",O_WRONLY)=%d: %m\n",pathnamepipe,fdpipe);
42                 exit(EXIT_FAILURE);
43                 }
44         if (-1==(fdunix=socket(PF_UNIX,SOCK_STREAM,0))) {
45                 fprintf(stderr,"socket(PF_UNIX,SOCK_STREAM,0)=%d: %m\n",fdunix);
46                 exit(EXIT_FAILURE);
47                 }
48         memset(&sockaddr_unix,0,sizeof(sockaddr_unix));
49         sockaddr_unix.sun_family=AF_UNIX;
50         strncpy(sockaddr_unix.sun_path,pathnameunix,sizeof(sockaddr_unix.sun_path));
51         if (connect(fdunix,(const struct sockaddr *)&sockaddr_unix,sizeof(sockaddr_unix))) {
52                 fprintf(stderr,"connect(UNIX socket,\"%s\"): %m\n",pathnameunix);
53                 exit(EXIT_FAILURE);
54                 }
55         for (;;) {
56                 pollfds[0].fd=fdunix;
57                 pollfds[0].events=POLLIN;
58                 pollfds[1].fd=fdpipe;
59                 pollfds[1].events=POLLIN;
60                 if (0>=poll(pollfds,sizeof(pollfds)/sizeof(*pollfds),-1)) {
61                         fprintf(stderr,"poll(UNIX socket,PIPE socket): %m\n");
62                         exit(EXIT_FAILURE);
63                         }
64                 if (pollfds[0].revents & (POLLERR|POLLHUP|POLLNVAL)) {
65                         fprintf(stderr,"poll(UNIX socket): revents=0x%X\n",(unsigned)pollfds[0].revents);
66                         exit(EXIT_FAILURE);
67                         }
68                 if (pollfds[1].revents & (POLLERR|POLLHUP|POLLNVAL)) {
69                         fprintf(stderr,"poll(PIPE socket): revents=0x%X\n",(unsigned)pollfds[1].revents);
70                         exit(EXIT_FAILURE);
71                         }
72                 for (fdi=0;fdi<1 /*sizeof(pollfds)/sizeof(*pollfds)*/;fdi++) {
73                         for (;;) {
74                                 ssize_t got;
75                                 char buf[0x1000];
76
77                                 if (fcntl(pollfds[fdi].fd,F_SETFL,O_NONBLOCK)) {
78                                         fprintf(stderr,"fcntl(%s socket,F_SETFL,O_NONBLOCK): %m\n",
79                                                         (fdi==0 ? "UNIX" : (fdi==1 ? "PIPE" : "<UNKNOWN>")));
80                                         exit(EXIT_FAILURE);
81                                         }
82                                 got=read(pollfds[fdi].fd,buf,sizeof(buf));
83                                 if (got<0) {
84                                         if (errno==EAGAIN)
85                                                 break;
86                                         fprintf(stderr,"read(%s socket): %m\n",
87                                                         (fdi==0 ? "UNIX" : (fdi==1 ? "PIPE" : "<UNKNOWN>")));
88                                         exit(EXIT_FAILURE);
89                                         }
90                                 if (got==0)
91                                         exit(EXIT_SUCCESS);
92 write(1,buf,got);
93                                 for (fdo=0;fdo<sizeof(pollfds)/sizeof(*pollfds);fdo++) {
94                                         if (fdi==fdo)
95                                                 continue;
96                                         if (fcntl(pollfds[fdo].fd,F_SETFL,0 /* !O_NONBLOCK */)) {
97                                                 fprintf(stderr,"fcntl(%s socket,F_SETFL,0 /* !O_NONBLOCK */): %m\n",
98                                                                 (fdi==0 ? "UNIX" : (fdi==1 ? "PIPE" : "<UNKNOWN>")));
99                                                 exit(EXIT_FAILURE);
100                                                 }
101                                         if (got!=write(pollfds[fdo].fd,buf,got)) {
102                                                 fprintf(stderr,"write(%s socket,%ld): %m\n",
103                                                                 (fdo==0 ? "UNIX" : (fdo==1 ? "PIPE" : "<UNKNOWN>")),
104                                                                 (long)got);
105                                                 exit(EXIT_FAILURE);
106                                                 }
107                                         }
108                                 }
109                         }
110                 }
111         return EXIT_SUCCESS;
112 }