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 + -
显示快捷键?