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

📄 pipe-socket.c

📁 Serveez是一个服务器框架
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * pipe-socket.c - pipes in socket structures * * Copyright (C) 2000, 2001 Stefan Jahn <stefan@lkcc.org> * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. *  * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this package; see the file COPYING.  If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA.   * * $Id: pipe-socket.c,v 1.21 2001/09/17 21:58:53 ela Exp $ * */#if HAVE_CONFIG_H# include <config.h>#endif#define _GNU_SOURCE#include <stdio.h>#include <string.h>#include <errno.h>#include <sys/types.h>#if HAVE_UNISTD_H# include <unistd.h>#endif#include <fcntl.h>#include <sys/stat.h>#include <time.h>#if HAVE_PWD_H# include <pwd.h>#endif#if HAVE_GRP_H# include <grp.h>#endif#ifdef __MINGW32__# include <winsock2.h>#endif#include "libserveez/alloc.h"#include "libserveez/util.h"#include "libserveez/socket.h"#include "libserveez/core.h"#include "libserveez/server-core.h"#include "libserveez/pipe-socket.h"#ifdef __MINGW32__/* Some static data for the CancelIo() call. We need to load the symbol   dynamically because it is not available on all versions of Windows. */typedef BOOL (__stdcall * CancelIoProc) (HANDLE);static CancelIoProc CancelIoFunc = NULL;static HANDLE Kernel32Handle = NULL;#endif /* __MINGW32__ *//* * Startup the pipe interface of the core API of serveez. Returns zero on * success. Gets called from @code{svz_boot()} once. Do not use. */intsvz_pipe_startup (void){#ifdef __MINGW32__  if ((Kernel32Handle = LoadLibrary ("KERNEL32.DLL")) == NULL)    {      svz_log (LOG_ERROR, "pipe: LoadLibrary: %s\n", SYS_ERROR);      return -1;    }  /* obtain CancelIo() function */  CancelIoFunc = (CancelIoProc) GetProcAddress (Kernel32Handle, "CancelIo");  if (CancelIoFunc == NULL)    {      svz_log (LOG_ERROR, "pipe: GetProcAddress: %s\n", SYS_ERROR);      FreeLibrary (Kernel32Handle);      Kernel32Handle = NULL;      return -1;    }#endif /* __MINGW32__ */  return 0;}/* * Cleanup the pipe interface of the core API of serveez. Returns zero on * success. Gets called from @code{svz_halt()} once. Do not use. */intsvz_pipe_cleanup (void){#ifdef __MINGW32__  if (Kernel32Handle != NULL)    {      FreeLibrary (Kernel32Handle);      Kernel32Handle = NULL;      CancelIoFunc = NULL;    }#endif /* __MINGW32__ */  return 0;}/* * Return a newly allocated and setup to some defaults pipe structure. */svz_pipe_t *svz_pipe_alloc (void){  svz_pipe_t *pipe;  pipe = svz_calloc (sizeof (svz_pipe_t));  pipe->uid = pipe->gid = pipe->perm = (unsigned int) -1;  return pipe;}/* * Destroy the given pipe structure @var{pipe}. */voidsvz_pipe_destroy (svz_pipe_t *pipe){  svz_free (pipe->name);  svz_free (pipe->user);  svz_free (pipe->group);  svz_free (pipe);}/*  * Check the consistency of the "user" - "user id" pair in the given pipe * structure @var{pipe}. Return zero if it is ok. */intsvz_pipe_check_user (svz_pipe_t *pipe){#if HAVE_PWD_H  struct passwd *p = NULL;  if (pipe->user)    {      if ((p = getpwnam (pipe->user)) == NULL)	{	  svz_log (LOG_WARNING, "%s: no such user `%s'\n", 		   pipe->name, pipe->user);	  return 0;	}      pipe->uid = p->pw_uid;      pipe->pgid = p->pw_gid;    }  else if (pipe->uid != (unsigned int) -1)    {      if ((p = getpwuid (pipe->uid)) == NULL)	{	  svz_log (LOG_WARNING, "%s: no such user id `%d'\n", 		   pipe->name, pipe->uid);	  return 0;	}      pipe->user = svz_strdup (p->pw_name);      pipe->pgid = p->pw_gid;    }#endif /* not HAVE_PWD_H */  return 0;}/* * Check the consistency of the "group" - "group id" pair in the structure * @var{pipe}. Return zero if it is valid. */intsvz_pipe_check_group (svz_pipe_t *pipe){#if HAVE_GRP_H  struct group *g = NULL;  int n = 0;  if (pipe->group)    {      if ((g = getgrnam (pipe->group)) == NULL)	{	  svz_log (LOG_WARNING, "%s: no such group `%s'\n", 		   pipe->name, pipe->group);	  return 0;	}      pipe->gid = g->gr_gid;    }  else if (pipe->gid != (unsigned int) -1)    {      if ((g = getgrgid (pipe->gid)) == NULL)	{	  svz_log (LOG_WARNING, "%s: no such group id `%d'\n", 		   pipe->name, pipe->gid);	  return 0;	}      pipe->group = svz_strdup (g->gr_name);    }  /* Check if the user is in the selected group and croak about it     if not. This check is only done if all necessary info is given. */  if (g && g->gr_mem && pipe->user)    {      while (g->gr_mem[n])	{	  if (!strcmp (g->gr_mem[n], pipe->user))	    {	      n = -1;	      break;	    }	  n++;	}      if (n != -1 && pipe->gid != pipe->pgid)	{	  svz_log (LOG_WARNING, "%s: user `%s' is not in group `%s'\n",		   pipe->name, pipe->user, pipe->group);	  return 0;	}    }#endif /* HAVE_GRP_H */  return 0;}/* * This function is for checking if a given socket structure contains  * a valid pipe socket (checking both pipes). Return non-zero on errors. */intsvz_pipe_valid (svz_socket_t *sock){  if (sock->flags & SOCK_FLAG_LISTENING)    return 0;  if (!(sock->flags & SOCK_FLAG_CONNECTED))    return -1;  if (sock->flags & SOCK_FLAG_RECV_PIPE)    if (sock->pipe_desc[READ] == INVALID_HANDLE)      return -1;  if (sock->flags & SOCK_FLAG_SEND_PIPE)    if (sock->pipe_desc[WRITE] == INVALID_HANDLE)      return -1;  return 0;}/* * This function is the default disconnection routine for pipe socket * structures. Return non-zero on errors. */intsvz_pipe_disconnect (svz_socket_t *sock){  svz_socket_t *rsock;  if (sock->flags & SOCK_FLAG_CONNECTED)    {      /* has this socket created by a listener ? */      if ((rsock = svz_sock_getreferrer (sock)) != NULL)	{#ifdef __MINGW32__	  /* cancel any pending I/O if necessary and possible */	  if (CancelIoFunc)	    {	      if (sock->flags & (SOCK_FLAG_READING | SOCK_FLAG_CONNECTING))		if (!CancelIoFunc (sock->pipe_desc[READ]))		  svz_log (LOG_ERROR, "CancelIo: %s\n", SYS_ERROR);	      if (sock->flags & (SOCK_FLAG_WRITING | SOCK_FLAG_CONNECTING))		if (!CancelIoFunc (sock->pipe_desc[WRITE]))		  svz_log (LOG_ERROR, "CancelIo: %s\n", SYS_ERROR);	    }	  /* just disconnect client pipes */	  if (!DisconnectNamedPipe (sock->pipe_desc[READ]))	    svz_log (LOG_ERROR, "DisconnectNamedPipe: %s\n", SYS_ERROR);	  if (!DisconnectNamedPipe (sock->pipe_desc[WRITE]))	    svz_log (LOG_ERROR, "DisconnectNamedPipe: %s\n", SYS_ERROR);	  /* reinitialize the overlapped structure of the listener */	  if (svz_os_version >= WinNT4x)	    {	      memset (sock->overlap[READ], 0, sizeof (OVERLAPPED));	      memset (sock->overlap[WRITE], 0, sizeof (OVERLAPPED));	      sock->overlap[READ] = NULL;	      sock->overlap[WRITE] = NULL;	    }#else /* not __MINGW32__ */	  /* close sending pipe only */	  if (sock->pipe_desc[WRITE] != INVALID_HANDLE)	    if (closehandle (sock->pipe_desc[WRITE]) < 0)	      svz_log (LOG_ERROR, "close: %s\n", SYS_ERROR);	  /* FIXME: reset receiving pipe ??? */#endif /* not __MINGW32__ */	  /* restart listening pipe server socket */	  rsock->flags &= ~SOCK_FLAG_INITED;	  svz_sock_setreferrer (rsock, NULL);	}      /* no, it is a connected pipe */      else	{	  /* close both pipes */	  if (sock->pipe_desc[READ] != INVALID_HANDLE)	    if (closehandle (sock->pipe_desc[READ]) < 0)	      svz_log (LOG_ERROR, "pipe: close: %s\n", SYS_ERROR);	  if (sock->pipe_desc[WRITE] != INVALID_HANDLE)	    if (closehandle (sock->pipe_desc[WRITE]) < 0)	      svz_log (LOG_ERROR, "pipe: close: %s\n", SYS_ERROR);	}#if ENABLE_DEBUG      svz_log (LOG_DEBUG, "pipe (%d-%d) disconnected\n",	       sock->pipe_desc[READ], sock->pipe_desc[WRITE]);#endif      sock->pipe_desc[READ] = INVALID_HANDLE;      sock->pipe_desc[WRITE] = INVALID_HANDLE;    }    /* prevent a pipe server's child to reinit the pipe server */  if (sock->flags & SOCK_FLAG_LISTENING)    {      if ((rsock = svz_sock_getreferrer (sock)) != NULL)	{#ifdef __MINGW32__	  rsock->overlap[READ] = NULL;	  rsock->overlap[WRITE] = NULL;#endif /* __MINGW32__ */	  svz_sock_setreferrer (rsock, NULL);	}#ifndef __MINGW32__      /* close listening pipe */      if (sock->pipe_desc[READ] != INVALID_HANDLE)	if (closehandle (sock->pipe_desc[READ]) < 0)	  svz_log (LOG_ERROR, "close: %s\n", SYS_ERROR);      /* delete named pipes on file system */      if (unlink (sock->recv_pipe) == -1)	svz_log (LOG_ERROR, "unlink: %s\n", SYS_ERROR);      if (unlink (sock->send_pipe) == -1)	svz_log (LOG_ERROR, "unlink: %s\n", SYS_ERROR);#else /* __MINGW32__ */      /* disconnect and close named pipes */      if (sock->pipe_desc[READ] != INVALID_HANDLE)	{	  if (!DisconnectNamedPipe (sock->pipe_desc[READ]))	    svz_log (LOG_ERROR, "DisconnectNamedPipe: %s\n", SYS_ERROR);	  if (!CloseHandle (sock->pipe_desc[READ]))	    svz_log (LOG_ERROR, "CloseHandle: %s\n", SYS_ERROR);	}      if (sock->pipe_desc[WRITE] != INVALID_HANDLE)	{	  if (!DisconnectNamedPipe (sock->pipe_desc[WRITE]))	    svz_log (LOG_ERROR, "DisconnectNamedPipe: %s\n", SYS_ERROR);	  if (!CloseHandle (sock->pipe_desc[WRITE]))	    svz_log (LOG_ERROR, "CloseHandle: %s\n", SYS_ERROR);	}#endif /* __MINGW32__ */#if ENABLE_DEBUG      svz_log (LOG_DEBUG, "pipe listener (%s) destroyed\n", sock->recv_pipe);#endif      sock->pipe_desc[READ] = INVALID_HANDLE;      sock->pipe_desc[WRITE] = INVALID_HANDLE;    }  return 0;}

⌨️ 快捷键说明

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