Как создать сокет домена 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 ()