📄 io.c
字号:
/* $Id: io.c,v 1.4 2007/01/04 21:35:54 erg Exp $ $Revision: 1.4 $ *//* vim:set shiftwidth=4 ts=8: *//*********************************************************** This software is part of the graphviz package ** http://www.graphviz.org/ ** ** Copyright (c) 1994-2004 AT&T Corp. ** and is licensed under the ** Common Public License, Version 1.0 ** by AT&T Corp. ** ** Information and Software Systems Research ** AT&T Research, Florham Park NJ ***********************************************************//* Lefteris Koutsofios - AT&T Labs Research */#include "common.h"#include "g.h"#include "io.h"#include "mem.h"io_t *iop;int ion;static void pipeopen (char *, FILE **, FILE **, int *);void IOinit (void) { struct stat statbuf; int ioi; iop = Marrayalloc ((long) IOINCR * IOSIZE); ion = IOINCR; for (ioi = 0; ioi < ion; ioi++) iop[ioi].inuse = FALSE; for (ioi = 0; ioi < 3; ioi++) if (fstat (ioi, &statbuf) == 0) { iop[ioi].inuse = TRUE; iop[ioi].type = IO_FILE; iop[ioi].ifp = iop[ioi].ofp = fdopen (ioi, "r+"); if (!(iop[ioi].buf = malloc (IOBUFSIZE))) panic1 (POS, "IOinit", "malloc failed"); iop[ioi].buf[0] = 0; }}void IOterm (void) { int ioi; for (ioi = 0; ioi < ion; ioi++) if (iop[ioi].inuse) IOclose (ioi, NULL); Marrayfree (iop), iop = NULL, ion = 0;}int IOopen (char *kind, char *name, char *mode, char *fmt) { io_t *p; int type; char *path, *command; int i; int count = 0; if (strcmp (kind, "file") == 0) type = IO_FILE; else if (strcmp (kind, "pipe") == 0) type = IO_PIPE; else return -1; for (i = 0; i < ion; i++) if (!iop[i].inuse) break; if (i == ion) { iop = Marraygrow (iop, (long) (ion + IOINCR) * IOSIZE); for (i = ion + IOINCR - 1; i >= ion; i--) iop[i].inuse = FALSE; i++, ion += IOINCR; } p = &iop[i]; p->type = type; if (!(p->buf = malloc (IOBUFSIZE))) panic1 (POS, "IOopen", "malloc failed"); p->buf[0] = 0; switch (type) { case IO_FILE: if (!(p->ifp = p->ofp = fopen (name, mode))) { path = buildpath (name, FALSE); if (!path || !(p->ifp = p->ofp = fopen (path, mode))) return -1; } break; case IO_PIPE: if (!fmt) fmt = "%e"; if ( !(path = buildpath (name, TRUE)) || !(command = buildcommand (path, NULL, -1, -1, fmt)) ) return -1; pipeopen (command, &p->ifp, &p->ofp, &p->pid); if (!p->ifp || !p->ofp) return -1; break; } p->inuse = TRUE; return i;}int IOclose (int ioi, char *action) { io_t *p; if (ioi < 0 || ioi >= ion || !iop[ioi].inuse) return -1; p = &iop[ioi]; free (p->buf); switch (p->type) { case IO_FILE: fclose (p->ifp); fclose (p->ofp); break; case IO_PIPE: CloseHandle (p->ifp); CloseHandle (p->ofp); break; } p->inuse = FALSE; return 0;}int IOreadline (int ioi, char *bufp, int bufn) { io_t *p; DWORD n; int l, i, m; if (ioi < 0 || ioi >= ion || !iop[ioi].inuse) return -1; p = &iop[ioi]; switch (p->type) { case IO_FILE: if (fgets (bufp, bufn, p->ifp) == NULL) return -1; break; case IO_PIPE: l = 0; if (p->buf[0]) { for (l = 0; l < bufn - 1 && p->buf[l]; l++) if ((bufp[l] = p->buf[l]) == '\n') { l++; break; } for (i = l; p->buf[i]; i++) p->buf[i - l] = p->buf[i]; p->buf[i - l] = 0; bufp[l] = 0; if (bufp[l - 1] == '\n') break; /* exit switch */ } while (l < bufn - 1) { m = bufn - l - 1; if (m > IOBUFSIZE - 1) m = IOBUFSIZE - 1; if (!ReadFile (p->ifp, bufp + l, m, &n, NULL)) return -1; for (m = l; m < l + n; m++) if (bufp[m] == '\n') { m++; break; } for (i = m; i < l + n; i++) p->buf[i - m] = bufp[i]; bufp[m] = 0; p->buf[i - m] = 0; if (bufp[m - 1] == '\n') break; l += n; } break; } l = strlen (bufp) - 1; while (bufp[l] == '\n' || bufp[l] == '\r') bufp[l--] = '\000'; return 0;}int IOread (int ioi, char *bufp, int bufn) { io_t *p; DWORD l; if (ioi < 0 || ioi >= ion || !iop[ioi].inuse) return -1; p = &iop[ioi]; switch (p->type) { case IO_FILE: if ((l = read (fileno (p->ifp), bufp, bufn - 1)) == -1) return -1; else if (l == 0) return 0; break; case IO_PIPE: if (!ReadFile (p->ifp, bufp, bufn - 1, &l, NULL)) return -1; if (l == 0) return 0; break; } bufp[l] = '\000'; return l;}int IOwriteline (int ioi, char *bufp) { io_t *p; DWORD l; if (ioi < 0 || ioi >= ion || !iop[ioi].inuse) return -1; p = &iop[ioi]; switch (p->type) { case IO_FILE: if (fputs (bufp, p->ofp) == EOF || fputs ("\n", p->ofp) == EOF) return -1; fflush (p->ofp); break; case IO_PIPE: if ( !WriteFile (p->ofp, bufp, strlen (bufp), &l, NULL) || !WriteFile (p->ofp, "\n", 1, &l, NULL) ) return -1; break; } return 0;}static void pipeopen (char *cmd, FILE **ifp, FILE **ofp, int *pidp) { PROCESS_INFORMATION pinfo; STARTUPINFO sinfo; SECURITY_ATTRIBUTES sattr; HANDLE h, p1[2], p2[2], save[2]; sattr.nLength = sizeof (SECURITY_ATTRIBUTES); sattr.bInheritHandle = TRUE; sattr.lpSecurityDescriptor = NULL; if ( !CreatePipe (&p1[0], &p1[1], &sattr, 0) || !CreatePipe (&p2[0], &p2[1], &sattr, 0) ) { *ifp = NULL; return; } save[0] = GetStdHandle (STD_INPUT_HANDLE); save[1] = GetStdHandle (STD_OUTPUT_HANDLE); if (!SetStdHandle (STD_OUTPUT_HANDLE, p1[1])) panic1 (POS, "pipeopen", "cannot set stdout handle"); if (!SetStdHandle (STD_INPUT_HANDLE, p2[0])) panic1 (POS, "pipeopen", "cannot set stdin handle"); h = p1[0]; if (!DuplicateHandle ( GetCurrentProcess (), h, GetCurrentProcess (), &p1[0], 0, FALSE, DUPLICATE_SAME_ACCESS )) panic1 (POS, "pipeopen", "cannot dup input handle"); CloseHandle (h); h = p2[1]; if (!DuplicateHandle ( GetCurrentProcess(), h, GetCurrentProcess(), &p2[1], 0, FALSE, DUPLICATE_SAME_ACCESS )) panic1 (POS, "pipeopen", "cannot dup output handle"); CloseHandle (h); sinfo.cb = sizeof (STARTUPINFO); sinfo.lpReserved = NULL; sinfo.lpDesktop = NULL; sinfo.lpTitle = NULL; sinfo.cbReserved2 = 0; sinfo.lpReserved2 = NULL; sinfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; sinfo.hStdInput = p2[0]; sinfo.hStdOutput = p1[1]; sinfo.wShowWindow = SW_HIDE; if (!CreateProcess ( NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &sinfo, &pinfo )) panic1 (POS, "pipeopen", "cannot create child process"); *pidp = pinfo.hProcess; if (!SetStdHandle (STD_INPUT_HANDLE, save[0])) panic1 (POS, "pipeopen", "cannot restore stdin"); if (!SetStdHandle (STD_OUTPUT_HANDLE, save[1])) panic1 (POS, "pipeopen", "cannot restore stdout"); CloseHandle (p1[1]); CloseHandle (p2[0]); *ifp = p1[0], *ofp = p2[1]; return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -