Пилю значит я очередную свою поделку и встречаю нипонятную вещь: accept() возвращает EFAULT всегда, когда я пытаюсь ему передать что-то кроме нуля вторым и 3-м агрументом. Причем работает он так же, как bind(), но бинд работает, а accept() нет. Насколько я понял bind - это копирование userspace->kernelspace, а accept() kernelspace->userspace в этом может быть причина и я где-то зафейлил. Может надо его как-то поособому юзать и т.п.?
Прикрепляю портынку говнокода своего, прошу сильно не бить и помочь:
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/epoll.h>
#include <sys/errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>
int32_t global_eplfd,
global_defaultdf;
struct sockaddr_in global_addr;
struct epoll_event global_epoll_event;
struct epoll_event global_epoll_events[100500];
inline uint8_t exit_nv(int32_t __status) {
exit(__status);
return 123;
}
#define CKFD(arg) do{(arg) == -1 && fprintf(stderr, "error : (%s), errno = %d\n", #arg, errno) && exit_nv(1);}while(0);
#define CKEW(arg) ((arg) != -1 || fprintf(stderr, "error : (%s), errno = %d\n", #arg, errno) && exit_nv(1))
void init(void) {
CKFD(global_eplfd = epoll_create(100500));
CKFD(global_defaultdf = socket(AF_INET, SOCK_STREAM, 0));
global_addr.sin_family = AF_INET;
global_addr.sin_port = htons(1123);
global_addr.sin_addr.s_addr = htonl(INADDR_ANY);
CKFD(bind(global_defaultdf, (struct sockaddr *)&global_addr, sizeof(global_addr)));
CKFD(listen(global_defaultdf, 128));
global_epoll_event.data.fd = global_defaultdf;
global_epoll_event.events = EPOLLIN | EPOLLRDHUP;
CKFD(epoll_ctl(global_eplfd, EPOLL_CTL_ADD, global_defaultdf, &global_epoll_event));
}
int32_t main(int32_t argc, char **argv) {
init();
int32_t i, ev_fd;
while(CKEW(i = epoll_wait(global_eplfd, global_epoll_events, 100500, -1))) {
fprintf(stdout, "unsleep, ev = %d\n", i);
while(--i > -1 && ((ev_fd = global_epoll_events[i].data.fd) || (fprintf(stderr, "bad_df\n") && exit_nv(1)))) {
fprintf(stdout, "new ev, fd = %d\n", ev_fd);
if(ev_fd == global_defaultdf) {
// CKFD(ev_fd = accept4(global_defaultdf, (struct sockaddr *)&global_addr, sizeof(global_addr), SOCK_NONBLOCK));//fail;
CKFD(ev_fd = accept4(global_defaultdf, 0, 0, SOCK_NONBLOCK));//not fail;
global_epoll_event.data.fd = ev_fd;
CKFD(epoll_ctl(global_eplfd, EPOLL_CTL_ADD, ev_fd, &global_epoll_event));
} else {
if(global_epoll_events[i].events & EPOLLRDHUP) { close(ev_fd); fprintf(stdout, "close, fd = %d\n", ev_fd);} else {
uint8_t buf[100500];
uint16_t end;
CKFD(end = read(ev_fd, buf, 100500))
buf[end] = '\0';
fprintf(stdout, "read message:\n %s", buf);
}
}
}
}
return 0;
}