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

📄 pipe-socket.c

📁 Serveez是一个服务器框架
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifdef __MINGW32__/* Print text representation of given overlapped I/O structure. */static voidsvz_pipe_overlap (LPOVERLAPPED overlap){  if (overlap)    {      printf ("Internal: %ld (0x%08lX), InternalHigh: %ld (0x%08lX)\n"	      "Offset: %ld (0x%08lX), OffsetHigh: %ld (0x%08lX)\n"	      "Event: %p\n",	      overlap->Internal, overlap->Internal, overlap->InternalHigh,	      overlap->InternalHigh, overlap->Offset, overlap->Offset,	      overlap->OffsetHigh, overlap->OffsetHigh, overlap->hEvent);    }}#endif /* __MINGW32__ *//* * The @code{svz_pipe_read_socket()} function reads as much data as  * available on a readable pipe descriptor or handle on Win32. Return  * a non-zero value on errors. */intsvz_pipe_read_socket (svz_socket_t *sock){  int num_read, do_read;  /* Read as much space is left in the receive buffer and return    * zero if there is no more space. */  do_read = sock->recv_buffer_size - sock->recv_buffer_fill;  if (do_read <= 0)     {      svz_log (LOG_ERROR, "receive buffer overflow on pipe %d\n", 	       sock->pipe_desc[READ]);      if (sock->kicked_socket)	sock->kicked_socket (sock, 0);      return -1;    }#ifdef __MINGW32__  /* Named pipes in Win32 cannot transfer more than 64KB at once. */  if (do_read > PIPE_MAX_READ)    do_read = PIPE_MAX_READ;  /* Use the PeekNamedPipe() call if there is no overlapped I/O in      order to make the following ReadFile() non-blocking. */  if (sock->overlap[READ] == NULL)    {      /* Check how many bytes could have been read from the pipe without	 really reading them. */      if (!PeekNamedPipe (sock->pipe_desc[READ], NULL, 0, 			  NULL, (DWORD *) &num_read, NULL))	{	  svz_log (LOG_ERROR, "pipe: PeekNamedPipe: %s\n", SYS_ERROR);	  return -1;	}      /* Leave this function if there is no data within the pipe. */      if (num_read <= 0)	return 0;      /* Adjust number of bytes to read. */      if (do_read > num_read)	do_read = num_read;    }  /* Try to get the result of the last ReadFile(). */  if (sock->flags & SOCK_FLAG_READING)    {      if (!GetOverlappedResult (sock->pipe_desc[READ], sock->overlap[READ],                                 (DWORD *) &num_read, FALSE))        {          if (GetLastError () != ERROR_IO_INCOMPLETE)            {              svz_log (LOG_ERROR, "pipe: GetOverlappedResult: %s\n", 		       SYS_ERROR);              return -1;            }	  return 0;        }      /* Schedule the pipe for the ReadFile() call again. */      else	{	  sock->recv_pending = 0;	  sock->flags &= ~SOCK_FLAG_READING;	}    }  /* Really read from the pipe. */  else if (!ReadFile (sock->pipe_desc[READ],		      sock->recv_buffer + sock->recv_buffer_fill,		      do_read, (DWORD *) &num_read, sock->overlap[READ]))    {      if (GetLastError () != ERROR_IO_PENDING)        {	  svz_log (LOG_ERROR, "pipe: ReadFile: %s\n", SYS_ERROR);	  return -1;        }      /* Schedule the pipe for the GetOverlappedResult() call. */      sock->recv_pending = do_read;      sock->flags |= SOCK_FLAG_READING;      return 0;    }#else /* not __MINGW32__ */  if ((num_read = read (sock->pipe_desc[READ],			sock->recv_buffer + sock->recv_buffer_fill,			do_read)) == -1)    {      svz_log (LOG_ERROR, "pipe: read: %s\n", SYS_ERROR);      if (errno == EAGAIN)	return 0;      return -1;    }#endif /* not __MINGW32__ */  /* Some data has been read from the pipe. */  if (num_read > 0)    {      sock->last_recv = time (NULL);#if ENABLE_FLOOD_PROTECTION      if (svz_sock_flood_protect (sock, num_read))	{	  svz_log (LOG_ERROR, "kicked pipe %d (flood)\n", 		   sock->pipe_desc[READ]);	  return -1;	}#endif /* ENABLE_FLOOD_PROTECTION */      sock->recv_buffer_fill += num_read;      if (sock->check_request)	if (sock->check_request (sock))	  return -1;    }#ifndef __MINGW32__  /* The pipe was selected but there is no data. */  else    {      svz_log (LOG_ERROR, "pipe: read: no data on pipe %d\n", 	       sock->pipe_desc[READ]);      return -1;    }#endif /* !__MINGW32__ */    return 0;}/* * This @code{svz_pipe_write_socket()} function writes as much data as  * possible into a writable pipe descriptor. It returns a non-zero value  * on errors. */intsvz_pipe_write_socket (svz_socket_t *sock){  int num_written, do_write;  /* Write as many bytes as possible, remember how many were actually      sent. */  do_write = sock->send_buffer_fill;#ifdef __MINGW32__  /* Named pipes in Win32 cannot transfer more than 64KB at once. */  if (do_write > PIPE_MAX_WRITE)    do_write = PIPE_MAX_WRITE;  /* Data bytes have been stored in system's cache. Now we are checking      if pending write operation has been completed. */  if (sock->flags & SOCK_FLAG_WRITING)    {      if (!GetOverlappedResult (sock->pipe_desc[WRITE], sock->overlap[WRITE], 				(DWORD *) &num_written, FALSE))	{	  if (GetLastError () != ERROR_IO_INCOMPLETE)	    {	      svz_log (LOG_ERROR, "pipe: GetOverlappedResult: %s\n", 		       SYS_ERROR);	      return -1;	    }	  return 0;	}      /* Reschedule the pipe descriptor for yet another WriteFile(). */      else	{	  sock->send_pending -= num_written;	  sock->flags &= ~SOCK_FLAG_WRITING;	  if (sock->send_pending != 0)	    {	      svz_log (LOG_ERROR, "pipe: %d pending send bytes left\n",		       sock->send_pending);	    }	}    }  /* Really write to the pipe. */  else if (!WriteFile (sock->pipe_desc[WRITE], sock->send_buffer, 		       do_write, (DWORD *) &num_written, sock->overlap[WRITE]))    {      if (GetLastError () != ERROR_IO_PENDING)	{	  svz_log (LOG_ERROR, "pipe: WriteFile: %s\n", SYS_ERROR);	  return -1;	}      sock->send_pending += do_write;      sock->flags |= SOCK_FLAG_WRITING;      return 0;    }#else /* not __MINGW32__ */  if ((num_written = write (sock->pipe_desc[WRITE], 			    sock->send_buffer, do_write)) == -1)    {      svz_log (LOG_ERROR, "pipe: write: %s\n", SYS_ERROR);      if (svz_errno == SOCK_UNAVAILABLE)	{	  sock->unavailable = time (NULL) + RELAX_FD_TIME;	  num_written = 0;	}    }#endif /* not __MINGW32__ */  /* Some data has been successfully written to the pipe. */  if (num_written > 0)    {      sock->last_send = time (NULL);      if (sock->send_buffer_fill > num_written)	{	  memmove (sock->send_buffer, 		   sock->send_buffer + num_written,		   sock->send_buffer_fill - num_written);	}      sock->send_buffer_fill -= num_written;    }  return (num_written < 0) ? -1 : 0;}/* * Create a socket structure containing both the pipe descriptors  * @var{recv_fd} and @var{send_fd}. Return @code{NULL} on errors. */svz_socket_t *svz_pipe_create (HANDLE recv_fd, HANDLE send_fd){  svz_socket_t *sock;#ifndef __MINGW32__  /* Try to set to non-blocking I/O. */  if (svz_fd_nonblock ((int) recv_fd) != 0)    return NULL;  if (svz_fd_nonblock ((int) send_fd) != 0)    return NULL;#endif /* __MINGW32__ */  /* Do not inherit these pipes */  if (svz_fd_cloexec ((int) recv_fd) != 0)    return NULL;  if (svz_fd_cloexec ((int) send_fd) != 0)    return NULL;  if ((sock = svz_sock_alloc ()) != NULL)    {      svz_sock_unique_id (sock);      sock->pipe_desc[READ] = recv_fd;      sock->pipe_desc[WRITE] = send_fd;      sock->flags |= (SOCK_FLAG_PIPE | SOCK_FLAG_CONNECTED);    }  return sock;}/* * Create a (non blocking) pair of pipes. This differs in Win32 and  * Unices. Return a non-zero value on errors. */intsvz_pipe_create_pair (HANDLE pipe_desc[2]){#ifdef __MINGW32__  SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), 			     NULL,    /* NULL security descriptor */			     TRUE };  /* Inherit handles */  if (!CreatePipe (&pipe_desc[READ], &pipe_desc[WRITE], &sa, 0))    {      svz_log (LOG_ERROR, "CreatePipe: %s\n", SYS_ERROR);      return -1;    }#else /* not __MINGW32__ */  if (pipe (pipe_desc) == -1)    {      svz_log (LOG_ERROR, "pipe: %s\n", SYS_ERROR);      return -1;    }  /*    * FIXME: Maybe cgi pipes MUST be blocking for *very* fast   *        outputs because thay cannot handle the EAGAIN error.   */  /* Make both ends of the pipe non-blocking. */  if (svz_fd_nonblock (pipe_desc[READ]) != 0)    return -1;  if (svz_fd_nonblock (pipe_desc[WRITE]) != 0)    return -1;#endif /* not __MINGW32__ */  return 0;}#ifndef __MINGW32__#if HAVE_SETEUID# define SETUID(id) seteuid (id)# define SETUID_FUNC "seteuid"#else# define SETUID(id) setuid (id)# define SETUID_FUNC "setuid"#endif#if HAVE_SETEGID# define SETGID(id) setegid (id)# define SETGID_FUNC "setegid"#else# define SETGID(id) setgid (id)# define SETGID_FUNC "setgid"#endif#if HAVE_GETEUID# define GETUID() geteuid ()#else# define GETUID() getuid ()#endif#if HAVE_GETEGID# define GETGID() getegid ()#else# define GETGID() getgid ()#endif/* * The following function saves the user and group permissions of the current * process. It stores the values for the umask, user id and group id in * @var{mask}, @var{uid} and @var{gid}. */static voidsvz_pipe_save_state (unsigned int *mask, unsigned int *uid, unsigned int *gid){  *mask = umask (0);  *uid = GETUID ();  *gid = GETGID ();}/* * This function sets the umask @var{mask}, the user id @var{uid} and the * group id @var{gid}. Returns zero on success, non-zero otherwise. */static intsvz_pipe_set_state (unsigned int mask, unsigned int uid, unsigned int gid){  umask (mask);  if (SETUID (uid) < 0)    {      svz_log (LOG_ERROR, "pipe: " SETUID_FUNC " (%d): %s\n", uid, SYS_ERROR);      return -1;    }  if (SETGID (gid) < 0)    {      svz_log (LOG_ERROR, "pipe: " SETGID_FUNC " (%d): %s\n", gid, SYS_ERROR);      return -1;    }  return 0;}/* * Modify the current permissions state as specified by @var{pipe}. Returns

⌨️ 快捷键说明

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