📄 pipe-socket.c
字号:
/* * 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 + -