📄 io.c
字号:
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 + -