#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stddef.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int unix_socket()
{
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
if(fd == -1)
return -1;
fcntl(fd, F_SETFD, fcntl(fd, F_GETFL) | FD_CLOEXEC);
#if 0
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
#else
struct timeval tv = {
.tv_sec = 3,
.tv_usec = 0
};
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(struct timeval));
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval));
#endif
return fd;
}
int unix_connect(int fd, char *pathname)
{
int ret = 0;
struct sockaddr_un addr;
memset(&addr, 0, sizeof(struct sockaddr_un));
struct stat st;
memset(&st, 0, sizeof(struct stat));
addr.sun_family = AF_UNIX;
snprintf(addr.sun_path, 108, "%s", pathname);
if(stat(addr.sun_path, &st) == -1 || S_ISSOCK(st.st_mode) == false)
return -1;
do{
ret = connect(fd, (struct sockaddr *)&addr, offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path));
if(ret != -1 || errno != EINPROGRESS)
break;
}while(1);
return ret;
}
int unix_bind(int fd, char *pathname)
{
struct sockaddr_un addr;
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
snprintf(addr.sun_path, 108, "%s", pathname);
int flag = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int));
unlink(addr.sun_path);
return bind(fd, (struct sockaddr *)&addr, offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path));
}
int unix_listen(int fd, int backlog)
{
return listen(fd, backlog);
}
int unix_accept(int sockfd, char *pathname, int pathname_len)
{
int fd = 0;
int len = sizeof(struct sockaddr_un);
struct sockaddr_un addr;
memset(&addr, 0, sizeof(struct sockaddr_un));
do{
fd = accept(sockfd, (struct sockaddr *)&addr, (socklen_t*)&len);
if(fd != -1 || errno != EAGAIN)
break;
}while(1);
if(fd >= 0)
{
fcntl(fd, F_SETFD, fcntl(fd, F_GETFL) | FD_CLOEXEC);
#if 0
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
#else
struct timeval tv = {
.tv_sec = 3,
.tv_usec = 0
};
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(struct timeval));
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval));
#endif
if(pathname && pathname_len>0)
{
len -= offsetof(struct sockaddr_un, sun_path);
addr.sun_path[len < 108 ? len : 108-1] = 0;
snprintf(pathname, pathname_len, "%s", addr.sun_path);
}
}
return fd;
}
void unix_close(int fd, char *pathname)
{
if(fd > 0)
close(fd);
if(pathname)
{
struct sockaddr_un addr;
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
snprintf(addr.sun_path, 108, "%s", pathname);
unlink(addr.sun_path);
}
}
UNIX Domain Socket
最新推荐文章于 2024-08-07 16:08:22 发布