У меня есть несколько фрагментов кода для установки сокета домена Unix и службы, использующей этот сокет. Хотя здесь есть некоторые запутанные ошибки, ведущие к сбою.
код, который создает сокет домена Unix, написан на c:
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/un.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
int main(int ac, char *av[])
{
if (ac != 4) {
printf("Usage: %s dummy-fd sockpath binary\n", av[0]);
exit(-1);
}
char *sockpn = av[2];
char *bin = av[3];
int srvfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (srvfd < 0) {
perror("socket");
exit(-1);
}
fcntl(srvfd, F_SETFD, FD_CLOEXEC);
struct stat st;
if (stat(sockpn, &st) >= 0) {
if (!S_ISSOCK(st.st_mode)) {
fprintf(stderr, "socket pathname %s exists and is not a socket\n",
sockpn);
exit(-1);
}
unlink(sockpn);
}
struct sockaddr_un addr;
addr.sun_family = AF_UNIX;
snprintf(&addr.sun_path[0], sizeof(addr.sun_path), "%s", sockpn);
if (bind(srvfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
fprintf(stderr, "WARNING: cannot bind to socket %s (%s), exiting\n",
sockpn, strerror(errno));
exit(-1);
}
// allow anyone to connect; for access control, use directory permissions
chmod(sockpn, 0777);
listen(srvfd, 5);
signal(SIGCHLD, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
for (;;) {
struct sockaddr_un client_addr;
unsigned int addrlen = sizeof(client_addr);
int cfd = accept(srvfd, (struct sockaddr *) &client_addr, &addrlen);
if (cfd < 0) {
perror("accept");
continue;
}
int pid = fork();
if (pid < 0) {
perror("fork");
close(cfd);
continue;
}
if (pid == 0) {
// Child process
dup2(cfd, 0);
dup2(cfd, 1);
close(cfd);
execl(bin, bin, 0);
perror("execl");
exit(-1);
}
close(cfd);
}
}
клиентский Python для использования этого sock выглядит следующим образом (unixclient.py):
def call(pn, req):
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect(pn)
sock.send(req)
sock.shutdown(socket.SHUT_DOWN)
data = ""
while True:
buf = sock.recv(1024)
if not buf:
break
data += buf
sock.close()
return data
И я запускаю этот фрагмент клиентского кода в другом коде Python, импортируя этот файл и вызывая функцию call
:(оба "/jail/zoobar/echosvc" и "/jail/zoobar/echosvc/sock" не будут работать)
resp = call("/jail/zoobar/echosvc", str1)
Там возникает ошибка, показывающая, что:
FIle "zoobar/unixclient.py", line 8, in call
sock.connect(pn)
File "<string>", line 1, in connect
error: [ERROR 2] No such file or directory
Тем не менее, я клянусь, что каталог и сокет существуют (/jail/zoobar/echosvc/sock), и разрешение тоже правильное (777), поэтому я не могу понять эту странную ошибку. Кто-нибудь знает об этом?
Я был бы очень признателен за экономию времени, чтобы помочь.
memset(&address, 0, sizeof(struct sockaddr_un));
в первый фрагмент кода, но тот же сбой. - person Kalzium   schedule 05.02.2013pn
это путь доменного сокета, здесь"/jail/zoobar/echosvc"
,req
это параметр, в связке не имеет значения. Когдаpn
равно"/jail/zoobar/echosvc/sock"
, все равно происходит та же ошибка. - person Kalzium   schedule 05.02.2013sock
на самом делеsocket
, сейчас исправлю - person Kalzium   schedule 05.02.2013