server.c
/** Unix Domain Socket
* Figure 17.15, 16 on p597 ~ p599 of APUE */
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#define QLEN 10
#define STALE 30
#define BUFLEN 128
int serv_listen(const char* name);
int serv_accept(int listenfd, uid_t *uidptr);
void serve(int sockfd);
int main(int argc, char* argv[])
{
int sockfd, size;
struct sockaddr_un un;
//un.sun_family = AF_UNIX;
//strcpy(un.sun_path, "foo.socket");
//if ( (sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
//{
//printf("socket failed\n");
//exit(1);
//}
//size = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);
//if ( bind(sockfd, (struct sockaddr*) &un, size) < 0)
//{
//printf("bind failed\n");
//exit(1);
//}
if ( ( sockfd = serv_listen("./foo.socket") ) < 0 )
{
printf("listen failed\n");
exit(1);
}
if ( sockfd >= 0 )
{
serve(sockfd);
exit(0);
}
exit(1);
}
void
serve (int sockfd)
{
int clfd;
FILE *fp;
char buf[BUFLEN];
while (1)
{
uid_t temp;
clfd = serv_accept(sockfd, &temp);
if (clfd < 0)
{
printf("runtimed:%d accept error: %s\n", clfd, strerror(errno));
exit(1);
}
send(clfd, "ServerTalks", strlen("ServerTalks"), 0);
close(clfd);
}
}
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);
memset(&un, 0, 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 *uidptr)
{
int clifd, err, rval;
socklen_t len;
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;
}
#ifdef S_ISSOCK
if (S_ISSOCK(statbuf.st_mode) == 0)
{
rval = -3;
goto errout;
}
#endif
if ((statbuf.st_mode & (S_IRWXG | S_IRWXO)) ||
(statbuf.st_mode & S_IRWXU) != S_IRWXU)
{
rval = -4;
goto errout;
}
staletime = time(NULL) - STALE;
if (statbuf.st_atime < staletime ||
statbuf.st_ctime < staletime ||
statbuf.st_mtime < staletime )
{
rval = -5;
goto errout;
}
if (uidptr != NULL)
*uidptr = statbuf.st_uid;
unlink(un.sun_path);
return clifd;
errout:
err = errno;
close(clifd);
errno = err;
return rval;
}
/////////////////////////////////////
client.c
/** Unix Domain Socket
* Figure 17.17 p600 Advanced Unix Programming Environment */
#include <stdio.h> //19
#include <stdlib.h>
#include <stddef.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#define CLI_PATH "/var/tmp"
#define CLI_PERM S_IRWXU
#define BUFLEN 128
int cli_conn(const char *name);
int
main(int argc, char* argv[])
{
// struct addrinfo *ailist, *aip;
int sockfd;
//if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
//{
//printf("socket failed\n");
//exit(1);
//}
if ((sockfd = cli_conn("./foo.socket")) < 0)
{
printf("connect failed\n");
exit(1);
}
else
{
int n;
char buf[BUFLEN];
while( (n = recv(sockfd, buf, BUFLEN, 0)) > 0 )
{
write(1, buf, n);
//printf("%s", buf);
}
if (n < 0)
{
printf("recv error\n");
exit(1);
}
exit(0);
}
exit(1);
}
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;
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
strcpy(un.sun_path, "./fooclient.socket");
//sprintf(un.sun_path, "%s", name);//foo.socket");//"%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 (chmod(un.sun_path, CLI_PERM) < 0)
{
rval = -3;
goto errout;
}
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
strcpy(un.sun_path, name);
len = offsetof(struct sockaddr_un, sun_path) + strlen(name);
if (connect(fd, (struct sockaddr*)&un, len) < 0)
{
rval = -4;
goto errout;
}
return fd;
errout:
err = errno;
close(fd);
errno = err;
return rval;
}
/** Unix Domain Socket
* Figure 17.15, 16 on p597 ~ p599 of APUE */
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#define QLEN 10
#define STALE 30
#define BUFLEN 128
int serv_listen(const char* name);
int serv_accept(int listenfd, uid_t *uidptr);
void serve(int sockfd);
int main(int argc, char* argv[])
{
int sockfd, size;
struct sockaddr_un un;
//un.sun_family = AF_UNIX;
//strcpy(un.sun_path, "foo.socket");
//if ( (sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
//{
//printf("socket failed\n");
//exit(1);
//}
//size = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);
//if ( bind(sockfd, (struct sockaddr*) &un, size) < 0)
//{
//printf("bind failed\n");
//exit(1);
//}
if ( ( sockfd = serv_listen("./foo.socket") ) < 0 )
{
printf("listen failed\n");
exit(1);
}
if ( sockfd >= 0 )
{
serve(sockfd);
exit(0);
}
exit(1);
}
void
serve (int sockfd)
{
int clfd;
FILE *fp;
char buf[BUFLEN];
while (1)
{
uid_t temp;
clfd = serv_accept(sockfd, &temp);
if (clfd < 0)
{
printf("runtimed:%d accept error: %s\n", clfd, strerror(errno));
exit(1);
}
send(clfd, "ServerTalks", strlen("ServerTalks"), 0);
close(clfd);
}
}
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);
memset(&un, 0, 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 *uidptr)
{
int clifd, err, rval;
socklen_t len;
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;
}
#ifdef S_ISSOCK
if (S_ISSOCK(statbuf.st_mode) == 0)
{
rval = -3;
goto errout;
}
#endif
if ((statbuf.st_mode & (S_IRWXG | S_IRWXO)) ||
(statbuf.st_mode & S_IRWXU) != S_IRWXU)
{
rval = -4;
goto errout;
}
staletime = time(NULL) - STALE;
if (statbuf.st_atime < staletime ||
statbuf.st_ctime < staletime ||
statbuf.st_mtime < staletime )
{
rval = -5;
goto errout;
}
if (uidptr != NULL)
*uidptr = statbuf.st_uid;
unlink(un.sun_path);
return clifd;
errout:
err = errno;
close(clifd);
errno = err;
return rval;
}
/////////////////////////////////////
client.c
/** Unix Domain Socket
* Figure 17.17 p600 Advanced Unix Programming Environment */
#include <stdio.h> //19
#include <stdlib.h>
#include <stddef.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#define CLI_PATH "/var/tmp"
#define CLI_PERM S_IRWXU
#define BUFLEN 128
int cli_conn(const char *name);
int
main(int argc, char* argv[])
{
// struct addrinfo *ailist, *aip;
int sockfd;
//if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
//{
//printf("socket failed\n");
//exit(1);
//}
if ((sockfd = cli_conn("./foo.socket")) < 0)
{
printf("connect failed\n");
exit(1);
}
else
{
int n;
char buf[BUFLEN];
while( (n = recv(sockfd, buf, BUFLEN, 0)) > 0 )
{
write(1, buf, n);
//printf("%s", buf);
}
if (n < 0)
{
printf("recv error\n");
exit(1);
}
exit(0);
}
exit(1);
}
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;
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
strcpy(un.sun_path, "./fooclient.socket");
//sprintf(un.sun_path, "%s", name);//foo.socket");//"%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 (chmod(un.sun_path, CLI_PERM) < 0)
{
rval = -3;
goto errout;
}
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
strcpy(un.sun_path, name);
len = offsetof(struct sockaddr_un, sun_path) + strlen(name);
if (connect(fd, (struct sockaddr*)&un, len) < 0)
{
rval = -4;
goto errout;
}
return fd;
errout:
err = errno;
close(fd);
errno = err;
return rval;
}