⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 std.c

📁 RESIN 3.2 最新源码
💻 C
字号:
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * @author Scott Ferguson */#include <sys/types.h>#ifdef WIN32#ifndef _WINSOCKAPI_ #define _WINSOCKAPI_#endif #include <windows.h>#include <winsock2.h>#else#include <sys/time.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/tcp.h>#include <netdb.h>#include <unistd.h>#ifdef POLL#include <sys/poll.h>#else#include <sys/select.h>#endif#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 "resin.h"static int std_read(connection_t *conn, char *buf, int len, int timeout);static int std_read_nonblock(connection_t *conn, char *buf, int len);static int std_write(connection_t *conn, char *buf, int len);static int std_write_nonblock(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_read,  std_read_nonblock,  std_write,  std_write_nonblock,  conn_close,  std_read_client_certificate,};static intwrite_exception_status(connection_t *conn, int error){  if (error == EAGAIN || error == EWOULDBLOCK || error == EINTR) {    if (conn->jni_env) {      resin_printf_exception(conn->jni_env, "com/caucho/vfs/ClientDisconnectException",			     "timeout fd=%d errno=%d\n", conn->fd, error);    }        return TIMEOUT_EXN;  }  else if (error == EPIPE || error == ECONNRESET) {    if (conn->jni_env) {      resin_printf_exception(conn->jni_env, "com/caucho/vfs/ClientDisconnectException",			     "Client disconnect fd=%d errno=%d\n",			     conn->fd, error);    }        return DISCONNECT_EXN;  }  else {    return -1;  }}static intread_exception_status(connection_t *conn, int error){  if (error == EAGAIN || error == EWOULDBLOCK || error == EINTR) {    return TIMEOUT_EXN;  }  else if (error == EPIPE || error == ECONNRESET) {    return -1;  }  else {    return -1;  }}static intstd_read_nonblock(connection_t *conn, char *buf, int len){  int fd;  int result;  if (! conn)    return -1;    fd = conn->fd;    if (fd < 0)    return -1;  result = recv(fd, buf, len, 0);  return result;}#ifdef POLLintpoll_read(int fd, int ms){  struct pollfd pollfd[1];  int result;    pollfd[0].fd = fd;  pollfd[0].events = POLLIN|POLLPRI;  pollfd[0].revents = 0;  result = poll(pollfd, 1, ms);  if (result > 0 && (pollfd[0].revents & (POLLIN|POLLPRI)) == 0)    return 1;  else    return result;}static intpoll_write(int fd, int ms){  struct pollfd pollfd[1];    pollfd[0].fd = fd;  pollfd[0].events = POLLOUT;  pollfd[0].revents = 0;  return poll(pollfd, 1, ms);}#else /* select */intpoll_read(int fd, int ms){  fd_set read_set;  struct timeval timeout;  int result;  FD_ZERO(&read_set);  FD_SET(fd, &read_set);  timeout.tv_sec = ms / 1000;  timeout.tv_usec = (ms % 1000) * 1000;  result = select(fd + 1, &read_set, 0, 0, &timeout);  return result;}static intpoll_write(int fd, int ms){  fd_set write_set;  struct timeval timeout;  FD_ZERO(&write_set);  FD_SET(fd, &write_set);  timeout.tv_sec = ms / 1000;  timeout.tv_usec = (ms % 1000) * 1000;  return select(fd + 1, 0, &write_set, 0, &timeout);}#endifstatic intstd_read(connection_t *conn, char *buf, int len, int timeout){  int fd;  int result;  int retry = 10;  if (! conn)    return -1;    fd = conn->fd;    if (fd < 0) {    return -1;  }  if (timeout > 0 && poll_read(fd, timeout) <= 0) {    return TIMEOUT_EXN;  }  do {#ifndef HAS_SOCK_TIMEOUT    if (timeout < 0 && poll_read(fd, conn->socket_timeout) <= 0) {      return TIMEOUT_EXN;    }#endif      result = recv(fd, buf, len, 0);  } while (result < 0 && (errno == EINTR || errno == EAGAIN) && retry-- >= 0);      if (result >= 0)    return result;  else {    return read_exception_status(conn, errno);  }}static intstd_write(connection_t *conn, char *buf, int len){  int fd;  int result;  int retry = 10;  int error;  if (! conn)    return -1;  fd = conn->fd;  if (fd < 0)    return -1;  conn->sent_data = 1;  #ifndef HAS_SOCK_TIMEOUT    if (poll_write(fd, conn->socket_timeout) == 0)      return -1;#endif  do {    result = send(fd, buf, len, 0);    if (result >= 0)      return result;    if (errno == EINTR || errno == EAGAIN) {      error = errno;      poll_write(fd, conn->socket_timeout);    }  } while (retry-- >= 0);  return write_exception_status(conn, error);}static intstd_write_nonblock(connection_t *conn, char *buf, int len){  int fd;  int result;  if (! conn)    return -1;  fd = conn->fd;  if (fd < 0)    return -1;#ifndef O_NONBLOCK  if (poll_write(fd, 0) <= 0)    return 0;#endif    result = send(fd, buf, len, 0);  return result;}intconn_close(connection_t *conn){  int fd;  if (! conn)    return -1;  fd = conn->fd;    conn->fd = -1;  if (fd >= 0) {    closesocket(fd);  }  return 1;}intstd_accept(server_socket_t *ss, connection_t *conn){  int fd;  int sock = -1;  char sin_data[256];  struct sockaddr *sin = (struct sockaddr *) sin_data;  unsigned int sin_len;  int tcp_no_delay = 1;  int poll_result;  struct timeval timeout;  int result;  if (! ss || ! conn)    return 0;    fd = ss->fd;  if (fd < 0)    return 0;  sin_len = sizeof(sin_data);  memset(sin, 0, sin_len);#ifdef WIN32  WaitForSingleObject(ss->accept_lock, INFINITE);  fd = ss->fd;  if (fd < 0) {    ReleaseMutex(ss->accept_lock);    return 0;  }#endif  /* pthread_mutex_lock(&ss->accept_lock); */    sock = -1;  /* XXX: no need to for the poll?  needs to match nonblock.  poll_result = poll_read(fd, 5000);  if (poll_result > 0)    sock = accept(fd, sin, &sin_len);  */  sock = accept(fd, sin, &sin_len);  #ifdef WIN32  ReleaseMutex(ss->accept_lock);#endif  /* pthread_mutex_unlock(&ss->accept_lock); */    if (sock < 0)    return 0;  if (tcp_no_delay) {    int flag = 1;    setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));  }#ifdef HAS_SOCK_TIMEOUT  timeout.tv_sec = ss->conn_socket_timeout / 1000;  timeout.tv_usec = ss->conn_socket_timeout % 1000 * 1000;  setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,	     (char *) &timeout, sizeof(timeout));  timeout.tv_sec = ss->conn_socket_timeout / 1000;  timeout.tv_usec = ss->conn_socket_timeout % 1000 * 1000;  setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO,	     (char *) &timeout, sizeof(timeout));#endif  conn->ss = ss;  conn->socket_timeout = ss->conn_socket_timeout;  conn->ssl_lock = &ss->ssl_lock;  conn->fd = sock;  conn->sock = 0;  conn->ops = &std_ops;  memcpy(conn->client_sin, sin, sizeof(conn->client_data));  conn->is_init = 0;  sin_len = sizeof(conn->server_data);  getsockname(sock, conn->server_sin, &sin_len);  conn->ssl_cipher = 0;  conn->ssl_bits = 0;  return 1;}voidstd_close_ss(server_socket_t *ss){  int fd;  char server_data[128];  struct sockaddr *server_sin = (struct sockaddr *) server_data;  unsigned int sin_len;  int result;   if (! ss)    return;    fd = ss->fd;  ss->fd = -1;  if (fd < 0)    return;  sin_len = sizeof(server_data);    if (! getsockname(fd, server_sin, &sin_len)) {    int retry;    /* probably should check for 0 socket name for local host*/    /* connect enough times to clear the threads waiting for a connection */    for (retry = 20; retry >= 0; retry--) {      int sock = socket(AF_INET, SOCK_STREAM, 0);      int result;      if (sock < 0)	break;      result = connect(sock, server_sin, sin_len);      closesocket(sock);      if (result < 0)	break;    }  }    result = closesocket(fd);}static intstd_read_client_certificate(connection_t *conn, char *buffer, int length){  return -1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -