C语言 如何在 C 中创建具有特定权限的 Unix 域套接字?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20171747/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create Unix Domain Socket with a specific permissions in C?
提问by abyss.7
I have a simple code, like:
我有一个简单的代码,例如:
sockaddr_un address;
address.sun_family = AF_UNIX;
strcpy(address.sun_path, path);
unlink(path);
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
bind(fd, (sockaddr*)(&address), sizeof(address));
listen(fd, 100);
I want to atomicallycreate the Unix Domain Socket file with a specific permissions, say: 0777. The manual doesn't say anything about socket file permissions with regard to umaskor whatever. Even, if the umaskdoes affect the socket file, then it's not an atomic way - in multi-threaded program.
我想原子地创建具有特定权限的 Unix 域套接字文件,例如:0777. 该手册没有说明有关套接字文件权限umask或其他内容的任何内容。即使,如果umask确实影响了套接字文件,那么它也不是原子方式 - 在多线程程序中。
I hope, there is a way to achieve my goal without using synchronization of umask()calls.
我希望,有一种方法可以在不使用umask()调用同步的情况下实现我的目标。
采纳答案by Elias M?rtenson
Another solution is to create a directory with the desired permissions, and then create the socket inside it (example code without any regard for error checking and buffer overflows):
另一种解决方案是创建一个具有所需权限的目录,然后在其中创建套接字(示例代码不考虑错误检查和缓冲区溢出):
// Create a directory with the proper permissions
mkdir(path, 0700);
// Append the name of the socket
strcat(path, "/socket_name");
// Create the socket normally
sockaddr_un address;
address.sun_family = AF_UNIX;
strcpy(address.sun_path, path);
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
bind(fd, (sockaddr*)(&address), sizeof(address));
listen(fd, 100);
回答by Don Carr
I had the best luck using chmod() (NOT fchmod) using the file name for the unix domain socket after calling socket(), bind(), but, before calling listen().
我在调用 socket()、bind() 之后使用 chmod()(不是 fchmod)使用 unix 域套接字的文件名获得了最好的运气,但是在调用 listen() 之前。
int return_value;
const char *sock_path;
struct sockaddr_un local;
sock_path = "/tmp/mysocket";
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockfd == -1)
{
perror("socket");
exit(-1);
}
local.sun_family = AF_UNIX;
strcpy(local.sun_path, sock_path);
unlink(local.sun_path);
len = strlen(local.sun_path) + sizeof(local.sun_family);
bind(sockfd, (struct sockaddr *)&local, len);
chmod(sock_path, 0777);
retval = listen(sockfd, BACKLOG);
if (retval == -1)
{
perror("listen");
exit(-1);
}
. . . . .
. . . . .
回答by Anonymous
Forking, using umask and passing back the fd is the only portable way I can think of. Having a directory for the socket is better in any case, for example nobody can delete the socket if the directory doesn't ahve the proper permissions, and creating diretcories can be done atomically.
分叉,使用 umask 并传回 fd 是我能想到的唯一可移植方式。在任何情况下都有一个套接字目录更好,例如,如果目录没有适当的权限,则没有人可以删除套接字,并且可以原子地创建目录。
The bigger problem is that relying on permissions is not portable - many BSD-derived socket stacks simply ignore the permissions of enclosing directories and/or the socket itself.
更大的问题是依赖权限是不可移植的——许多 BSD 派生的套接字堆栈只是忽略了封闭目录和/或套接字本身的权限。
On GNU/Linux systems, you cna do it by calling fchmod on the socket fd after socket() and before bind()
在 GNU/Linux 系统上,您可以通过在 socket() 之后和 bind() 之前在套接字 fd 上调用 fchmod 来实现

