set_fl()和clr_fl()函数原型

本文提供了两个用于处理文件描述符的函数:set_fl用于设置文件状态标志,clr_fl用于清除文件状态标志。通过fcntl系统调用实现,适用于Linux等类Unix系统。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

突然想起下边这两个函数的原型也不太好找,所以贴出来与大家共享。

void set_fl(int fd, int flags) /* flags are file status flags to turn on */
{
    int        val;

    if ( (val = fcntl(fd, F_GETFL, 0)) < 0)
        {
            printf("fcntl F_GETFL error");
            exit(1);
        }

    val |= flags;        /* turn on flags */

    if (fcntl(fd, F_SETFL, val) < 0)
        {
            printf("fcntl F_SETFL error");
            exit(1);
        }
}

void clr_fl(int fd, int flags)
{
    int val;

    if ((val = fcntl(fd, F_GETFL, 0)) == -1)
    {
        syslog(LOG_ERR, __FILE__, __LINE__,"fcntl() error : %s", strerror(errno));
        exit(1);
    }
    val &= ~flags; /* turn flags off */

    if (fcntl(fd, F_SETFL, val) == -1)
    {
        syslog(LOG_ERR, __FILE__, __LINE__,"fcntl() error : %s", strerror(errno));
        exit(1);
    }
    return;
}

  

转载于:https://www.cnblogs.com/panxiongfei/p/3482719.html

#include "web_server.h" #include <sys/select.h> // 创建socket (同多线程版本) int create_socket() { /* 同multithreaded.c */ } void bind_socket(int sockfd) { /* 同multithreaded.c */ } const char* get_content_type(const char* path) { /* 同multithreaded.c */ } int is_path_safe(const char* path) { /* 同multithreaded.c */ } void send_http_response(int client_fd, http_status_t status, const char* content_type, off_t content_length) { /* 同multithreaded.c */ } void send_error_response(int client_fd, http_status_t status) { /* 同multithreaded.c */ } int main() { int server_fd = create_socket(); bind_socket(server_fd); // 设置非阻塞模式 fcntl(server_fd, F_SETFL, fcntl(server_fd, F_GETFL) | O_NONBLOCK); if (listen(server_fd, 128) < 0) { perror("listen"); exit(EXIT_FAILURE); } fd_set read_fds, write_fds; FD_ZERO(&read_fds); FD_ZERO(&write_fds); FD_SET(server_fd, &read_fds); int max_fd = server_fd; client_state_t clients[MAX_CLIENTS] = {0}; printf("[IO Multiplex] Web server running on port %d...\n", PORT); while (1) { fd_set tmp_read = read_fds; fd_set tmp_write = write_fds; if (select(max_fd + 1, &tmp_read, &tmp_write, NULL, NULL) < 0) { perror("select"); continue; } // 处理新连接 if (FD_ISSET(server_fd, &tmp_read)) { struct sockaddr_in client_addr; socklen_t addr_len = sizeof(client_addr); int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &addr_len); if (client_fd > 0) { fcntl(client_fd, F_SETFL, fcntl(client_fd, F_GETFL) | O_NONBLOCK); // 添加到客户端列表 for (int i = 0; i < MAX_CLIENTS; i++) { if (clients[i].fd == 0) { clients[i].fd = client_fd; clients[i].bytes_received = 0; clients[i].header_sent = 0; FD_SET(client_fd, &read_fds); if (client_fd > max_fd) max_fd = client_fd; break; } } } } // 处理客户端请求 for (int i = 0; i < MAX_CLIENTS; i++) { if (clients[i].fd == 0) continue; int client_fd = clients[i].fd; // 读取数据 if (FD_ISSET(client_fd, &tmp_read)) { ssize_t bytes_read = recv(client_fd, clients[i].request + clients[i].bytes_received, MAX_REQUEST_SIZE - clients[i].bytes_received - 1, 0); if (bytes_read > 0) { clients[i].bytes_received += bytes_read; clients[i].request[clients[i].bytes_received] = '\0'; // 检查完整请求 if (strstr(clients[i].request, "\r\n\r\n")) { char method[16], path[256]; if (sscanf(clients[i].request, "%15s %255s", method, path) == 2 && strcmp(method, "GET") == 0) { char full_path[MAX_PATH_LENGTH]; snprintf(full_path, sizeof(full_path), "%s%s", WEBROOT, (strcmp(path, "/") == 0) ? "/index.html" : path); if (!is_path_safe(full_path)) { send_error_response(client_fd, HTTP_403); close(client_fd); clients[i].fd = 0; FD_CLR(client_fd, &read_fds); FD_CLR(client_fd, &write_fds); continue; } clients[i].file_fd = open(full_path, O_RDONLY); if (clients[i].file_fd < 0) { send_error_response(client_fd, HTTP_404); close(client_fd); clients[i].fd = 0; FD_CLR(client_fd, &read_fds); FD_CLR(client_fd, &write_fds); continue; } struct stat file_stat; fstat(clients[i].file_fd, &file_stat); clients[i].file_size = file_stat.st_size; clients[i].file_offset = 0; const char* content_type = get_content_type(full_path); char header[512]; snprintf(header, sizeof(header), "HTTP/1.1 200 OK\r\n" "Content-Type: %s\r\n" "Content-Length: %ld\r\n" "Connection: close\r\n\r\n", content_type, clients[i].file_size); memcpy(clients[i].request, header, strlen(header)); clients[i].bytes_received = strlen(header); clients[i].header_sent = 0; FD_CLR(client_fd, &read_fds); FD_SET(client_fd, &write_fds); } else { send_error_response(client_fd, HTTP_400); close(client_fd); clients[i].fd = 0; FD_CLR(client_fd, &read_fds); } } } else if (bytes_read == 0 || (bytes_read < 0 && errno != EAGAIN)) { close(client_fd); if (clients[i].file_fd > 0) close(clients[i].file_fd); clients[i].fd = 0; FD_CLR(client_fd, &read_fds); FD_CLR(client_fd, &write_fds); } } // 发送数据 if (FD_ISSET(client_fd, &tmp_write)) { if (!clients[i].header_sent) { ssize_t bytes_sent = send(client_fd, clients[i].request + clients[i].header_sent, clients[i].bytes_received - clients[i].header_sent, 0); if (bytes_sent > 0) { clients[i].header_sent += bytes_sent; } else if (bytes_sent < 0 && errno != EAGAIN) { close(client_fd); close(clients[i].file_fd); clients[i].fd = 0; FD_CLR(client_fd, &write_fds); continue; } } else { ssize_t bytes_sent = sendfile(client_fd, clients[i].file_fd, &clients[i].file_offset, clients[i].file_size - clients[i].file_offset); if (bytes_sent <= 0 && errno != EAGAIN) { close(client_fd); close(clients[i].file_fd); clients[i].fd = 0; FD_CLR(client_fd, &write_fds); } } } } } close(server_fd); return 0; } 报错代码如下io_multiplex.c: In function ‘bind_socket’: io_multiplex.c:6:22: warning: unused parameter ‘sockfd’ [-Wunused-parameter] void bind_socket(int sockfd) { /* 同multithreaded.c */ } ^ io_multiplex.c: In function ‘get_content_type’: io_multiplex.c:7:42: warning: unused parameter ‘path’ [-Wunused-parameter] const char* get_content_type(const char* path) { /* 同multithreaded.c */ } ^ io_multiplex.c: In function ‘is_path_safe’: io_multiplex.c:8:30: warning: unused parameter ‘path’ [-Wunused-parameter] int is_path_safe(const char* path) { /* 同multithreaded.c */ } ^ io_multiplex.c: In function ‘send_http_response’: io_multiplex.c:9:29: warning: unused parameter ‘client_fd’ [-Wunused-parameter] void send_http_response(int client_fd, http_status_t status, ^ io_multiplex.c:9:54: warning: unused parameter ‘status’ [-Wunused-parameter] void send_http_response(int client_fd, http_status_t status, ^ io_multiplex.c:10:37: warning: unused parameter ‘content_type’ [-Wunused-parameter] const char* content_type, off_t content_length) { /* 同multithreaded.c */ } ^ io_multiplex.c:10:57: warning: unused parameter ‘content_length’ [-Wunused-parameter] const char* content_type, off_t content_length) { /* 同multithreaded.c */ } ^ io_multiplex.c: In function ‘send_error_response’: io_multiplex.c:11:30: warning: unused parameter ‘client_fd’ [-Wunused-parameter] void send_error_response(int client_fd, http_status_t status) { /* 同multithreaded.c */ } ^ io_multiplex.c:11:55: warning: unused parameter ‘status’ [-Wunused-parameter] void send_error_response(int client_fd, http_status_t status) { /* 同multithreaded.c */ } ^ io_multiplex.c: In function ‘main’: io_multiplex.c:31:5: warning: missing braces around initializer [-Wmissing-braces] client_state_t clients[MAX_CLIENTS] = {0}; ^ io_multiplex.c:31:5: warning: (near initialization for ‘clients[0]’) [-Wmissing-braces] io_multiplex.c: In function ‘create_socket’: io_multiplex.c:5:1: warning: control reaches end of non-void function [-Wreturn-type] int create_socket() { /* 同multithreaded.c */ } ^ io_multiplex.c: In function ‘get_content_type’: io_multiplex.c:7:1: warning: control reaches end of non-void function [-Wreturn-type] const char* get_content_type(const char* path) { /* 同multithreaded.c */ } ^ io_multiplex.c: In function ‘is_path_safe’: io_multiplex.c:8:1: warning: control reaches end of non-void function [-Wreturn-type] int is_path_safe(const char* path) { /* 同multithreaded.c */ } ^
08-08
#include "common.h" #include <sys/select.h> #define MAX_CLIENTS 1024 int main() { int server_fd = socket(AF_INET, SOCK_STREAM, 0); // ... (初始化代码同多线程版本) fd_set read_fds, master_fds; FD_ZERO(&master_fds); FD_SET(server_fd, &master_fds); int max_fd = server_fd; printf("IO Multiplexing server running on port %d\n", PORT); while (1) { read_fds = master_fds; if (select(max_fd + 1, &read_fds, NULL, NULL, NULL) < 0) { perror("select"); continue; } for (int fd = 0; fd <= max_fd; fd++) { if (!FD_ISSET(fd, &read_fds)) continue; if (fd == server_fd) { // 新连接 struct sockaddr_in client_addr; socklen_t client_len = sizeof(client_addr); int client_sock = accept(server_fd, (struct sockaddr*)&client_addr, &client_len); if (client_sock < 0) { perror("accept"); } else { FD_SET(client_sock, &master_fds); if (client_sock > max_fd) max_fd = client_sock; char client_ip[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, sizeof(client_ip)); printf("New connection from %s\n", client_ip); } } else { // 客户端数据 HttpRequest req; parse_request(fd, &req); if (req.method[0] != '\0') { // 有效请求 struct sockaddr_in client_addr; socklen_t addr_len = sizeof(client_addr); getpeername(fd, (struct sockaddr*)&client_addr, &addr_len); char client_ip[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, sizeof(client_ip)); log_request(client_ip, &req); if (strcmp(req.method, "GET") == 0) { handle_get(fd, &req); } else if (strcmp(req.method, "POST") == 0) { handle_post(fd, &req); } else { send_response(fd, 501, "Not Implemented", "text/plain", "Method not implemented", 21); } } free_request(&req); close(fd); FD_CLR(fd, &master_fds); } } } close(server_fd);这段代码出现accept:invalid
最新发布
08-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值