UNIX(7) Miscellaneous Information Manual UNIX(7) unix - #include #include unix_socket = socket(AF_UNIX, type, 0); error = socketpair(AF_UNIX, type, 0, int *sv); AF_UNIX ( AF_LOCAL) . UNIX ( ). Linux . UNIX : SOCK_STREAM SOCK_DGRAM ( UNIX UNIX ) ( Linux 2.6.4) SOCK_SEQPACKET . UNIX . UNIX : struct sockaddr_un { sa_family_t sun_family; /* AF_UNIX */ char sun_path[108]; /* Pathname */ }; sun_family AF_UNIX. Linux sun_path 108 BUGS . ( bind(2) connect(2) sendto(2)) sockaddr_un . ( getsockname(2) getpeername(2) recvfrom(2) accept(2)) . sockaddr_un: pathname UNIX bind(2). ( ) offsetof(struct sockaddr_un, sun_path) + strlen(sun_path) + 1 sun_path . ( Linux offsetof() sizeof(sa_family_t) sun_path offsetof() .) . unnamed bind(2) . socketpair(2) . sizeof(sa_family_t) sun_path. abstract ( ) sun_path[0] ('\0'). sun_path . ( .) . addrlen sizeof(sa_family_t) ( 2) (addrlen - sizeof(sa_family_t)) sun_path. : o sun_path . o sun_path. o addrlen sockaddr_un : offsetof(struct sockaddr_un, sun_path)+strlen(addr.sun_path)+1 addrlen sizeof(struct sockaddr_un). UNIX . ( ) sun_path . sun_path 92 . (accept(2) recvfrom(2) getsockname(2) getpeername(2)) . UNIX addrlen - . . : sun_path. ( BUGS.) . () . . POSIX ( BSD ) . . . umask(2) . ( chown(2) chmod(2)). : umask(2) ( fchown(2) fchmod(2)) . . . SOL_SOCKET AF_UNIX. setsockopt(2) getsockopt(2) SOL_SOCKET . SO_PASSCRED SCM_CREDENTIALS . SCM_CREDENTIALS SCM_CREDENTIALS . . setsockopt(2) getsockopt(2) . SO_PASSSEC SELinux SCM_SECURITY ( ). setsockopt(2) getsockopt(2) . SO_PASSSEC 2.6.18 4.2. SO_PEEK_OFF socket(7). SO_PEERCRED . connect(2) listen(2) socketpair(2). getsockopt(2) ucred _GNU_SOURCE . AF_UNIX AF_UNIX socketpair(2). bind(2) addrlen sizeof(sa_family_t) SO_PASSCRED . 5 [0-9a-f]. 2^20 . ( 2.1.15 8 2^32 . 5 2.3.15.) (Sockets API) . ( MSG_OOB send(2) recv(2)). MSG_MORE send(2) . 3.4 MSG_TRUNC flags recv(2) . SO_SNDBUF SO_RCVBUF . SO_SNDBUF . ( socket(7)) 32 . sendmsg(2) recvmsg(2). SOL_SOCKET AF_UNIX. cmsg_level cmsghdr SOL_SOCKET cmsg_type . cmsg(3). SCM_RIGHTS . . " " . ( open(2)) . (dup(2)) . ( ) ( ) . RLIMIT_NOFILE ( getrlimit(2)) . SCM_MAX_FD . sendmsg(2) EINVAL. SCM_MAX_FD 253 ( 255 Linux 2.6.38). SCM_CREDENTIALS UNIX. . struct ucred. : struct ucred { pid_t pid; /* Process ID of the sending process */ uid_t uid; /* User ID of the sending process */ gid_t gid; /* Group ID of the sending process */ }; glibc 2.8 _GNU_SOURCE ( ) . . . ( CAP_SYS_ADMIN PID ) ( CAP_SETUID) ( CAP_SETGID). struct ucred SO_PASSCRED . SCM_SECURITY SELinux ( ) . . NAME_MAX . SO_PASSSEC ( ). sendmsg(2) . . Linux UNIX. UNIX Linux . . . : (1) sendmsg(2) . (2) sendmsg(2) . (3) sendmsg(2) . recvmsg(2) 20 . sendmsg(2) . . ( SCM_RIGHTS ). ( msg_control msghdr recvmsg(2) NULL) . MSG_CTRUNC msg.msg_flags recvmsg(2). Ioctls ioctl(2) value. : int value; error = ioctl(unix_socket, ioctl_type, &value); ioctl_type: SIOCINQ SOCK_STREAM . LISTEN (EINVAL). SIOCINQ . FIONREAD . SOCK_DGRAM udp(7). EADDRINUSE . EBADF sendmsg(2) UNIX ( SCM_RIGHTS ) ( ). ECONNREFUSED connect(2) . . ECONNRESET . EFAULT . EINVAL . AF_UNIX sun_type . EISCONN connect(2) . ENFILE . ENOENT connect(2) . ENOMEM . ENOTCONN . EOPNOTSUPP . EPERM struct ucred. EPIPE . SIGPIPE . MSG_NOSIGNAL send(2) sendmsg(2). EPROTONOSUPPORT AF_UNIX. EPROTOTYPE (SOCK_DGRAM SOCK_STREAM). ESOCKTNOSUPPORT . ESRCH (SCM_CREDENTIALS) PID . ETOOMANYREFS sendmsg(2) UNIX ( SCM_RIGHTS ). " " RLIMIT_NOFILE CAP_SYS_RESOURCE. sendmsg(2) recvmsg(2). Linux 4.5 ( ). sendmsg(2) RLIMIT_NOFILE. . . SCM_CREDENTIALS Linux 2.2 . ( BSD .) ( unlink(2)). UNIX . SOCK_STREAM sendmsg(2) recvmsg(2). UNIX . Linux sun_path. : . : 108 sizeof(sun_path). ( accept(2)) addrlen sizeof(struct sockaddr_un) sun_path. ( addrlen sun_path) sun_path. ( ) sun_path : strnlen(addr.sun_path, addrlen - offsetof(sockaddr_un, sun_path)) sizeof(struct sockaddr_un)+1 . addrlen sizeof(struct sockaddr_un) sun_path: void *addrp; addrlen = sizeof(struct sockaddr_un); addrp = malloc(addrlen + 1); if (addrp == NULL) /* Handle error */ ; memset(addrp, 0, addrlen + 1); if (getsockname(sfd, (struct sockaddr *) addrp, &addrlen)) == -1) /* handle error */ ; printf("sun_path = %s\n", ((struct sockaddr_un *) addrp)->sun_path); . . . . . . "END". . . . "DOWN". . "DOWN". $ ./server & [1] 25887 $ ./client 3 4; Result = 7 $ ./client 11 -5; Result = 6 $ ./client DOWN; Result = 0 [1]+ Done ./server $ /* * File connection.h */ #ifndef CONNECTION_H #define CONNECTION_H #define SOCKET_NAME "/tmp/9Lq7BNBnBycd6nxy.socket" #define BUFFER_SIZE 12 #endif // include guard /* * File server.c */ #include #include #include #include #include #include #include #include "connection.h" int main(void) { int down_flag = 0; int ret; int connection_socket; int data_socket; int result; ssize_t r, w; struct sockaddr_un name; char buffer[BUFFER_SIZE]; /* Create local socket. */ connection_socket = socket(AF_UNIX, SOCK_SEQPACKET, 0); if (connection_socket == -1) { perror("socket"); exit(EXIT_FAILURE); } /* * For portability clear the whole structure, since some * implementations have additional (nonstandard) fields in * the structure. */ memset(&name, 0, sizeof(name)); /* Bind socket to socket name. */ name.sun_family = AF_UNIX; strncpy(name.sun_path, SOCKET_NAME, sizeof(name.sun_path) - 1); ret = bind(connection_socket, (const struct sockaddr *) &name, sizeof(name)); if (ret == -1) { perror("bind"); exit(EXIT_FAILURE); } /* * Prepare for accepting connections. The backlog size is set * to 20. So while one request is being processed other requests * can be waiting. */ ret = listen(connection_socket, 20); if (ret == -1) { perror("listen"); exit(EXIT_FAILURE); } /* This is the main loop for handling connections. */ for (;;) { /* Wait for incoming connection. */ data_socket = accept(connection_socket, NULL, NULL); if (data_socket == -1) { perror("accept"); exit(EXIT_FAILURE); } result = 0; for (;;) { /* Wait for next data packet. */ r = read(data_socket, buffer, sizeof(buffer)); if (r == -1) { perror("read"); exit(EXIT_FAILURE); } /* Ensure buffer is 0-terminated. */ buffer[sizeof(buffer) - 1] = 0; /* Handle commands. */ if (!strncmp(buffer, "DOWN", sizeof(buffer))) { down_flag = 1; continue; } if (!strncmp(buffer, "END", sizeof(buffer))) { break; } if (down_flag) { continue; } /* Add received summand. */ result += atoi(buffer); } /* Send result. */ sprintf(buffer, "%d", result); w = write(data_socket, buffer, sizeof(buffer)); if (w == -1) { perror("write"); exit(EXIT_FAILURE); } /* Close socket. */ close(data_socket); /* Quit on DOWN command. */ if (down_flag) { break; } } close(connection_socket); /* Unlink the socket. */ unlink(SOCKET_NAME); exit(EXIT_SUCCESS); } /* * File client.c */ #include #include #include #include #include #include #include #include "connection.h" int main(int argc, char *argv[]) { int ret; int data_socket; ssize_t r, w; struct sockaddr_un addr; char buffer[BUFFER_SIZE]; /* Create local socket. */ data_socket = socket(AF_UNIX, SOCK_SEQPACKET, 0); if (data_socket == -1) { perror("socket"); exit(EXIT_FAILURE); } /* * For portability clear the whole structure, since some * implementations have additional (nonstandard) fields in * the structure. */ memset(&addr, 0, sizeof(addr)); /* Connect socket to socket address. */ addr.sun_family = AF_UNIX; strncpy(addr.sun_path, SOCKET_NAME, sizeof(addr.sun_path) - 1); ret = connect(data_socket, (const struct sockaddr *) &addr, sizeof(addr)); if (ret == -1) { fprintf(stderr, "The server is down.\n"); exit(EXIT_FAILURE); } /* Send arguments. */ for (int i = 1; i < argc; ++i) { w = write(data_socket, argv[i], strlen(argv[i]) + 1); if (w == -1) { perror("write"); break; } } /* Request result. */ strcpy(buffer, "END"); w = write(data_socket, buffer, strlen(buffer) + 1); if (w == -1) { perror("write"); exit(EXIT_FAILURE); } /* Receive result. */ r = read(data_socket, buffer, sizeof(buffer)); if (r == -1) { perror("read"); exit(EXIT_FAILURE); } /* Ensure buffer is 0-terminated. */ buffer[sizeof(buffer) - 1] = 0; printf("Result = %s\n", buffer); /* Close socket. */ close(data_socket); exit(EXIT_SUCCESS); } SCM_RIGHTS cmsg(3) seccomp_unotify(2). recvmsg(2), sendmsg(2), socket(2), socketpair(2), cmsg(3), capabilities(7), credentials(7), socket(7), udp(7) 3 . . : . 6.18 8 2026 UNIX(7)