/* $Header$*/ /* * Copyright © 2003 Keith Packard and Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. */ extend namespace File { public file stdnull () { static bool set = false; static file f; if (!set) f = open("/dev/null", "r+"); return f; } public typedef union { file input; file output; file error; } childfd; public int mkchild(string path, string[*] argv, childfd fds ...) /* * Call filter transforming 'fds' into an array of three files. * This is what happens when you fork() */ { file[3] filter_fds = { stdnull(), ... }; for (int i = 0; i < dim(fds); i++) { union switch(fds[i]) { case input f: filter_fds[0] = f; break; case output f: filter_fds[1] = f; break; case error f: filter_fds[2] = f; break; } } return filter(path, argv, filter_fds); } public namespace FileGlobals { public int getchar () /* return getc (stdin); */ { return File::getc (stdin); } public void ungetchar (int ch) /* ungetc (ch, stdin); */ { File::ungetc (ch, stdin); } public void putchar (int c) /* putc (c, stdout) */ { putc (c, stdout); } public int getbyte () /* return getb (stdin) */ { return File::getb (stdin); } public void putbyte (int b) /* putb (b, stdout) */ { File::putb (b, stdout); } public string fgets (file f) /* * Return a line from 'f' as a string. * The trailing newline will be stripped off. */ { string s; int c; s = ""; for (;;) { c = getc (f); switch (c) { case '\n': case -1: return s; default: s = s + String::new (c); } } } public string gets () /* return fgets (stdin); */ { return fgets (stdin); } } public import FileGlobals; } public import File::FileGlobals;