我有一个循环处理一个
accept(2)
打电话。我想在一个
SIGINT
signal
功能。
void signal_handler(int signal) {
printf("Caught signal\n");
}
int main() {
signal(SIGINT, &signal_handler);
// ...
int accept_fd = accept(sock, NULL, NULL);
if (accept_fd == -1) {
close(sock);
perror("accept");
return 1;
}
// ...
}
如果我修改
main
使用
sigaction
int main() {
struct sigaction sa;
sa.sa_handler = &signal_handler;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGINT, &sa, NULL);
// ...
int accept_fd = accept(sock, NULL, NULL);
if (accept_fd == -1) {
close(sock);
perror("accept");
return 1;
}
// ...
}
发送信号后,我得到
Caught Signal
,后跟
accept: Interrupted system call
. 从手册页
接受(2)
错误
EINTR系统调用被在有效连接到达之前捕获的信号中断;请参阅信号(7)。
我明白
更现代,我应该多用一次
信号
,但我很好奇为什么它提供了这种功能上的差异。
下面我为每个案例提供了一个完整的可用示例程序。
信号示例(2)
#include <netdb.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 32
void signal_handler(int signal) {
printf("Caught signal\n");
}
int main() {
signal(SIGINT, &signal_handler);
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
struct addrinfo *addr_info;
int info_result = getaddrinfo("localhost", "8080", &hints, &addr_info);
if (info_result != 0) {
printf("Getting address failed\n");
return 1;
}
int sock = socket(addr_info->ai_family, addr_info->ai_socktype, addr_info->ai_protocol);
if (sock == -1) {
printf("Socket Failed\n");
return 1;
}
int bind_result = bind(sock, addr_info->ai_addr, addr_info->ai_addrlen);
if (bind_result == -1) {
close(sock);
printf("Bind Failed\n");
return 1;
}
int listen_result = listen(sock, 8);
if (listen_result == -1) {
close(sock);
printf("Listen Failed\n");
return 1;
}
printf("Waiting...\n");
int accept_fd = accept(sock, NULL, NULL);
if (accept_fd == -1) {
close(sock);
perror("accept");
return 1;
}
printf("Got fd %d\n", accept_fd);
char *buffer = malloc(BUFFER_SIZE * sizeof(char));
int n;
while ((n = read(accept_fd, buffer, BUFFER_SIZE)) > 0) {
printf("%.*s\n", n, buffer);
}
close(sock);
}
#include <netdb.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 32
void signal_handler(int signal) {
printf("Caught signal\n");
}
int main() {
struct sigaction sa;
sa.sa_handler = &signal_handler;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGINT, &sa, NULL);
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
struct addrinfo *addr_info;
int info_result = getaddrinfo("localhost", "8080", &hints, &addr_info);
if (info_result != 0) {
printf("Getting address failed\n");
return 1;
}
int sock = socket(addr_info->ai_family, addr_info->ai_socktype, addr_info->ai_protocol);
if (sock == -1) {
printf("Socket Failed\n");
return 1;
}
int bind_result = bind(sock, addr_info->ai_addr, addr_info->ai_addrlen);
if (bind_result == -1) {
close(sock);
printf("Bind Failed\n");
return 1;
}
int listen_result = listen(sock, 8);
if (listen_result == -1) {
close(sock);
printf("Listen Failed\n");
return 1;
}
printf("Waiting...\n");
int accept_fd = accept(sock, NULL, NULL);
if (accept_fd == -1) {
close(sock);
perror("accept");
return 1;
}
printf("Got fd %d\n", accept_fd);
char *buffer = malloc(BUFFER_SIZE * sizeof(char));
int n;
while ((n = read(accept_fd, buffer, BUFFER_SIZE)) > 0) {
printf("%.*s\n", n, buffer);
}
close(sock);
}