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

📄 pipe.c

📁 具有IDE功能的编辑器
💻 C
字号:
/* pipe.c - for opening a process as a pipe and reading both stderr and stdout together   Copyright (C) 1996-2000 Paul Sheer   This program 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 of the License, or   (at your option) any later version.   This program 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 program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA   02111-1307, USA. */#include <config.h>#include "global.h"#include "pipe-headers.h"#include <my_string.h>#include "pool.h"#include "mad.h"#ifndef _PATH_DEV#define _PATH_DEV "/dev/"#endif#define _PATH_DEV_PTYXX _PATH_DEV "ptyXX"int data_read_ready (int f);int data_read_wait (int f);int data_write_ready (int f);int data_write_wait (int f);pid_t triple_pipe_open (int *in, int *out, int *err, int mix, const char *file, char *const argv[]);char *read_pipe (int fd, int *len);#undef min#define min(x,y)     (((x) < (y)) ? (x) : (y))void set_signal_handlers_to_default (void){    signal (SIGHUP, SIG_DFL);    signal (SIGQUIT, SIG_DFL);    signal (SIGINT, SIG_DFL);    signal (SIGTERM, SIG_DFL);    signal (SIGABRT, SIG_DFL);    signal (SIGCHLD, SIG_DFL);    signal (SIGALRM, SIG_IGN);}/*   This opens a process as a pipe. 'in', 'out' and 'err' are pointers to file handles   which are filled in by popen. 'in' refers to stdin of the process, to   which you can write. 'out' and 'err' refer to stdout and stderr of the process   from which you can read. 'in', 'out' and 'err' can be passed   as NULL if you want to ignore output or input of those pipes.   If 'mix' is non-zero, then both stderr and stdout of the process   can be read from 'out'. If mix is non-zero, then 'err' must be passed as NULL.   Popen forks and then calls execvp (see execvp(3)) --- which must also take argv[0]   and args must terminate with a NULL.   Returns -1 if the fork failed, and -2 if pipe() failed.   Otherwise returns the pid of the child. */pid_t triple_pipe_open (int *in, int *out, int *err, int mix, const char *file, char *const argv[]){    pid_t p;    int e;    int f0[2], f1[2], f2[2];    e = (pipe (f0) | pipe (f1) | pipe (f2));    if (e) {	close (f0[0]);	close (f0[1]);	close (f1[0]);	close (f1[1]);	close (f2[0]);	close (f2[1]);	return -2;    }    p = fork ();    if (p == -1) {	close (f0[0]);	close (f0[1]);	close (f1[0]);	close (f1[1]);	close (f2[0]);	close (f2[1]);	return -1;    }    if (p) {	if (in) {	    *in = f0[1];	} else {	    close (f0[1]);	}	if (out) {	    *out = f1[0];	} else {	    close (f1[0]);	}	if (err) {	    *err = f2[0];	} else {	    close (f2[0]);	}	close (f0[0]);	close (f1[1]);	close (f2[1]);	return p;    } else {	int nulldevice_wr, nulldevice_rd;	nulldevice_wr = open ("/dev/null", O_WRONLY);	nulldevice_rd = open ("/dev/null", O_RDONLY);	close (0);	if (in)	    dup (f0[0]);	else	    dup (nulldevice_rd);	close (1);	if (out)	    dup (f1[1]);	else	    dup (nulldevice_wr);	close (2);	if (err)	    dup (f2[1]);	else {	    if (mix)		dup (f1[1]);	    else		dup (nulldevice_wr);	}	close (f0[0]);	close (f0[1]);	close (f1[0]);	close (f1[1]);	close (f2[0]);	close (f2[1]);	close (nulldevice_rd);	close (nulldevice_wr);	set_signal_handlers_to_default ();	execvp (file, argv);	exit (1);    }    return 0; /* prevents warning */}#if 0#ifndef HAVE_FORKPTY/* This is stolen from libc-5.4.46 with the intention of having   this all still work on systems that do not have the forkpty()   function (like non-BSD systems like solaris). No idea if it will   actually work on these systems. */static int my_openpty (int *amaster, int *aslave, char *name){    char line[] = _PATH_DEV_PTYXX;    const char *p, *q;    int master, slave, ttygid;    struct group *gr;    if ((gr = getgrnam ("tty")) != NULL)	ttygid = gr->gr_gid;    else	ttygid = -1;    for (p = "pqrstuvwxyzabcde"; *p; p++) {	line[sizeof (_PATH_DEV_PTYXX) - 3] = *p;	for (q = "0123456789abcdef"; *q; q++) {	    line[sizeof (_PATH_DEV_PTYXX) - 2] = *q;	    if ((master = open (line, O_RDWR, 0)) == -1) {		if (errno == ENOENT)		    return -1;	    } else {		line[sizeof (_PATH_DEV) - 1] = 't';		chown (line, getuid (), ttygid);		chmod (line, S_IRUSR | S_IWUSR | S_IWGRP);		if ((slave = open (line, O_RDWR, 0)) != -1) {		    *amaster = master;		    *aslave = slave;		    strcpy (name, line);		    return 0;		}		close (master);		line[sizeof (_PATH_DEV) - 1] = 'p';	    }	}    }    errno = ENOENT;    return -1;}static int forkpty (int *amaster, char *name,...){    int master, slave;    pid_t pid;    if (my_openpty (&master, &slave, name) == -1)	return -1;    switch (pid = fork ()) {    case -1:	return -1;    case 0:	close (master);#ifdef HAVE_SETSID	pid = setsid ();#define HAVE_PID_THIS_TTY#elif defined (HAVE_SETPGRP)	pid = setpgrp (0, 0);#define HAVE_PID_THIS_TTY#endif#ifdef TIOCSCTTY	ioctl (slave, TIOCSCTTY, 0);#ifdef HAVE_PID_THIS_TTY#elif defined (HAVE_TCSETPGRP)	tcsetpgrp (slave, pid);#elif defined (TIOCSPGRP)	ioctl (slave, TIOCSPGRP, &pid);#endif#endif	close (0);	dup (slave);	close (1);	dup (slave);	close (2);	dup (slave);	if (slave > 2)	    close (slave);	return 0;    }    *amaster = master;    close (slave);    return pid;}#endif				/* ! HAVE_FORKPTY */static void set_termios (int fd){#ifdef HAVE_TCGETATTR    struct termios tios;    memset (&tios, 0, sizeof (tios));    if (tcgetattr (fd, &tios) != 0)	return;#ifdef B19200#ifdef OCRNL    tios.c_oflag &= ~(ONLCR | OCRNL);#else    tios.c_oflag &= ~ONLCR;#endif    tios.c_lflag &= ~(ECHO | ICANON | ISIG);    tios.c_iflag &= ~(ICRNL);#ifdef VTIME    tios.c_cc[VTIME] = 1;#endif#ifdef VMIN    tios.c_cc[VMIN] = 1;#endif    tios.c_iflag &= ~(ISTRIP);#if defined(TABDLY) && defined(TAB3)    if ((tios.c_oflag & TABDLY) == TAB3)	tios.c_oflag &= ~TAB3;#endif/* disable interpretation of ^S: */    tios.c_iflag &= ~IXON;#ifdef VDISCARD    tios.c_cc[VDISCARD] = 255;#endif#ifdef VEOL2    tios.c_cc[VEOL2] = 255;#endif#ifdef VEOL    tios.c_cc[VEOL] = 255;#endif#ifdef VLNEXT    tios.c_cc[VLNEXT] = 255;#endif#ifdef VREPRINT    tios.c_cc[VREPRINT] = 255;#endif#ifdef VSUSP    tios.c_cc[VSUSP] = 255;#endif#ifdef VWERASE    tios.c_cc[VWERASE] = 255;#endif    tcsetattr (fd, TCSADRAIN, &tios);#endif#endif				/* HAVE_TCGETATTR */}pid_t open_under_pty (int *in, int *out, char *line, const char *file, char *const argv[]){    int master = 0;    char l[80];    pid_t p;#ifdef HAVE_FORKPTY#ifdef NEED_WINSIZE    struct winsize {	unsigned short ws_row;	unsigned short ws_col;	unsigned short ws_xpixel;	unsigned short ws_ypixel;    } win;#else    struct winsize win;#endif    memset (&win, 0, sizeof (win));    p = (pid_t) forkpty (&master, l, NULL, &win);#else    p = (pid_t) forkpty (&master, l);#endif    if (p == -1)	return -1;#if 0    ioctl (master, FIONBIO, &yes);    ioctl (master, FIONBIO, &yes);#endif    strcpy (line, l);    if (p) {	*in = dup (master);	*out = dup (master);	close (master);	return p;    }    set_termios (0);    execvp (file, argv);    exit (1);    return 0;}#endif#define CHUNK 8192/*   Reads all available data and mallocs space for it plus   one byte, and sets that byte to zero. If len is non-NULL   bytes read is placed in len. If *len is passed non-zero then   reads that amount max. */char *read_pipe (int fd, int *len){    POOL *p;    int c, count = 0;    int l = CHUNK;    p = pool_init ();    if (len)	if (*len)	    if (l > *len)		l = *len;    for (;;) {	if (pool_freespace (p) < l + 1)	    pool_advance (p, l + 1);	do {	    c = read (fd, pool_current (p), l);	} while (c < 0 && errno == EINTR);	if (c <= 0)	    break;	count += c;	pool_current (p) += c;	if (len)	    if (*len)		if (pool_length (p) >= l)		    break;    }    pool_null (p);    if (len)	*len = pool_length (p);    return (char *) pool_break (p);}

⌨️ 快捷键说明

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