3 * Test the file-descriptor passing code
5 * (c) 2018 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of the mLib utilities library.
12 * mLib is free software: you can redistribute it and/or modify it under
13 * the terms of the GNU Library General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or (at
15 * your option) any later version.
17 * mLib is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
20 * License for more details.
22 * You should have received a copy of the GNU Library General Public
23 * License along with mLib. If not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
28 /*----- Header files ------------------------------------------------------*/
35 #include <sys/socket.h>
44 /*----- Main code ---------------------------------------------------------*/
46 static void set_unix_addr(struct sockaddr_un
*sun
, const char *path
)
48 if (strlen(path
) >= sizeof(sun
->sun_path
))
49 die(2, "pathname `%s' too long", path
);
50 sun
->sun_family
= AF_UNIX
;
51 strcpy(sun
->sun_path
, path
);
54 const char sockmsg
[] = "socket message", pipemsg
[] = "pipe message";
56 int main(int argc
, char *argv
[])
58 struct sockaddr_un sun
;
60 int lsk
, sk
, fd
, pfd
[2];
66 if (argc
== 3 && strcmp(argv
[1], "server") == 0) {
67 set_unix_addr(&sun
, argv
[2]);
68 lsk
= socket(PF_UNIX
, SOCK_STREAM
, 0);
69 if (lsk
< 0) die(2, "socket: %s", strerror(errno
));
70 if (bind(lsk
, (struct sockaddr
*)&sun
, sizeof(sun
)))
71 die(2, "bind: %s", strerror(errno
));
72 if (listen(lsk
, 5)) die(2, "listen: %s", strerror(errno
));
73 len
= sizeof(sun
); sk
= accept(lsk
, (struct sockaddr
*)&sun
, &len
);
74 if (sk
< 0) die(2, "accept: %s", strerror(errno
));
76 n
= fdpass_recv(sk
, &fd
, buf
, sizeof(buf
));
77 if (n
< 0) die(2, "fdrecv: %s", strerror(errno
));
79 if (fd
== -1) die(2, "no fd found");
80 if (n
!= sizeof(sockmsg
) || strcmp(buf
, sockmsg
) != 0)
81 die(2, "socket message mismatch (found `%.*s')", (int)n
, buf
);
82 n
= read(fd
, buf
, sizeof(buf
));
83 if (n
< 0) die(2, "read: %s", strerror(errno
));
84 if (n
!= sizeof(pipemsg
) || strcmp(buf
, pipemsg
) != 0)
85 die(2, "pipe message mismatch (found `%.*s')", (int)n
, buf
);
87 } else if (argc
== 3 && strcmp(argv
[1], "client") == 0) {
88 set_unix_addr(&sun
, argv
[2]);
89 if (pipe(pfd
)) die(2, "pipe: %s", strerror(errno
));
90 sk
= socket(PF_UNIX
, SOCK_STREAM
, 0);
91 if (sk
< 0) die(2, "socket: %s", strerror(errno
));
92 if (connect(sk
, (struct sockaddr
*)&sun
, sizeof(sun
)))
93 die(2, "connect: %s", strerror(errno
));
94 if (fdpass_send(sk
, pfd
[0], sockmsg
, sizeof(sockmsg
)) < 0)
95 die(2, "fdsend: %s", strerror(errno
));
98 if (write(pfd
[1], pipemsg
, sizeof(pipemsg
)) < 0)
99 die(2, "write: %s", strerror(errno
));
102 pquis(stderr
, "usage: $ client|server SOCK\n");
108 /*----- That's all, folks -------------------------------------------------*/