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

📄 io.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	int flag = 0;	struct stat buf;	extern double strtod();	flag = str2mode(mode);	if (do_unix)		goto strictopen;#ifdef VMS	if ((openfd = vms_devopen(name, flag)) >= 0)		return openfd;#endif /* VMS */	if (STREQ(name, "-"))		openfd = fileno(stdin);	else if (STREQN(name, "/dev/", 5) && stat(name, &buf) == -1) {		cp = name + 5;				if (STREQ(cp, "stdin") && (flag & O_RDONLY) == O_RDONLY)			openfd = fileno(stdin);		else if (STREQ(cp, "stdout") && (flag & O_WRONLY) == O_WRONLY)			openfd = fileno(stdout);		else if (STREQ(cp, "stderr") && (flag & O_WRONLY) == O_WRONLY)			openfd = fileno(stderr);		else if (STREQN(cp, "fd/", 3)) {			cp += 3;			openfd = (int)strtod(cp, &ptr);			if (openfd <= INVALID_HANDLE || ptr == cp)				openfd = INVALID_HANDLE;		}	}strictopen:	if (openfd == INVALID_HANDLE)		openfd = open(name, flag, 0666);	if (openfd != INVALID_HANDLE && fstat(openfd, &buf) > 0) 		if (S_ISDIR(buf.st_mode))			fatal("file `%s' is a directory", name);	return openfd;}/* spec_setup --- setup an IOBUF for a special internal file */voidspec_setup(iop, len, allocate)IOBUF *iop;int len;int allocate;{	char *cp;	if (allocate) {		emalloc(cp, char *, len+2, "spec_setup");		iop->buf = cp;	} else {		len = strlen(iop->buf);		iop->buf[len++] = '\n';	/* get_a_record clobbered it */		iop->buf[len] = '\0';	/* just in case */	}	iop->off = iop->buf;	iop->cnt = 0;	iop->secsiz = 0;	iop->size = len;	iop->end = iop->buf + len;	iop->fd = -1;	iop->flag = IOP_IS_INTERNAL;}/* specfdopen --- open a fd special file */intspecfdopen(iop, name, mode)IOBUF *iop;char *name, *mode;{	int fd;	IOBUF *tp;	fd = devopen(name, mode);	if (fd == INVALID_HANDLE)		return INVALID_HANDLE;	tp = iop_alloc(fd);	if (tp == NULL)		return INVALID_HANDLE;	*iop = *tp;	iop->flag |= IOP_NO_FREE;	free(tp);	return 0;}/* pidopen --- "open" /dev/pid, /dev/ppid, and /dev/pgrpid */intpidopen(iop, name, mode)IOBUF *iop;char *name, *mode;{	char tbuf[BUFSIZ];	int i;	if (name[6] == 'g')/* following #if will improve in 2.16 */#if defined(__svr4__) || defined(i860) || defined(_AIX) || defined(BSD4_4)		sprintf(tbuf, "%d\n", getpgrp());#else		sprintf(tbuf, "%d\n", getpgrp(getpid()));#endif	else if (name[6] == 'i')		sprintf(tbuf, "%d\n", getpid());	else		sprintf(tbuf, "%d\n", getppid());	i = strlen(tbuf);	spec_setup(iop, i, 1);	strcpy(iop->buf, tbuf);	return 0;}/* useropen --- "open" /dev/user *//* * /dev/user creates a record as follows: *	$1 = getuid() *	$2 = geteuid() *	$3 = getgid() *	$4 = getegid() * If multiple groups are supported, the $5 through $NF are the * supplementary group set. */intuseropen(iop, name, mode)IOBUF *iop;char *name, *mode;{	char tbuf[BUFSIZ], *cp;	int i;#if defined(NGROUPS_MAX) && NGROUPS_MAX > 0	int groupset[NGROUPS_MAX];	int ngroups;#endif	sprintf(tbuf, "%d %d %d %d", getuid(), geteuid(), getgid(), getegid());	cp = tbuf + strlen(tbuf);#if defined(NGROUPS_MAX) && NGROUPS_MAX > 0	ngroups = getgroups(NGROUPS_MAX, groupset);	if (ngroups == -1)		fatal("could not find groups: %s", strerror(errno));	for (i = 0; i < ngroups; i++) {		*cp++ = ' ';		sprintf(cp, "%d", groupset[i]);		cp += strlen(cp);	}#endif	*cp++ = '\n';	*cp++ = '\0';	i = strlen(tbuf);	spec_setup(iop, i, 1);	strcpy(iop->buf, tbuf);	return 0;}/* iop_open --- handle special and regular files for input */static IOBUF *iop_open(name, mode)char *name, *mode;{	int openfd = INVALID_HANDLE;	char *cp, *ptr;	int flag = 0;	int i;	struct stat buf;	IOBUF *iop;	static struct internal {		char *name;		int compare;		int (*fp)();		IOBUF iob;	} table[] = {		{ "/dev/fd/",		8,	specfdopen },		{ "/dev/stdin",		10,	specfdopen },		{ "/dev/stdout",	11,	specfdopen },		{ "/dev/stderr",	11,	specfdopen },		{ "/dev/pid",		8,	pidopen },		{ "/dev/ppid",		9,	pidopen },		{ "/dev/pgrpid",	11,	pidopen },		{ "/dev/user",		9,	useropen },	};	int devcount = sizeof(table) / sizeof(table[0]);	flag = str2mode(mode);	if (do_unix)		goto strictopen;	if (STREQ(name, "-"))		openfd = fileno(stdin);	else if (STREQN(name, "/dev/", 5) && stat(name, &buf) == -1) {		int i;		for (i = 0; i < devcount; i++) {			if (STREQN(name, table[i].name, table[i].compare)) {				IOBUF *iop = & table[i].iob;				if (iop->buf != NULL) {					spec_setup(iop, 0, 0);					return iop;				} else if ((*table[i].fp)(iop, name, mode) == 0)					return iop;				else {					warning("could not open %s, mode `%s'",						name, mode);					return NULL;				}			}		}	}strictopen:	if (openfd == INVALID_HANDLE)		openfd = open(name, flag, 0666);	if (openfd != INVALID_HANDLE && fstat(openfd, &buf) > 0) 		if ((buf.st_mode & S_IFMT) == S_IFDIR)			fatal("file `%s' is a directory", name);	iop = iop_alloc(openfd);	return iop;}#ifndef PIPES_SIMULATED	/* real pipes */static intwait_any(interesting)int interesting;	/* pid of interest, if any */{	SIGTYPE (*hstat)(), (*istat)(), (*qstat)();	int pid;	int status = 0;	struct redirect *redp;	extern int errno;	hstat = signal(SIGHUP, SIG_IGN);	istat = signal(SIGINT, SIG_IGN);	qstat = signal(SIGQUIT, SIG_IGN);	for (;;) {#ifdef NeXT		pid = wait((union wait *)&status);#else		pid = wait(&status);#endif /* NeXT */		if (interesting && pid == interesting) {			break;		} else if (pid != -1) {			for (redp = red_head; redp != NULL; redp = redp->next)				if (pid == redp->pid) {					redp->pid = -1;					redp->status = status;					if (redp->fp) {						pclose(redp->fp);						redp->fp = 0;					}					if (redp->iop) {						(void) iop_close(redp->iop);						redp->iop = 0;					}					break;				}		}		if (pid == -1 && errno == ECHILD)			break;	}	signal(SIGHUP, hstat);	signal(SIGINT, istat);	signal(SIGQUIT, qstat);	return(status);}static IOBUF *gawk_popen(cmd, rp)char *cmd;struct redirect *rp;{	int p[2];	register int pid;	/* used to wait for any children to synchronize input and output,	 * but this could cause gawk to hang when it is started in a pipeline	 * and thus has a child process feeding it input (shell dependant)	 */	/*(void) wait_any(0);*/	/* wait for outstanding processes */	if (pipe(p) < 0)		fatal("cannot open pipe \"%s\" (%s)", cmd, strerror(errno));	if ((pid = fork()) == 0) {		if (close(1) == -1)			fatal("close of stdout in child failed (%s)",				strerror(errno));		if (dup(p[1]) != 1)			fatal("dup of pipe failed (%s)", strerror(errno));		if (close(p[0]) == -1 || close(p[1]) == -1)			fatal("close of pipe failed (%s)", strerror(errno));		if (close(0) == -1)			fatal("close of stdin in child failed (%s)",				strerror(errno));		execl("/bin/sh", "sh", "-c", cmd, 0);		_exit(127);	}	if (pid == -1)		fatal("cannot fork for \"%s\" (%s)", cmd, strerror(errno));	rp->pid = pid;	if (close(p[1]) == -1)		fatal("close of pipe failed (%s)", strerror(errno));	return (rp->iop = iop_alloc(p[0]));}static intgawk_pclose(rp)struct redirect *rp;{	(void) iop_close(rp->iop);	rp->iop = NULL;	/* process previously found, return stored status */	if (rp->pid == -1)		return (rp->status >> 8) & 0xFF;	rp->status = wait_any(rp->pid);	rp->pid = -1;	return (rp->status >> 8) & 0xFF;}#else	/* PIPES_SIMULATED */	/* use temporary file rather than pipe */#ifdef VMSstatic IOBUF *gawk_popen(cmd, rp)char *cmd;struct redirect *rp;{	FILE *current;	if ((current = popen(cmd, "r")) == NULL)		return NULL;	return (rp->iop = iop_alloc(fileno(current)));}static intgawk_pclose(rp)struct redirect *rp;{	int rval, aval, fd = rp->iop->fd;	FILE *kludge = fdopen(fd, "r"); /* pclose needs FILE* w/ right fileno */	rp->iop->fd = dup(fd);	  /* kludge to allow close() + pclose() */	rval = iop_close(rp->iop);	rp->iop = NULL;	aval = pclose(kludge);	return (rval < 0 ? rval : aval);}#else	/* VMS */staticstruct {	char *command;	char *name;} pipes[_NFILE];static IOBUF *gawk_popen(cmd, rp)char *cmd;struct redirect *rp;{	extern char *strdup(const char *);	int current;	char *name;	static char cmdbuf[256];	/* get a name to use.  */	if ((name = tempnam(".", "pip")) == NULL)		return NULL;	sprintf(cmdbuf,"%s > %s", cmd, name);	system(cmdbuf);	if ((current = open(name,O_RDONLY)) == INVALID_HANDLE)		return NULL;	pipes[current].name = name;	pipes[current].command = strdup(cmd);	rp->iop = iop_alloc(current);	return (rp->iop = iop_alloc(current));}static intgawk_pclose(rp)struct redirect *rp;{	int cur = rp->iop->fd;	int rval;	rval = iop_close(rp->iop);	rp->iop = NULL;	/* check for an open file  */	if (pipes[cur].name == NULL)		return -1;	unlink(pipes[cur].name);	free(pipes[cur].name);	pipes[cur].name = NULL;	free(pipes[cur].command);	return rval;}#endif	/* VMS */#endif	/* PIPES_SIMULATED */NODE *do_getline(tree)NODE *tree;{	struct redirect *rp = NULL;	IOBUF *iop;	int cnt = EOF;	char *s = NULL;	int errcode;	while (cnt == EOF) {		if (tree->rnode == NULL) {	 /* no redirection */			iop = nextfile(0);			if (iop == NULL)		/* end of input */				return tmp_number((AWKNUM) 0.0);		} else {			int redir_error = 0;			rp = redirect(tree->rnode, &redir_error);			if (rp == NULL && redir_error) { /* failed redirect */				if (! do_unix) {					char *s = strerror(redir_error);					unref(ERRNO_node->var_value);					ERRNO_node->var_value =						make_string(s, strlen(s));				}				return tmp_number((AWKNUM) -1.0);			}			iop = rp->iop;			if (iop == NULL)		/* end of input */				return tmp_number((AWKNUM) 0.0);		}		errcode = 0;		cnt = get_a_record(&s, iop, *RS, & errcode);		if (! do_unix && errcode != 0) {			char *s = strerror(errcode);			unref(ERRNO_node->var_value);			ERRNO_node->var_value = make_string(s, strlen(s));			return tmp_number((AWKNUM) -1.0);		}		if (cnt == EOF) {			if (rp) {				/*				 * Don't do iop_close() here if we are				 * reading from a pipe; otherwise				 * gawk_pclose will not be called.				 */				if (!(rp->flag & RED_PIPE)) {					(void) iop_close(iop);					rp->iop = NULL;				}				rp->flag |= RED_EOF;	/* sticky EOF */				return tmp_number((AWKNUM) 0.0);			} else				continue;	/* try another file */		}		if (!rp) {			NR += 1;			FNR += 1;		}		if (tree->lnode == NULL)	/* no optional var. */			set_record(s, cnt, 1);		else {			/* assignment to variable */			Func_ptr after_assign = NULL;			NODE **lhs;			lhs = get_lhs(tree->lnode, &after_assign);			unref(*lhs);			*lhs = make_string(s, strlen(s));			(*lhs)->flags |= MAYBE_NUM;			/* we may have to regenerate $0 here! */			if (after_assign)				(*after_assign)();		}	}	return tmp_number((AWKNUM) 1.0);}intpathopen (file)char *file;{	int fd = do_pathopen(file);#ifdef DEFAULT_FILETYPE	if (! do_unix && fd <= INVALID_HANDLE) {		char *file_awk;		int save = errno;#ifdef VMS		int vms_save = vaxc$errno;#endif		/* append ".awk" and try again */		emalloc(file_awk, char *, strlen(file) +			sizeof(DEFAULT_FILETYPE) + 1, "pathopen");		sprintf(file_awk, "%s%s", file, DEFAULT_FILETYPE);		fd = do_pathopen(file_awk);		free(file_awk);		if (fd <= INVALID_HANDLE) {			errno = save;#ifdef VMS			vaxc$errno = vms_save;#endif		}	}#endif	/*DEFAULT_FILETYPE*/	return fd;}static intdo_pathopen (file)char *file;{	static char *savepath = DEFPATH;	/* defined in config.h */	static int first = 1;	char *awkpath, *cp;	char trypath[BUFSIZ];	int fd;	if (STREQ(file, "-"))		return (0);	if (do_unix)		return (devopen(file, "r"));	if (first) {		first = 0;		if ((awkpath = getenv ("AWKPATH")) != NULL && *awkpath)			savepath = awkpath;	/* used for restarting */	}	awkpath = savepath;	/* some kind of path name, no search */#ifdef VMS	/* (strchr not equal implies either or both not NULL) */	if (strchr(file, ':') != strchr(file, ']')	 || strchr(file, '>') != strchr(file, '/'))#else /*!VMS*/#ifdef MSDOS	if (strchr(file, '/') != strchr(file, '\\')	 || strchr(file, ':') != NULL)#else	if (strchr(file, '/') != NULL)#endif	/*MSDOS*/#endif	/*VMS*/		return (devopen(file, "r"));	do {		trypath[0] = '\0';		/* this should take into account limits on size of trypath */		for (cp = trypath; *awkpath && *awkpath != ENVSEP; )			*cp++ = *awkpath++;		if (cp != trypath) {	/* nun-null element in path */			/* add directory punctuation only if needed */#ifdef VMS			if (strchr(":]>/", *(cp-1)) == NULL)#else#ifdef MSDOS			if (strchr(":\\/", *(cp-1)) == NULL)#else			if (*(cp-1) != '/')#endif#endif				*cp++ = '/';			/* append filename */			strcpy (cp, file);		} else			strcpy (trypath, file);		if ((fd = devopen(trypath, "r")) >= 0)			return (fd);		/* no luck, keep going */		if(*awkpath == ENVSEP && awkpath[1] != '\0')			awkpath++;	/* skip colon */	} while (*awkpath);	/*	 * You might have one of the awk	 * paths defined, WITHOUT the current working directory in it.	 * Therefore try to open the file in the current directory.	 */	return (devopen(file, "r"));}

⌨️ 快捷键说明

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