erl_io.c
来自「OTP是开放电信平台的简称」· C语言 代码 · 共 108 行
C
108 行
/* ``The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved via the world wide web at http://www.erlang.org/. * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' * * $Id$ *//* Some stuff to let the Erlang and VxWorks shells coexist peacefully. Basically, run Erlang as a spawned task with input redirected to the slave side of a pseudo-tty, and connect explicitly to the master side of the pseudo-tty to send input to Erlang when desired. */#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <stdio.h>#include <ioLib.h>#include <taskLib.h>#include <ptyDrv.h>extern int spTaskPriority, spTaskOptions;#define TBUFSIZ 512#define DEFAULT_STACK_SIZE 100000static int slavefd = -1, masterfd = -1;static run_erl();/* Frontend to the Erlang startup function - callable from VxWorks shell or script. 'arg' is actually a string passed to the real startup. */start_erl(arg)int arg;{ int stacksize; char *stackenv; /* create and open the pty - we want the master side to be open all the time, since closing it probably generates EOF on the slave side */ (void)ptyDevCreate("/pty/erlang.", TBUFSIZ, TBUFSIZ); if (slavefd != -1) (void)close(slavefd); slavefd = open("/pty/erlang.S", O_RDONLY, 0); if (masterfd != -1) (void)close(masterfd); masterfd = open("/pty/erlang.M", O_WRONLY, 0); /* flush any old leftover garbage */ (void) ioctl(masterfd, FIOFLUSH, 0); if ((stackenv = getenv("ERLSTACKSIZE")) == NULL) stacksize = DEFAULT_STACK_SIZE; else stacksize = atoi(stackenv); /* spawn Erlang, via stub below */ return(taskSpawn("erlang", spTaskPriority, spTaskOptions, stacksize, run_erl, arg, 0,0,0,0,0,0,0,0,0));}/* Little stub that runs in the spawned task - we need this to redirect stdin reliably (redirections aren't "inherited" in VxWorks) */staticrun_erl(arg)int arg;{ ioTaskStdSet(0, 0, slavefd); /* redirect stdin to slave side of pty */ /* We don't want to redirect stdout/err since no one will be reading from the master side (to_erl - and the open()s above - could be made bidirectional, but still the master side would only be read when to_erl was running), and output can eventually fill the pty buffer and cause the Erlang system to block. Not redirecting stdout/err will have the effect that output from Erlang, e.g. the shell prompt, will appear on console/rlogin/whatever even when to_erl isn't running, which may be confusing - can't win 'em all... */ erl_exec(arg, 0,0,0,0,0,0,0,0); /* call the real startup */}/* Function callable from VxWorks shell to talk to Erlang - stop talking and return to VxWorks shell through ^D (EOF) */to_erl(){ char buf[TBUFSIZ]; int cc; if (masterfd == -1) { /* sanity check */ fprintf(stderr, "Must start_erl first!\n"); return(-1); } while ((cc = read(0, buf, TBUFSIZ)) > 0) /* just pass everything through */ if (write(masterfd, buf, cc) != cc) { fprintf(stderr, "Write to Erlang failed!\n"); return(-1); } return(cc);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?