📄 pipe-socket.c
字号:
* zero on success and non-zero on errors. */static intsvz_pipe_try_state (svz_pipe_t *pipe){ /* umask value */ if (pipe->perm != (unsigned int) -1) umask (~pipe->perm); /* group id (need to change group first !) */ if (pipe->gid != (unsigned int) -1) if (SETGID (pipe->gid) < 0) { svz_log (LOG_ERROR, "pipe: " SETGID_FUNC " (%d): %s\n", pipe->gid, SYS_ERROR); return -1; } /* user id */ if (pipe->uid != (unsigned int) -1) if (SETUID (pipe->uid) < 0) { svz_log (LOG_ERROR, "pipe: " SETUID_FUNC " (%d): %s\n", pipe->uid, SYS_ERROR); return -1; } return 0;}#endif /* not __MINGW32__ *//* * Set the file names of the socket structure @var{sock} to @var{recv} for * the receiving end and @var{send} for the sending end of a pipe socket. */static voidsvz_pipe_set_files (svz_socket_t *sock, char *recv, char *send){ if (sock->recv_pipe) svz_free (sock->recv_pipe); if (sock->send_pipe) svz_free (sock->send_pipe);#ifndef __MINGW32__ sock->recv_pipe = svz_strdup (recv); sock->send_pipe = svz_strdup (send);#else /* __MINGW32__ */ if (strstr (recv, "\\pipe\\") == NULL) { sock->recv_pipe = svz_malloc (strlen (recv) + 10); sprintf (sock->recv_pipe, "\\\\.\\pipe\\%s", recv); } else sock->recv_pipe = svz_strdup (recv); if (strstr (send, "\\pipe\\") == NULL) { sock->send_pipe = svz_malloc (strlen (send) + 10); sprintf (sock->send_pipe, "\\\\.\\pipe\\%s", send); } else sock->send_pipe = svz_strdup (send);#endif /* __MINGW32__ */}/* * This routine creates a pipe connection socket structure to a pair of * named pipes. Return @code{NULL} on errors. */svz_socket_t *svz_pipe_connect (svz_pipe_t *recv, svz_pipe_t *send){ svz_socket_t *sock; HANDLE recv_pipe, send_pipe;#ifndef __MINGW32__ unsigned int mask, uid, gid; struct stat buf;#endif /* create socket structure */ if ((sock = svz_sock_alloc ()) == NULL) return NULL; /* create pipe file text representation */ svz_pipe_set_files (sock, recv->name, send->name);#ifndef __MINGW32__ /* is receive pipe such a ? */ if (stat (sock->recv_pipe, &buf) == -1 || !S_ISFIFO (buf.st_mode)) { svz_log (LOG_ERROR, "pipe: no such pipe: %s\n", sock->recv_pipe); svz_sock_free (sock); return NULL; } /* is send pipe such a ? */ if (stat (sock->send_pipe, &buf) == -1 || !S_ISFIFO (buf.st_mode)) { svz_log (LOG_ERROR, "pipe: no such pipe: %s\n", sock->send_pipe); svz_sock_free (sock); return NULL; } /* save the current process's permission state and set the new state for the receive pipe if necessary and possible */ svz_pipe_save_state (&mask, &uid, &gid); if (svz_pipe_try_state (recv) < 0) { svz_pipe_set_state (mask, uid, gid); svz_sock_free (sock); return NULL; } /* try opening receiving pipe for reading */ if ((recv_pipe = open (sock->recv_pipe, O_RDONLY | O_NONBLOCK)) == -1) { svz_log (LOG_ERROR, "pipe: open: %s\n", SYS_ERROR); svz_sock_free (sock); svz_pipe_set_state (mask, uid, gid); return NULL; } /* restore the current process's permission state */ svz_pipe_set_state (mask, uid, gid); /* save the current process's permission state and set the new state for the send pipe if necessary and possible */ svz_pipe_save_state (&mask, &uid, &gid); if (svz_pipe_try_state (send) < 0) { close (recv_pipe); svz_pipe_set_state (mask, uid, gid); svz_sock_free (sock); return NULL; } /* try opening sending pipe for writing */ if ((send_pipe = open (sock->send_pipe, O_WRONLY | O_NONBLOCK)) == -1) { svz_log (LOG_ERROR, "pipe: open: %s\n", SYS_ERROR); close (recv_pipe); svz_sock_free (sock); svz_pipe_set_state (mask, uid, gid); return NULL; } /* restore the current process's permission state */ svz_pipe_set_state (mask, uid, gid); /* set send pipe to non-blocking mode and do not inherit the created pipe descriptors */ if (svz_fd_nonblock (send_pipe) != 0 || svz_fd_cloexec (send_pipe) != 0 || svz_fd_cloexec (recv_pipe) != 0) { close (recv_pipe); close (send_pipe); svz_sock_free (sock); return NULL; }#else /* __MINGW32__ */ /* try opening receiving pipe */ if ((recv_pipe = CreateFile (sock->recv_pipe, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL)) == INVALID_HANDLE_VALUE) { svz_log (LOG_ERROR, "pipe: CreateFile: %s\n", SYS_ERROR); svz_sock_free (sock); return NULL; } /* try opening sending pipe */ if ((send_pipe = CreateFile (sock->send_pipe, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL)) == INVALID_HANDLE_VALUE) { svz_log (LOG_ERROR, "pipe: CreateFile: %s\n", SYS_ERROR); DisconnectNamedPipe (recv_pipe); CloseHandle (recv_pipe); svz_sock_free (sock); return NULL; } /* initialize the overlap structure on WinNT systems */ if (svz_os_version >= WinNT4x) { sock->overlap[READ] = svz_malloc (sizeof (OVERLAPPED)); memset (sock->overlap[READ], 0, sizeof (OVERLAPPED)); sock->overlap[WRITE] = svz_malloc (sizeof (OVERLAPPED)); memset (sock->overlap[WRITE], 0, sizeof (OVERLAPPED)); }#endif /* __MINGW32__ */ /* modify socket structure and assign some callbacks */ svz_sock_unique_id (sock); sock->pipe_desc[READ] = recv_pipe; sock->pipe_desc[WRITE] = send_pipe; sock->flags |= (SOCK_FLAG_PIPE | SOCK_FLAG_CONNECTED); svz_sock_enqueue (sock); sock->read_socket = svz_pipe_read_socket; sock->write_socket = svz_pipe_write_socket; svz_sock_connections++; return sock;}#if HAVE_MKFIFO# define MKFIFO(path, mode) mkfifo (path, mode)# define MKFIFO_FUNC "mkfifo"#else# define MKFIFO(path, mode) mknod (path, mode | S_IFIFO, 0)# define MKFIFO_FUNC "mknod"#endif/* * Prepare the server socket structure @var{sock} for listening * on the receiving pipe of @var{recv}. Open the reading end of such a * connection. Return either zero or non-zero on errors. */intsvz_pipe_listener (svz_socket_t *sock, svz_pipe_t *recv, svz_pipe_t *send){#if defined (HAVE_MKFIFO) || defined (HAVE_MKNOD) struct stat buf; unsigned int mask, uid, gid;#endif#if defined (HAVE_MKFIFO) || defined (HAVE_MKNOD) || defined (__MINGW32__)#ifdef __MINGW32__ HANDLE send_pipe;#endif HANDLE recv_pipe; /* Setup the text representation of the fifo names. */ svz_pipe_set_files (sock, recv->name, send->name); /* Pipe requested via port configuration ? */ if (!sock->recv_pipe || !sock->send_pipe) return -1;#endif#if defined (HAVE_MKFIFO) || defined (HAVE_MKNOD) /* Test if both of the named pipes have been created yet. If not then create them locally. */ if (stat (sock->recv_pipe, &buf) == -1) { /* Save old permissions and set new ones. */ svz_pipe_save_state (&mask, &uid, &gid); if (svz_pipe_try_state (recv) < 0) { svz_pipe_set_state (mask, uid, gid); return -1; } /* Create fifo locally. */ if (MKFIFO (sock->recv_pipe, 0666) != 0) { svz_log (LOG_ERROR, "pipe: " MKFIFO_FUNC ": %s\n", SYS_ERROR); svz_pipe_set_state (mask, uid, gid); return -1; } /* Check if that was successful. */ if (stat (sock->recv_pipe, &buf) == -1 || !S_ISFIFO (buf.st_mode)) { svz_log (LOG_ERROR, "pipe: stat: " MKFIFO_FUNC "() did not create a fifo\n"); svz_pipe_set_state (mask, uid, gid); return -1; } /* Restore old permissions. */ svz_pipe_set_state (mask, uid, gid); } if (stat (sock->send_pipe, &buf) == -1) { svz_pipe_save_state (&mask, &uid, &gid); if (svz_pipe_try_state (send) < 0) { svz_pipe_set_state (mask, uid, gid); return -1; } if (MKFIFO (sock->send_pipe, 0666) != 0) { svz_log (LOG_ERROR, "pipe: " MKFIFO_FUNC ": %s\n", SYS_ERROR); svz_pipe_set_state (mask, uid, gid); return -1; } if (stat (sock->send_pipe, &buf) == -1 || !S_ISFIFO (buf.st_mode)) { svz_log (LOG_ERROR, "pipe: stat: " MKFIFO_FUNC "() did not create a fifo\n"); svz_pipe_set_state (mask, uid, gid); return -1; } svz_pipe_set_state (mask, uid, gid); } /* Try opening the server's read pipe. Should always be possible. */ if ((recv_pipe = open (sock->recv_pipe, O_NONBLOCK | O_RDONLY)) == -1) { svz_log (LOG_ERROR, "pipe: open: %s\n", SYS_ERROR); return -1; } /* Check if the file descriptor is a pipe. */ if (fstat (recv_pipe, &buf) == -1 || !S_ISFIFO (buf.st_mode)) { svz_log (LOG_ERROR, "pipe: fstat: " MKFIFO_FUNC "() did not create a fifo\n"); close (recv_pipe); return -1; } /* Do not inherit this pipe. */ svz_fd_cloexec (recv_pipe); sock->pipe_desc[READ] = recv_pipe; sock->flags |= SOCK_FLAG_RECV_PIPE;#elif defined (__MINGW32__) /* not (HAVE_MKFIFO || HAVE_MKNOD) */ /* * Create both of the named pipes and put the handles into * the server socket structure. */ recv_pipe = CreateNamedPipe ( sock->recv_pipe, /* path */ PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, /* receive + overlapped */ PIPE_READMODE_BYTE | PIPE_WAIT, /* binary + blocking */ 1, /* one instance only */ 0, 0, /* default buffer sizes */ 100, /* timeout in ms */ NULL); /* no security */ if (recv_pipe == INVALID_HANDLE_VALUE || !recv_pipe) { svz_log (LOG_ERROR, "pipe: CreateNamedPipe: %s\n", SYS_ERROR); return -1; } sock->pipe_desc[READ] = recv_pipe; sock->flags |= SOCK_FLAG_RECV_PIPE; send_pipe = CreateNamedPipe ( sock->send_pipe, /* path */ PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED, /* send + overlapped */ PIPE_TYPE_BYTE | PIPE_WAIT, /* binary + blocking */ 1, /* one instance only */ 0, 0, /* default buffer sizes */ 100, /* timeout in ms */ NULL); /* no security */ if (send_pipe == INVALID_HANDLE_VALUE || !send_pipe) { svz_log (LOG_ERROR, "pipe: CreateNamedPipe: %s\n", SYS_ERROR); return -1; } sock->pipe_desc[WRITE] = send_pipe; sock->flags |= SOCK_FLAG_SEND_PIPE; /* * Initialize the overlapped structures for this server socket. Each * client connected gets it passed. */ if (svz_os_version >= WinNT4x) { sock->overlap[READ] = svz_malloc (sizeof (OVERLAPPED)); memset (sock->overlap[READ], 0, sizeof (OVERLAPPED)); sock->overlap[WRITE] = svz_malloc (sizeof (OVERLAPPED)); memset (sock->overlap[WRITE], 0, sizeof (OVERLAPPED)); }#else /* not __MINGW32__ */ return -1;#endif /* neither HAVE_MKFIFO nor __MINGW32__ */#if defined (HAVE_MKFIFO) || defined (HAVE_MKNOD) || defined (__MINGW32__) return 0;#endif /* HAVE_MKFIFO or __MINGW32__ */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -