32

我有一个简单的代码,例如:

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 Domain Socket 文件,例如:0777. 该手册没有说明有关套接字文件权限的umask任何内容。即使,如果umask确实影响套接字文件,那么它也不是一种原子方式 - 在多线程程序中。

我希望,有一种方法可以在不使用umask()调用同步的情况下实现我的目标。

4

3 回答 3

22

另一种解决方案是创建一个具有所需权限的目录,然后在其中创建套接字(示例代码不考虑错误检查和缓冲区溢出):

// 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);
于 2014-02-05T03:22:28.740 回答
15

在调用 socket()、bind() 之后,但是在调用listen() 之前,我使用 chmod()(不是 fchmod)使用 unix 域套接字的文件名获得了最好的运气。

  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);
  }

. . . . .

于 2014-07-02T21:46:40.700 回答
8

分叉,使用 umask 并传回 fd 是我能想到的唯一可移植方式。在任何情况下都有一个套接字目录会更好,例如,如果目录没有适当的权限,则没有人可以删除套接字,并且可以原子地创建目录。

更大的问题是依赖权限是不可移植的——许多 BSD 派生的套接字堆栈只是忽略了封闭目录和/或套接字本身的权限。

在 GNU/Linux 系统上,您可以通过在 socket() 之后和 bind() 之前在套接字 fd 上调用 fchmod 来实现

于 2014-06-14T01:57:55.727 回答