steveh@hammer.UUCP (05/21/86)
# The rest of this file is a shell script which will extract: # Makefile README client.c give.c server.c spair.c take.c echo x - README cat >README <<'!Funky!Stuff!' These are demonstrations of Unix domain sockets. They assume a bug fixed 4.2 (or 4.3) system. 0) To build the examples type: make 1) client/server example. # start server server /tmp/echo & # run client client /tmp/echo hello world... ^D 2) give/take example. take /tmp/catch & give /etc/motd /tmp/catch !Funky!Stuff! echo x - Makefile cat >Makefile <<'!Funky!Stuff!' CFLAGS = -O DEMOS = client server give take spair all: ${DEMOS} clean:; rm -f *.o ${DEMOS} !Funky!Stuff! echo x - client.c cat >client.c <<'!Funky!Stuff!' /* * Connect to a unix domain server. */ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #define STDIN 0 #define STDOUT 1 main(argc,argv) char **argv; { int s; struct sockaddr_un sun; if(argc != 2) { fprintf(stderr, "Usage: client filename\n"); exit(1); } if( (s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { perror("socket"); exit(1); } sun.sun_family = AF_UNIX; strcpy(sun.sun_path, argv[1]); if( connect(s, (struct sockaddr *) &sun, sizeof(sun)) < 0) { perror("connect"); exit(1); } /* echo loop */ for(;;) { int mask; mask = (1<<STDIN) | (1<<s); if(select(s+1, &mask, (int *) 0, (int *) 0, 0) < 0) { perror("select"); exit(1); } if(mask & (1<<s)) if(copy(s, STDOUT) == 0) break; /* end of file */ if(mask & (1<<STDIN)) if(copy(STDIN, s) == 0) break; } } copy(from, to) { char buf[BUFSIZ]; register int cc; cc = read(from, buf, sizeof buf); if(cc == 0) return 0; if(cc < 0) { perror("read"); exit(1); } if(write(to, buf, cc) < 0) { perror("write"); exit(1); } return cc; } !Funky!Stuff! echo x - give.c cat >give.c <<'!Funky!Stuff!' /* * Pass a file to a process * * Usage: give file socket */ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #include <sys/uio.h> struct sockaddr_un sun = { AF_UNIX }; main(argc, argv) char **argv; { int f, s; struct msghdr msg; struct iovec iov; if(argc != 3) { fprintf(stderr, "Usage: give file socket\n"); exit(1); } if(strcmp(argv[1], "-") == 0) f = 0; else if( (f = open(argv[1],0)) < 0) { perror(*argv); exit(1); } if( (s = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { perror("socket"); exit(1); } strcpy(sun.sun_path, argv[2]); msg.msg_name = (caddr_t) &sun; msg.msg_namelen = sizeof sun; iov.iov_base = argv[1]; iov.iov_len = strlen(argv[1]); msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_accrights = (caddr_t) &f; msg.msg_accrightslen = sizeof(f); fprintf(stderr, "give s=%d f=%d\n", f, s); if(sendmsg(s, &msg, 0) < 0) { perror("sendmsg"); exit(1); } } !Funky!Stuff! echo x - server.c cat >server.c <<'!Funky!Stuff!' /* * Unix domain echo server. */ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #define STDIN 0 #define STDOUT 1 main(argc,argv) char **argv; { register int cc, s, ns; char buf[BUFSIZ]; int fromlen; struct sockaddr_un sun; struct sockaddr from; if(argc != 2) { fprintf(stderr, "Usage: echoserver filename\n"); exit(1); } if( (s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { perror("socket"); exit(1); } sun.sun_family = AF_UNIX; strcpy(sun.sun_path, argv[1]); if( bind(s, (struct sockaddr *) &sun, sizeof(sun)) < 0) { perror("bind"); exit(1); } listen(s, 1); fromlen = sizeof from; ns = accept(s, &from, &fromlen); if(ns < 0) perror("accept"); else while( (cc = read(ns, buf, sizeof buf)) > 0) if(write(ns, buf, cc) < 0) { perror("server write"); break; } if(cc < 0) perror("server read"); close(ns); close(s); unlink(sun.sun_path); /* cleanup */ } !Funky!Stuff! echo x - spair.c cat >spair.c <<'!Funky!Stuff!' /* * demonstrate socketsv */ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> main(argc, argv) char **argv; { register int child; int sv[2]; if( socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0) { perror("socketpair"); exit(1); } if(write(sv[0], "tick 00", 8) < 0 || write(sv[1], "tock 00", 8) < 0) { perror("write"); exit(1); } child = fork(); if(child < 0) perror("fork"); else if(child == 0) { flip(sv[0], sv[1]); } else { flip(sv[1], sv[0]); wait((int *) 0); } } flip(from, to) { register int i; register int pid = getpid(); char ibuf[32], obuf[32];; for(i = 0; i < 10; ++i) { if(read(from, ibuf, sizeof ibuf) < 0) { perror("read"); return; } printf("%d: %s\n", pid, ibuf); sprintf(obuf, "%-4.4s %02d", ibuf, i); if(write(to, obuf, sizeof obuf) < 0) { perror("write"); return; } } close(from); close(to); } !Funky!Stuff! echo x - take.c cat >take.c <<'!Funky!Stuff!' /* * Receive a file on a socket */ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #include <sys/uio.h> struct sockaddr_un sun = { AF_UNIX }; main(argc, argv) char **argv; { register int n; int s, f; struct sockaddr from; struct msghdr msg; struct iovec iov; char buf[8*1024]; if(argc != 2) { fprintf(stderr, "Usage: take socket\n"); exit(1); } if( (s = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { perror("socket"); exit(1); } strcpy(sun.sun_path, argv[1]); if( bind(s, &sun, sizeof sun) < 0) { perror("bind"); exit(1); } msg.msg_name = (caddr_t) &from; msg.msg_namelen = sizeof from; iov.iov_base = buf; iov.iov_len = sizeof buf; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_accrights = (caddr_t) &f; msg.msg_accrightslen = sizeof(f); fprintf(stderr, "take s=%d\n",s); n = recvmsg(s, &msg, 0); if(n < 0) { perror("recvmsg"); unlink(sun.sun_path); exit(1); } fprintf(stderr, "take got f=%d\n", f); close(s); unlink(sun.sun_path); buf[n] = '\0'; fprintf(stderr, ">%s<\n", buf); while( (n = read(f, buf, sizeof buf)) > 0) write(1, buf, n); if(n < 0) perror("read"); } !Funky!Stuff! -- Stephen Hemminger {ihnp4,decvax,ucbvax}!tektronix!hammer!steveh Tektronix GWD Networking (503)685-2103