Как создать сокет домена Unix с определенными разрешениями в C?
у меня есть простой код, например:
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);
Я хочу атомарно создайте файл сокета домена Unix с определенными разрешениями, скажем:0777
. В руководстве ничего не говорится о разрешениях файлов сокетов в отношении umask
или что-то еще. Даже, если umask
влияет на файл сокета, тогда это не атомарный способ в многопоточной программе.
Я надеюсь, что есть способ достичь моей цели без использования синхронизации umask()
звонки.
3 ответов
другое решение-создать каталог с требуемыми разрешениями, а затем создать сокет внутри него (пример кода без учета проверки ошибок и переполнения буфера):
// 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);
Мне повезло использовать chmod () (не fchmod), используя имя файла для сокета домена unix после вызова socket (), bind (), но перед вызовом 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);
}
. . . . .
раздвоение, использование umask и передача FD-единственный портативный способ, который я могу придумать. Иметь каталог для сокета лучше в любом случае, например, никто не может удалить сокет, если каталог не имеет надлежащих разрешений, и создание diretcories может быть сделано атомарно.
большая проблема заключается в том, что использование разрешений не является переносимым - многие стеки сокетов, производные от BSD, просто игнорируют разрешения вложенных каталогов и / или сокета себя.
в системах GNU / Linux вы можете сделать это, вызвав fchmod в сокете FD после socket () и перед bind ()