📄 std.c
字号:
/* * Copyright (c) 1998-2002 Caucho Technology -- all rights reserved * * Caucho Technology permits modification and use of this file in * source and binary form ("the Software") subject to the Caucho * Developer Source License 1.1 ("the License") which accompanies * this file. The License is also available at * http://www.caucho.com/download/cdsl1-1.xtp * * In addition to the terms of the License, the following conditions * must be met: * * 1. Each copy or derived work of the Software must preserve the copyright * notice and this notice unmodified. * * 2. Each copy of the Software in source or binary form must include * an unmodified copy of the License in a plain ASCII text file named * LICENSE. * * 3. Caucho reserves all rights to its names, trademarks and logos. * In particular, the names "Resin" and "Caucho" are trademarks of * Caucho and may not be used to endorse products derived from * this software. "Resin" and "Caucho" may not appear in the names * of products derived from this software. * * This Software is provided "AS IS," without a warranty of any kind. * ALL EXPRESS OR IMPLIED REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. * * CAUCHO TECHNOLOGY AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE OR ANY THIRD PARTY AS A RESULT OF USING OR * DISTRIBUTING SOFTWARE. IN NO EVENT WILL CAUCHO OR ITS LICENSORS BE LIABLE * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF HE HAS BEEN ADVISED OF THE POSSIBILITY * OF SUCH DAMAGES. * * @author Scott Ferguson */#include <sys/types.h>#ifdef WIN32#include <windows.h>#else#include <sys/time.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/tcp.h>#include <netdb.h>#include <unistd.h>#endif#include <sys/stat.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>/* probably system-dependent */#include <jni.h>#include <errno.h>#include <signal.h>#include "../common/cse.h"#include "version.h"#include "resin.h"#include "resin_jni.h"static int std_open(connection_t *conn, int fd);static int std_read(connection_t *conn, char *buf, int len);static int std_write(connection_t *conn, char *buf, int len);int conn_close(connection_t *conn);void std_free(connection_t *conn);static int std_read_client_certificate(connection_t *conn, char *buf, int len);struct connection_ops_t std_ops = { std_open, std_read, std_write, conn_close, std_free, std_read_client_certificate,};static intexception_status(connection_t *conn, int error){ if (error == EINTR || error == EAGAIN) return INTERRUPT_EXN; else if (error == EPIPE || errno == ECONNRESET) { conn->ops->close(conn); return DISCONNECT_EXN; } else { conn->ops->close(conn); return -1; }}static intstd_open(connection_t *conn, int fd){ conn->fd = fd; return fd;}static intstd_read(connection_t *conn, char *buf, int len){ fd_set read_mask; struct timeval timeout; int fd; int ms; int result; int retry = 100; if (! conn) return -1; fd = conn->fd; ms = conn->timeout; if (fd < 0) return -1; FD_ZERO(&read_mask); if (ms <= 0) { timeout.tv_sec = 65; timeout.tv_usec = 0; } else { timeout.tv_sec = ms / 1000; timeout.tv_usec = ms % 1000 * 1000; } while (retry-- > 0) { FD_SET(fd, &read_mask); result = select(fd + 1, &read_mask, 0, 0, &timeout); if (result > 0) { } else if (result == 0) { return TIMEOUT_EXN; } else if (errno == EINTR || errno == EAGAIN) continue; else return exception_status(conn, errno); result = recv(fd, buf, len, 0); if (result >= 0) return result; else if (errno == EINTR || errno == EAGAIN) continue; else return exception_status(conn, errno); } return TIMEOUT_EXN;}static intstd_write(connection_t *conn, char *buf, int len){ fd_set write_mask; struct timeval timeout; int fd; int ms; int result; int retry = 100; if (! conn) return -1; fd = conn->fd; if (fd < 0) return -1; while (retry-- > 0) { if (conn->sent_data) { ms = conn->timeout; FD_ZERO(&write_mask); FD_SET(fd, &write_mask); if (ms <= 0) { timeout.tv_sec = 30; timeout.tv_usec = 0; } else { timeout.tv_sec = ms / 1000; timeout.tv_usec = ms % 1000 * 1000; } result = select(fd + 1, 0, &write_mask, 0, &timeout); if (result > 0) { } else if (result == 0) { conn->ops->close(conn); return TIMEOUT_EXN; } else if (errno == EINTR || errno == EAGAIN) continue; else return exception_status(conn, errno); } conn->sent_data = 1; result = send(fd, buf, len, 0); if (result >= 0) return result; else if (errno == EINTR || errno == EAGAIN) { continue; } else { return exception_status(conn, errno); } } return TIMEOUT_EXN;}intconn_close(connection_t *conn){ int fd; if (! conn) return -1; fd = conn->fd; conn->fd = -1; if (fd > 0) closesocket(fd); return 1;}voidstd_free(connection_t *conn){ server_socket_t *ss; if (! conn) return; ss = conn->ss; pthread_mutex_lock(&ss->ssl_lock); conn->next = ss->free_head; ss->free_head = conn; pthread_mutex_unlock(&ss->ssl_lock);}connection_t *std_accept(server_socket_t *ss){ int fd; int sock = -1; struct sockaddr_in sin; int len; connection_t *conn; fd_set read_mask; struct timeval timeout; int tcp_no_delay = 1; if (! ss) return 0; fd = ss->fd; if (fd < 0) return 0; FD_ZERO(&read_mask); FD_SET(fd, &read_mask); timeout.tv_sec = 5; timeout.tv_usec = 0; if (select(fd + 1, &read_mask, 0, 0, &timeout) <= 0) return 0; len = sizeof(sin); memset(&sin, 0, sizeof(sin)); sock = accept(fd, (struct sockaddr *) &sin, &len); if (sock < 0) return 0; { int flag = 1; if (tcp_no_delay) setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)); } pthread_mutex_lock(&ss->ssl_lock); conn = ss->free_head; if (conn) ss->free_head = conn->next; pthread_mutex_unlock(&ss->ssl_lock); if (! conn) { conn = cse_malloc(sizeof(connection_t)); if (! conn) { closesocket(sock); return 0; } memset(conn, 0, sizeof(connection_t)); conn->ss = ss; conn->timeout = ss->request_timeout; conn->ssl_lock = &ss->ssl_lock; } conn->fd = sock; conn->ops = &std_ops; conn->client_sin = sin; conn->is_init = 0; len = sizeof(conn->client_sin); getsockname(sock, (struct sockaddr *) &conn->server_sin, &len); return conn;}static intstd_read_client_certificate(connection_t *conn, char *buffer, int length){ return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -