From 200fbe924466720bd2a8c5eb05b05d67b0a2414c Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Thu, 14 Mar 2013 15:42:19 +0100 Subject: Added support for ENEA OSE This port has support for both non-smp and smp. It contains a new way to do io checking in which erts_poll_wait receives the payload of the polled entity. This has implications for all linked-in drivers. --- erts/etc/common/Makefile.in | 42 +++++++++++++++++++++++++++++++----------- erts/etc/common/inet_gethost.c | 2 +- 2 files changed, 32 insertions(+), 12 deletions(-) (limited to 'erts/etc/common') diff --git a/erts/etc/common/Makefile.in b/erts/etc/common/Makefile.in index 5c1ce51644..d7fe75ce6f 100644 --- a/erts/etc/common/Makefile.in +++ b/erts/etc/common/Makefile.in @@ -20,6 +20,10 @@ include $(ERL_TOP)/make/output.mk include $(ERL_TOP)/make/target.mk +ifeq ($(findstring ose,$(TARGET)),ose) +include $(ERL_TOP)/make/$(TARGET)/ose_lm.mk +endif + ERTS_LIB_TYPEMARKER=.$(TYPE) USING_MINGW=@MIXED_CYGWIN_MINGW@ @@ -161,7 +165,26 @@ endif PORT_ENTRY_POINT=erl_port_entry ENTRY_LDFLAGS=-entry:$(PORT_ENTRY_POINT) -else # UNIX (!win32) +else +ifeq ($(findstring ose,$(TARGET)),ose) +ENTRY_LDFLAGS= +ENTRY_OBJ= +ERLSRV_OBJECTS= +MC_OUTPUTS= +INET_GETHOST = +INSTALL_EMBEDDED_PROGS = +INSTALL_EMBEDDED_DATA = +INSTALL_TOP = Install +INSTALL_TOP_BIN = +INSTALL_MISC = +INSTALL_SRC = +ERLEXECDIR = . +INSTALL_LIBS = +INSTALL_OBJS = +INSTALL_INCLUDES = +TEXTFILES = Install erl.src +INSTALL_PROGS = +else # UNIX (!win32 && !ose) ENTRY_LDFLAGS= ENTRY_OBJ= ERLSRV_OBJECTS= @@ -186,6 +209,7 @@ INSTALL_PROGS = \ $(BINDIR)/$(ERLEXEC) \ $(INSTALL_EMBEDDED_PROGS) endif +endif .PHONY: etc etc: $(ENTRY_OBJ) $(INSTALL_PROGS) $(INSTALL_LIBS) $(TEXTFILES) $(INSTALL_TOP_BIN) @@ -370,27 +394,27 @@ $(OBJDIR)/heart.o: heart.c $(RC_GENERATED) $(OBJDIR)/inet_gethost.o: inet_gethost.c $(RC_GENERATED) $(V_CC) $(CFLAGS) -o $@ -c inet_gethost.c +# inet_gethost $(BINDIR)/inet_gethost@EXEEXT@: $(OBJDIR)/inet_gethost.o $(ENTRY_OBJ) $(ERTS_LIB) $(ld_verbose)$(PURIFY) $(LD) $(LDFLAGS) $(ENTRY_LDFLAGS) -o $@ $(OBJDIR)/inet_gethost.o $(ENTRY_OBJ) $(LIBS) $(ERTS_INTERNAL_LIBS) +# run_erl $(BINDIR)/run_erl: $(OBJDIR)/safe_string.o $(OBJDIR)/run_erl.o - $(V_LD) $(LDFLAGS) -o $@ $(OBJDIR)/safe_string.o $(OBJDIR)/run_erl.o $(LIBS) - + $(V_LD) $(LDFLAGS) -o $@ $(OBJDIR)/safe_string.o $(OBJDIR)/run_erl.o $(LIBS) $(ERTS_INTERNAL_LIBS) $(OBJDIR)/run_erl.o: ../unix/run_erl.c $(RC_GENERATED) $(V_CC) $(CFLAGS) -o $@ -c ../unix/run_erl.c +# to_erl $(BINDIR)/to_erl: $(OBJDIR)/safe_string.o $(OBJDIR)/to_erl.o $(V_LD) $(LDFLAGS) -o $@ $(OBJDIR)/safe_string.o $(OBJDIR)/to_erl.o - $(OBJDIR)/to_erl.o: ../unix/to_erl.c $(RC_GENERATED) $(V_CC) $(CFLAGS) -o $@ -c ../unix/to_erl.c +# dyn_erl $(BINDIR)/dyn_erl: $(OBJDIR)/safe_string.o $(OBJDIR)/dyn_erl.o $(V_LD) $(LDFLAGS) -o $@ $(OBJDIR)/safe_string.o $(OBJDIR)/dyn_erl.o - $(OBJDIR)/dyn_erl.o: ../unix/dyn_erl.c $(RC_GENERATED) $(V_CC) $(CFLAGS) -o $@ -c ../unix/dyn_erl.c - $(OBJDIR)/safe_string.o: ../unix/safe_string.c $(RC_GENERATED) $(V_CC) $(CFLAGS) -o $@ -c ../unix/safe_string.c @@ -401,6 +425,7 @@ $(BINDIR)/$(ERLEXEC): $(OBJDIR)/$(ERLEXEC).o $(ERTS_LIB) $(OBJDIR)/$(ERLEXEC).o: $(ERLEXECDIR)/$(ERLEXEC).c $(RC_GENERATED) $(V_CC) -I$(EMUDIR) $(CFLAGS) -o $@ -c $(ERLEXECDIR)/$(ERLEXEC).c endif + $(BINDIR)/erlc@EXEEXT@: $(OBJDIR)/erlc.o $(ERTS_LIB) $(ld_verbose)$(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/erlc.o -L$(OBJDIR) $(LIBS) $(ERTS_INTERNAL_LIBS) @@ -478,11 +503,6 @@ ifneq ($(INSTALL_MISC),) $(INSTALL_DIR) "$(RELEASE_PATH)/misc" $(INSTALL_SCRIPT) $(INSTALL_MISC) "$(RELEASE_PATH)/misc" endif -ifneq ($(INSTALL_ERL_OSE),) - $(INSTALL_DIR) "$(RELEASE_PATH)/build_erl_ose" - cd $(OSEETC) && $(TAR) erl_ose_$(SYSTEM_VSN).tar $(INSTALL_ERL_OSE) - cd $(OSEETC) && $(INSTALL_SCRIPT) erl_ose_$(SYSTEM_VSN).tar "$(RELEASE_PATH)/build_erl_ose" -endif ifneq ($(INSTALL_SRC),) $(INSTALL_DIR) "$(RELEASE_PATH)/erts-$(VSN)/src" $(INSTALL_DATA) $(INSTALL_SRC) "$(RELEASE_PATH)/erts-$(VSN)/src" diff --git a/erts/etc/common/inet_gethost.c b/erts/etc/common/inet_gethost.c index bef97862a3..9ec4192667 100644 --- a/erts/etc/common/inet_gethost.c +++ b/erts/etc/common/inet_gethost.c @@ -1209,7 +1209,7 @@ static void start_que_request(Worker *w) #endif } -#ifndef WIN32 +#ifndef WIN32 /* Signal utilities */ static RETSIGTYPE (*sys_sigset(int sig, RETSIGTYPE (*func)(int)))(int) { -- cgit v1.2.3 From aa80261396941ee63758d6b5965a7e075b79b4ee Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Mon, 16 Dec 2013 16:34:58 +0100 Subject: erts: Refactor common parts out of run_erl and to_erl This is in preperation for writing ose version of run_erl and to_erl --- erts/etc/common/Makefile.in | 28 +- erts/etc/common/run_erl_common.c | 610 +++++++++++++++++++++++++++++++++++++++ erts/etc/common/run_erl_common.h | 95 ++++++ erts/etc/common/run_erl_vsn.h | 29 ++ erts/etc/common/safe_string.c | 122 ++++++++ erts/etc/common/safe_string.h | 64 ++++ erts/etc/common/to_erl_common.c | 607 ++++++++++++++++++++++++++++++++++++++ erts/etc/common/to_erl_common.h | 28 ++ 8 files changed, 1572 insertions(+), 11 deletions(-) create mode 100644 erts/etc/common/run_erl_common.c create mode 100644 erts/etc/common/run_erl_common.h create mode 100644 erts/etc/common/run_erl_vsn.h create mode 100644 erts/etc/common/safe_string.c create mode 100644 erts/etc/common/safe_string.h create mode 100644 erts/etc/common/to_erl_common.c create mode 100644 erts/etc/common/to_erl_common.h (limited to 'erts/etc/common') diff --git a/erts/etc/common/Makefile.in b/erts/etc/common/Makefile.in index d7fe75ce6f..f5df53ec01 100644 --- a/erts/etc/common/Makefile.in +++ b/erts/etc/common/Makefile.in @@ -254,7 +254,9 @@ endif rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/run_erl.o rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/to_erl.o rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/dyn_erl.o - rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/safe_string.o + rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/safe_string.o + rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/run_erl_common.o + rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/to_erl_common.o rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/typer.o rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/ct_run.o rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/vxcall.o @@ -399,24 +401,28 @@ $(BINDIR)/inet_gethost@EXEEXT@: $(OBJDIR)/inet_gethost.o $(ENTRY_OBJ) $(ERTS_LIB $(ld_verbose)$(PURIFY) $(LD) $(LDFLAGS) $(ENTRY_LDFLAGS) -o $@ $(OBJDIR)/inet_gethost.o $(ENTRY_OBJ) $(LIBS) $(ERTS_INTERNAL_LIBS) # run_erl -$(BINDIR)/run_erl: $(OBJDIR)/safe_string.o $(OBJDIR)/run_erl.o - $(V_LD) $(LDFLAGS) -o $@ $(OBJDIR)/safe_string.o $(OBJDIR)/run_erl.o $(LIBS) $(ERTS_INTERNAL_LIBS) -$(OBJDIR)/run_erl.o: ../unix/run_erl.c $(RC_GENERATED) - $(V_CC) $(CFLAGS) -o $@ -c ../unix/run_erl.c +$(BINDIR)/run_erl: $(OBJDIR)/safe_string.o $(OBJDIR)/run_erl.o $(OBJDIR)/run_erl_common.o + $(V_LD) $(LDFLAGS) -o $@ $^ $(LIBS) +$(OBJDIR)/run_erl.o: ../unix/run_erl.c ../common/run_erl_common.h $(RC_GENERATED) + $(V_CC) $(CFLAGS) -I ../common/ -o $@ -c ../unix/run_erl.c +$(OBJDIR)/run_erl_common.o: ../common/run_erl_common.c ../common/run_erl_common.h $(RC_GENERATED) + $(V_CC) $(CFLAGS) -o $@ -c $< # to_erl -$(BINDIR)/to_erl: $(OBJDIR)/safe_string.o $(OBJDIR)/to_erl.o - $(V_LD) $(LDFLAGS) -o $@ $(OBJDIR)/safe_string.o $(OBJDIR)/to_erl.o -$(OBJDIR)/to_erl.o: ../unix/to_erl.c $(RC_GENERATED) - $(V_CC) $(CFLAGS) -o $@ -c ../unix/to_erl.c +$(BINDIR)/to_erl: $(OBJDIR)/safe_string.o $(OBJDIR)/to_erl.o $(OBJDIR)/to_erl_common.o + $(V_LD) $(LDFLAGS) -o $@ $^ +$(OBJDIR)/to_erl.o: ../unix/to_erl.c ../common/safe_string.h $(RC_GENERATED) + $(V_CC) $(CFLAGS) -I ../common/ -o $@ -c ../unix/to_erl.c +$(OBJDIR)/to_erl_common.o: ../common/to_erl_common.c ../common/to_erl_common.h $(RC_GENERATED) + $(V_CC) $(CFLAGS) -o $@ -c $< # dyn_erl $(BINDIR)/dyn_erl: $(OBJDIR)/safe_string.o $(OBJDIR)/dyn_erl.o $(V_LD) $(LDFLAGS) -o $@ $(OBJDIR)/safe_string.o $(OBJDIR)/dyn_erl.o $(OBJDIR)/dyn_erl.o: ../unix/dyn_erl.c $(RC_GENERATED) $(V_CC) $(CFLAGS) -o $@ -c ../unix/dyn_erl.c -$(OBJDIR)/safe_string.o: ../unix/safe_string.c $(RC_GENERATED) - $(V_CC) $(CFLAGS) -o $@ -c ../unix/safe_string.c +$(OBJDIR)/safe_string.o: ../common/safe_string.c $(RC_GENERATED) + $(V_CC) $(CFLAGS) -o $@ -c ../common/safe_string.c ifneq ($(TARGET),win32) $(BINDIR)/$(ERLEXEC): $(OBJDIR)/$(ERLEXEC).o $(ERTS_LIB) diff --git a/erts/etc/common/run_erl_common.c b/erts/etc/common/run_erl_common.c new file mode 100644 index 0000000000..dc899c5349 --- /dev/null +++ b/erts/etc/common/run_erl_common.c @@ -0,0 +1,610 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2014. All Rights Reserved. + * + * 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 online 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. + * + * %CopyrightEnd% + */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_SYSLOG_H +# include +#endif + +#include "run_erl_common.h" +#include "safe_string.h" + +#define DEFAULT_LOG_GENERATIONS 5 +#define LOG_MAX_GENERATIONS 1000 /* No more than 1000 log files */ +#define LOG_MIN_GENERATIONS 2 /* At least two to switch between */ +#define DEFAULT_LOG_MAXSIZE 100000 +#define LOG_MIN_MAXSIZE 1000 /* Smallast value for changing log file */ +#define LOG_STUBNAME "erlang.log." +#define LOG_PERM 0664 +#define DEFAULT_LOG_ACTIVITY_MINUTES 5 +#define DEFAULT_LOG_ALIVE_MINUTES 15 +#define DEFAULT_LOG_ALIVE_FORMAT "%a %b %e %T %Z %Y" +#define ALIVE_BUFFSIZ 1024 + +#define STATUSFILENAME "/run_erl.log" + +#define PIPE_STUBNAME "erlang.pipe" +#define PIPE_STUBLEN strlen(PIPE_STUBNAME) +#define PERM (S_IWUSR | S_IRUSR | S_IWOTH | S_IROTH | S_IWGRP | S_IRGRP) + +#if !defined(O_SYNC) +#define O_SYNC 0 +#define USE_FSYNC 1 +#endif + +/* prototypes */ + +static int next_log(int log_num); +static int prev_log(int log_num); +static int find_next_log_num(void); +static int open_log(int log_num, int flags); + +/* static data */ +static char statusfile[FILENAME_BUFSIZ]; +static char log_dir[FILENAME_BUFSIZ]; +static FILE *stdstatus = NULL; +static int log_generations = DEFAULT_LOG_GENERATIONS; +static int log_maxsize = DEFAULT_LOG_MAXSIZE; +static int log_activity_minutes = DEFAULT_LOG_ACTIVITY_MINUTES; +static int log_alive_in_gmt = 0; +static char log_alive_format[ALIVE_BUFFSIZ+1]; +static int run_daemon = 0; +static unsigned protocol_ver = RUN_ERL_LO_VER; /* assume lowest to begin with */ + +int erts_run_erl_log_alive_minutes = DEFAULT_LOG_ALIVE_MINUTES; + +/* + * Current log number and log fd + */ +static int log_num; +static int lfd=0; + + +/* + * getenv_int: + */ +static char *getenv_int(const char *name) { + return getenv(name); +} + +/* + * next_log: + * Returns the index number that follows the given index number. + * (Wrapping after log_generations) + */ +static int next_log(int log_num) { + return log_num>=log_generations?1:log_num+1; +} + +/* + * prev_log: + * Returns the index number that precedes the given index number. + * (Wrapping after log_generations) + */ +static int prev_log(int log_num) { + return log_num<=1?log_generations:log_num-1; +} + +/* + * find_next_log_num() + * Searches through the log directory to check which logs that already + * exist. It finds the "hole" in the sequence, and returns the index + * number for the last log in the log sequence. If there is no hole, index + * 1 is returned. + */ +static int find_next_log_num(void) { + int i, next_gen, log_gen; + DIR *dirp; + struct dirent *direntp; + int log_exists[LOG_MAX_GENERATIONS+1]; + int stub_len = strlen(LOG_STUBNAME); + + /* Initialize exiting log table */ + + for(i=log_generations; i>=0; i--) + log_exists[i] = 0; + dirp = opendir(log_dir); + if(!dirp) { + ERRNO_ERR1(LOG_ERR,"Can't access log directory '%s'", log_dir); + exit(1); + } + + /* Check the directory for existing logs */ + + while((direntp=readdir(dirp)) != NULL) { + if(strncmp(direntp->d_name,LOG_STUBNAME,stub_len)==0) { + int num = atoi(direntp->d_name+stub_len); + if(num < 1 || num > log_generations) + continue; + log_exists[num] = 1; + } + } + closedir(dirp); + + /* Find out the next available log file number */ + + next_gen = 0; + for(i=log_generations; i>=0; i--) { + if(log_exists[i]) + if(next_gen) + break; + else + ; + else + next_gen = i; + } + + /* Find out the current log file number */ + + if(next_gen) + log_gen = prev_log(next_gen); + else + log_gen = 1; + + return log_gen; +} /* find_next_log_num() */ + +static int open_log(int log_num, int flags) +{ + char buf[FILENAME_MAX]; + time_t now; + struct tm *tmptr; + char log_buffer[ALIVE_BUFFSIZ+1]; + + /* Remove the next log (to keep a "hole" in the log sequence) */ + sn_printf(buf, sizeof(buf), "%s/%s%d", + log_dir, LOG_STUBNAME, next_log(log_num)); + unlink(buf); + + /* Create or continue on the current log file */ + sn_printf(buf, sizeof(buf), "%s/%s%d", log_dir, LOG_STUBNAME, log_num); + + do { + lfd = open(buf, flags, LOG_PERM); + } while (lfd < 0 && errno == EINTR); + + if(lfd <0){ + ERRNO_ERR1(LOG_ERR,"Can't open log file '%s'.", buf); + exit(1); + } + + /* Write a LOGGING STARTED and time stamp into the log file */ + time(&now); + if (log_alive_in_gmt) { + tmptr = gmtime(&now); + } else { + tmptr = localtime(&now); + } + if (!strftime(log_buffer, ALIVE_BUFFSIZ, log_alive_format, + tmptr)) { + strn_cpy(log_buffer, sizeof(log_buffer), + "(could not format time in 256 positions " + "with current format string.)"); + } + log_buffer[ALIVE_BUFFSIZ] = '\0'; + + sn_printf(buf, sizeof(buf), "\n=====\n===== LOGGING STARTED %s\n=====\n", + log_buffer); + if (erts_run_erl_write_all(lfd, buf, strlen(buf)) < 0) + erts_run_erl_log_status("Error in writing to log.\n"); + +#if USE_FSYNC + fsync(lfd); +#endif + + return lfd; +} + +/* Instead of making sure basename exists, we do our own */ +char *simple_basename(char *path) +{ + char *ptr; + for (ptr = path; *ptr != '\0'; ++ptr) { + if (*ptr == '/') { + path = ptr + 1; + } + } + return path; +} + +ssize_t sf_read(int fd, void *buffer, size_t len) { + ssize_t n = 0; + + do { n = read(fd, buffer, len); } while (n < 0 && errno == EINTR); + + return n; +} + +ssize_t sf_write(int fd, const void *buffer, size_t len) { + ssize_t n = 0; + + do { n = write(fd, buffer, len); } while (n < 0 && errno == EINTR); + + return n; +} + +int sf_open(const char *path, int type, mode_t mode) { + int fd = 0; + + do { fd = open(path, type, mode); } while(fd < 0 && errno == EINTR); + + return fd; +} + +int sf_close(int fd) { + int res = 0; + + do { res = close(fd); } while(res < 0 && errno == EINTR); + + return res; +} + +/* Call write() until entire buffer has been written or error. + * Return len or -1. + */ +int erts_run_erl_write_all(int fd, const char* buf, int len) +{ + int left = len; + int written; + for (;;) { + do { + written = write(fd,buf,left); + } while (written < 0 && errno == EINTR); + if (written == left) { + return len; + } + if (written < 0) { + return -1; + } + left -= written; + buf += written; + } + return written; +} + +/* erts_run_erl_log_status() + * Prints the arguments to a status file + * Works like printf (see vfrpintf) + */ +void erts_run_erl_log_status(const char *format,...) +{ + va_list args; + time_t now; + + if (stdstatus == NULL) + stdstatus = fopen(statusfile, "w"); + if (stdstatus == NULL) + return; + now = time(NULL); + fprintf(stdstatus, "run_erl [%d] %s", + (int)getpid(), + ctime(&now)); + va_start(args, format); + vfprintf(stdstatus, format, args); + va_end(args); + fflush(stdstatus); + return; +} + +/* error_logf() + * Prints the arguments to stderr or syslog + * Works like printf (see vfprintf) + */ +void erts_run_erl_log_error(int priority, int line, const char *format, ...) +{ + va_list args; + va_start(args, format); + +#ifdef HAVE_SYSLOG_H + if (run_daemon) { + vsyslog(priority,format,args); + } + else +#endif + { + time_t now = time(NULL); + fprintf(stderr, "run_erl:%d [%d] %s", line, + (int)getpid(), + ctime(&now)); + vfprintf(stderr, format, args); + } + va_end(args); +} + +/* erts_run_erl_log_write() + * Writes a message to lfd. If the current log file is full, + * a new log file is opened. + */ +int erts_run_erl_log_write(char* buf, size_t len) +{ + int size; + ssize_t res; + /* Decide if new logfile needed, and open if so */ + + size = lseek(lfd,0,SEEK_END); + if(size+len > log_maxsize) { + int res; + do { + res = close(lfd); + } while (res < 0 && errno == EINTR); + log_num = next_log(log_num); + lfd = open_log(log_num, O_RDWR|O_CREAT|O_TRUNC|O_SYNC); + } + + /* Write to log file */ + + if ((res = erts_run_erl_write_all(lfd, buf, len)) < 0) { + erts_run_erl_log_status("Error in writing to log.\n"); + } + +#if USE_FSYNC + fsync(lfd); +#endif + return res; +} + +int erts_run_erl_log_activity(int timeout,time_t now,time_t last_activity) { + char log_alive_buffer[ALIVE_BUFFSIZ+1]; + char buf[BUFSIZ]; + + if (timeout || now - last_activity > log_activity_minutes*60) { + /* Either a time out: 15 minutes without action, */ + /* or something is coming in right now, but it's a long time */ + /* since last time, so let's write a time stamp this message */ + struct tm *tmptr; + if (log_alive_in_gmt) { + tmptr = gmtime(&now); + } else { + tmptr = localtime(&now); + } + if (!strftime(log_alive_buffer, ALIVE_BUFFSIZ, log_alive_format, + tmptr)) { + strn_cpy(log_alive_buffer, sizeof(log_alive_buffer), + "(could not format time in 256 positions " + "with current format string.)"); + } + log_alive_buffer[ALIVE_BUFFSIZ] = '\0'; + + sn_printf(buf, sizeof(buf), "\n===== %s%s\n", + timeout?"ALIVE ":"", log_alive_buffer); + return erts_run_erl_log_write(buf, strlen(buf)); + } + return 0; +} + +int erts_run_erl_log_open() { + + log_num = find_next_log_num(); + lfd = open_log(log_num, O_RDWR|O_APPEND|O_CREAT|O_SYNC); + return 0; +} + +int erts_run_erl_log_init(int daemon, char* logdir) { + char *p; + + /* Get values for LOG file handling from the environment */ + if ((p = getenv_int("RUN_ERL_LOG_ALIVE_MINUTES"))) { + erts_run_erl_log_alive_minutes = atoi(p); + if (!erts_run_erl_log_alive_minutes) { + ERROR1(LOG_ERR,"Minimum value for RUN_ERL_LOG_ALIVE_MINUTES is 1 " + "(current value is %s)",p); + } + log_activity_minutes = erts_run_erl_log_alive_minutes / 3; + if (!log_activity_minutes) { + ++log_activity_minutes; + } + } + if ((p = getenv_int( + "RUN_ERL_LOG_ACTIVITY_MINUTES"))) { + log_activity_minutes = atoi(p); + if (!log_activity_minutes) { + ERROR1(LOG_ERR,"Minimum value for RUN_ERL_LOG_ACTIVITY_MINUTES is 1 " + "(current value is %s)",p); + } + } + if ((p = getenv_int("RUN_ERL_LOG_ALIVE_FORMAT"))) { + if (strlen(p) > ALIVE_BUFFSIZ) { + ERROR1(LOG_ERR, "RUN_ERL_LOG_ALIVE_FORMAT can contain a maximum of " + "%d characters", ALIVE_BUFFSIZ); + } + strn_cpy(log_alive_format, sizeof(log_alive_format), p); + } else { + strn_cpy(log_alive_format, sizeof(log_alive_format), + DEFAULT_LOG_ALIVE_FORMAT); + } + if ((p = getenv_int("RUN_ERL_LOG_ALIVE_IN_UTC")) + && strcmp(p,"0")) { + ++log_alive_in_gmt; + } + if ((p = getenv_int("RUN_ERL_LOG_GENERATIONS"))) { + log_generations = atoi(p); + if (log_generations < LOG_MIN_GENERATIONS) + ERROR1(LOG_ERR,"Minimum RUN_ERL_LOG_GENERATIONS is %d", + LOG_MIN_GENERATIONS); + if (log_generations > LOG_MAX_GENERATIONS) + ERROR1(LOG_ERR,"Maximum RUN_ERL_LOG_GENERATIONS is %d", + LOG_MAX_GENERATIONS); + } + + if ((p = getenv_int("RUN_ERL_LOG_MAXSIZE"))) { + log_maxsize = atoi(p); + if (log_maxsize < LOG_MIN_MAXSIZE) + ERROR1(LOG_ERR,"Minimum RUN_ERL_LOG_MAXSIZE is %d", LOG_MIN_MAXSIZE); + } + + run_daemon = daemon; + + strn_cpy(log_dir, sizeof(log_dir), logdir); + strn_cpy(statusfile, sizeof(statusfile), log_dir); + strn_cat(statusfile, sizeof(statusfile), STATUSFILENAME); + + return 0; +} + +/* create_fifo() + * Creates a new fifo with the given name and permission. + */ +static int create_fifo(char *name, int perm) +{ + if ((mkfifo(name, perm) < 0) && (errno != EEXIST)) + return -1; + return 0; +} + +/* + * w- and r_pipename have to be pre-allocated of atleast FILENAME_MAX size + */ +int erts_run_erl_open_fifo(char *pipename,char *w_pipename,char *r_pipename) { + int calculated_pipename = 0; + int highest_pipe_num = 0; + int fd; + + /* + * Create FIFOs and open them + */ + + if(*pipename && pipename[strlen(pipename)-1] == '/') { + /* The user wishes us to find a unique pipe name in the specified */ + /* directory */ + DIR *dirp; + struct dirent *direntp; + + calculated_pipename = 1; + dirp = opendir(pipename); + if(!dirp) { + ERRNO_ERR1(LOG_ERR,"Can't access pipe directory '%s'.", pipename); + return 1; + } + + /* Check the directory for existing pipes */ + + while((direntp=readdir(dirp)) != NULL) { + if(strncmp(direntp->d_name,PIPE_STUBNAME,PIPE_STUBLEN)==0) { + int num = atoi(direntp->d_name+PIPE_STUBLEN+1); + if(num > highest_pipe_num) + highest_pipe_num = num; + } + } + closedir(dirp); + strn_catf(pipename, BUFSIZ, "%s.%d", + PIPE_STUBNAME, highest_pipe_num+1); + } /* if */ + + for(;;) { + /* write FIFO - is read FIFO for `to_erl' program */ + strn_cpy(w_pipename, BUFSIZ, pipename); + strn_cat(w_pipename, BUFSIZ, ".r"); + if (create_fifo(w_pipename, PERM) < 0) { + ERRNO_ERR1(LOG_ERR,"Cannot create FIFO %s for writing.", + w_pipename); + return 1; + } + + /* read FIFO - is write FIFO for `to_erl' program */ + strn_cpy(r_pipename, BUFSIZ, pipename); + strn_cat(r_pipename, BUFSIZ, ".w"); + + /* Check that nobody is running run_erl already */ + if ((fd = sf_open(r_pipename, O_WRONLY|DONT_BLOCK_PLEASE, 0)) >= 0) { + /* Open as client succeeded -- run_erl is already running! */ + sf_close(fd); + if (calculated_pipename) { + ++highest_pipe_num; + strn_catf(pipename, BUFSIZ, "%s.%d", + PIPE_STUBNAME, highest_pipe_num+1); + continue; + } + fprintf(stderr, "Erlang already running on pipe %s.\n", pipename); + return 1; + } + if (create_fifo(r_pipename, PERM) < 0) { + ERRNO_ERR1(LOG_ERR,"Cannot create FIFO %s for reading.", + r_pipename); + return 1; + } + break; + } + return 0; +} + +/* Extract any control sequences that are ment only for run_erl + * and should not be forwarded to the pty. + */ +int erts_run_erl_extract_ctrl_seq(char* buf, int len) +{ + static const char prefix[] = "\033_"; + static const char suffix[] = "\033\\"; + char* bufend = buf + len; + char* start = buf; + char* command; + char* end; + + for (;;) { + start = find_str(start, bufend-start, prefix); + if (!start) break; + + command = start + strlen(prefix); + end = find_str(command, bufend-command, suffix); + if (end) { + unsigned col, row; + if (sscanf(command,"version=%u", &PROTOCOL_VER)==1) { + /*fprintf(stderr,"to_erl v%u\n", protocol_ver);*/ + } + else if (sscanf(command,"winsize=%u,%u", &col, &row)==2) { +#ifdef TIOCSWINSZ + struct winsize ws; + ws.ws_col = col; + ws.ws_row = row; + if (ioctl(MFD, TIOCSWINSZ, &ws) < 0) { + ERRNO_ERR0(LOG_ERR,"Failed to set window size"); + } +#endif + } + else { + ERROR2(LOG_ERR, "Ignoring unknown ctrl command '%.*s'\n", + (int)(end-command), command); + } + + /* Remove ctrl sequence from buf */ + end += strlen(suffix); + memmove(start, end, bufend-end); + bufend -= end - start; + } + else { + ERROR2(LOG_ERR, "Missing suffix in ctrl sequence '%.*s'\n", + (int)(bufend-start), start); + break; + } + } + return bufend - buf; +} diff --git a/erts/etc/common/run_erl_common.h b/erts/etc/common/run_erl_common.h new file mode 100644 index 0000000000..dca1af93f2 --- /dev/null +++ b/erts/etc/common/run_erl_common.h @@ -0,0 +1,95 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2013. All Rights Reserved. + * + * 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 online 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. + * + * %CopyrightEnd% + */ +/* + * Functions that are common to both OSE and unix implementations of run_erl + */ +#ifndef ERL_RUN_ERL_LOG_H +#define ERL_RUN_ERL_LOG_H + +#include +#include +#include + +#include "run_erl_vsn.h" + +/* Log handling */ +int erts_run_erl_log_init(int run_daemon, char* logdir); +int erts_run_erl_log_open(void); +int erts_run_erl_log_close(void); +int erts_run_erl_log_write(char *buff, size_t len); +int erts_run_erl_log_activity(int timeout, time_t now, time_t last_activity); + +void erts_run_erl_log_status(const char *format,...); +void erts_run_erl_log_error(int priority, int line, const char *format,...); + +int erts_run_erl_open_fifo(char *pipename,char *w_pipename,char *r_pipename); +int erts_run_erl_log_alive_minutes(void); +int erts_run_erl_extract_ctrl_seq(char* buf, int len); + +/* File operations */ +ssize_t sf_read(int fd, void *buffer, size_t len); +ssize_t sf_write(int fd, const void *buffer, size_t len); +int sf_open(const char *path, int type, mode_t mode); +int sf_close(int fd); +int erts_run_erl_write_all(int fd, const char* buf, int len); +char *simple_basename(char *path); + +#ifndef LOG_ERR +#define LOG_ERR NULL +#endif + +#define ERROR0(Prio,Format) erts_run_erl_log_error(Prio,__LINE__,Format"\n") +#define ERROR1(Prio,Format,A1) erts_run_erl_log_error(Prio,__LINE__,Format"\n",A1) +#define ERROR2(Prio,Format,A1,A2) erts_run_erl_log_error(Prio,__LINE__,Format"\n",A1,A2) + +#ifdef HAVE_STRERROR +# define ADD_ERRNO(Format) "errno=%d '%s'\n"Format"\n",errno,strerror(errno) +#else +# define ADD_ERRNO(Format) "errno=%d\n"Format"\n",errno +#endif +#define ERRNO_ERR0(Prio,Format) erts_run_erl_log_error(Prio,__LINE__,ADD_ERRNO(Format)) +#define ERRNO_ERR1(Prio,Format,A1) erts_run_erl_log_error(Prio,__LINE__,ADD_ERRNO(Format),A1) +#define ERRNO_ERR2(Prio,Format,A1,A2) erts_run_erl_log_error(Prio,__LINE__,ADD_ERRNO(Format),A1,A2) + +/* defined in run_common.c */ +extern int erts_run_erl_log_alive_minutes; + +#define RUN_ERL_USAGE \ + "%s (pipe_name|pipe_dir/) log_dir \"command [parameters ...]\"" \ + "\n\nDESCRIPTION:\n" \ + "You may also set the environment variables RUN_ERL_LOG_GENERATIONS\n" \ + "and RUN_ERL_LOG_MAXSIZE to the number of log files to use and the\n" \ + "size of the log file when to switch to the next log file\n" + +#ifndef FILENAME_MAX +#define FILENAME_MAX 250 +#endif + +#define FILENAME_BUFSIZ FILENAME_MAX + +#ifdef O_NONBLOCK +# define DONT_BLOCK_PLEASE O_NONBLOCK +#else +# define DONT_BLOCK_PLEASE O_NDELAY +# ifndef EAGAIN +# define EAGAIN -3898734 +# endif +#endif + +#endif diff --git a/erts/etc/common/run_erl_vsn.h b/erts/etc/common/run_erl_vsn.h new file mode 100644 index 0000000000..f6ac753bde --- /dev/null +++ b/erts/etc/common/run_erl_vsn.h @@ -0,0 +1,29 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2008-2009. All Rights Reserved. + * + * 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 online 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. + * + * %CopyrightEnd% + */ + +/* + * The protocol version number used between to_erl and run_erl. + */ +#define RUN_ERL_HI_VER 1 /* My preferred protocol version */ +#define RUN_ERL_LO_VER 0 /* The lowest version I accept to talk with */ + +/* Version history: + * 0: Older, without version handshake + * 1: R12B-3, version handshake + window size ctrl + */ diff --git a/erts/etc/common/safe_string.c b/erts/etc/common/safe_string.c new file mode 100644 index 0000000000..b2f8814408 --- /dev/null +++ b/erts/etc/common/safe_string.c @@ -0,0 +1,122 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2008-2009. All Rights Reserved. + * + * 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 online 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. + * + * %CopyrightEnd% + */ +/* + * Module: safe_string.c + * + * This is a bunch of generic string operation + * that are safe regarding buffer overflow. + * + * All string functions terminate the process with an error message + * on buffer overflow. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include "safe_string.h" +#include +#include +#include +#include + + +static void string_overflow_handler(const char* format, ...) +{ + va_list args; + va_start(args, format); + vfprintf(stderr,format,args); + va_end(args); + exit(1); +} + +int vsn_printf(char* dst, size_t size, const char* format, va_list args) +{ + int ret = vsnprintf(dst, size, format, args); + if (ret >= size || ret < 0) { + string_overflow_handler("Buffer truncated '%s'\n",dst); + } + return ret; +} + +int sn_printf(char* dst, size_t size, const char* format, ...) +{ + va_list args; + int ret; + va_start(args, format); + ret = vsn_printf(dst,size,format,args); + va_end(args); + return ret; +} + +int strn_cpy(char* dst, size_t size, const char* src) +{ + return sn_printf(dst,size,"%s",src); +} + +int strn_cat(char* dst, size_t size, const char* src) +{ + return strn_catf(dst,size,"%s",src); +} + +int strn_catf(char* dst, size_t size, const char* format, ...) +{ + int ret; + va_list args; +#ifdef _GNU_SOURCE + int len = strnlen(dst,size); +#else + int len = strlen(dst); +#endif + + if (len >= size) { + string_overflow_handler("Buffer already overflowed '%.*s'\n", + size, dst); + } + va_start(args, format); + ret = vsn_printf(dst+len, size-len, format, args); + va_end(args); + return len+ret; +} + +char* find_str(const char* haystack, int hsize, const char* needle) +{ + int i = 0; + int nsize = strlen(needle); + hsize -= nsize - 1; + for (i=0; i dest) { + for (i=0; i=0; i--) ((char*)dest)[i] = ((char*)src)[i]; + } + return dest; +} +#endif /* HAVE_MEMMOVE */ diff --git a/erts/etc/common/safe_string.h b/erts/etc/common/safe_string.h new file mode 100644 index 0000000000..ff063fe641 --- /dev/null +++ b/erts/etc/common/safe_string.h @@ -0,0 +1,64 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2008-2009. All Rights Reserved. + * + * 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 online 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. + * + * %CopyrightEnd% + */ +/* + * Module: safe_string.h + * + * This is an interface to a bunch of generic string operation + * that are safe regarding buffer overflow. + * + * All string functions terminate the process with an error message + * on buffer overflow. + */ + +#include +#include + +/* Like vsnprintf() + */ +int vsn_printf(char* dst, size_t size, const char* format, va_list args); + +/* Like snprintf() + */ +int sn_printf(char* dst, size_t size, const char* format, ...); + +/* Like strncpy() + * Returns length of copied string. + */ +int strn_cpy(char* dst, size_t size, const char* src); + +/* Almost like strncat() + * size is sizeof entire dst buffer. + * Returns length of resulting string. + */ +int strn_cat(char* dst, size_t size, const char* src); + +/* Combination of strncat() and snprintf() + * size is sizeof entire dst buffer. + * Returns length of resulting string. + */ +int strn_catf(char* dst, size_t size, const char* format, ...); + +/* Simular to strstr() but search size bytes of haystack + * without regard to '\0' characters. + */ +char* find_str(const char* haystack, int size, const char* needle); + +#ifndef HAVE_MEMMOVE +void* memmove(void *dest, const void *src, size_t n); +#endif diff --git a/erts/etc/common/to_erl_common.c b/erts/etc/common/to_erl_common.c new file mode 100644 index 0000000000..4c38877277 --- /dev/null +++ b/erts/etc/common/to_erl_common.c @@ -0,0 +1,607 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 1996-2013. All Rights Reserved. + * + * 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 online 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. + * + * %CopyrightEnd% + */ +/* + * Module: to_erl.c + * + * This module implements a process that opens two specified FIFOs, one + * for reading and one for writing; reads from its stdin, and writes what + * it has read to the write FIF0; reads from the read FIFO, and writes to + * its stdout. + * + ________ _________ + | |--<-- pipe.r (fifo1) --<--| | + | to_erl | | run_erl | (parent) + |________|-->-- pipe.w (fifo2) -->--|_________| + ^ master pty + | + | slave pty + ____V____ + | | + | "erl" | (child) + |_________| + */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_IOCTL_H +# include +#endif + +#include "to_erl_common.h" +#include "run_erl_vsn.h" +#include "safe_string.h" /* strn_cpy, strn_catf, sn_printf, etc. */ + +#if defined(O_NONBLOCK) +# define DONT_BLOCK_PLEASE O_NONBLOCK +#else +# define DONT_BLOCK_PLEASE O_NDELAY +# if !defined(EAGAIN) +# define EAGAIN -3898734 +# endif +#endif + +#ifdef HAVE_STRERROR +# define STRERROR(x) strerror(x) +#else +# define STRERROR(x) "" +#endif + +#define noDEBUG + +#define PIPE_DIR "/tmp/" +#define PIPE_STUBNAME "erlang.pipe" +#define PIPE_STUBLEN strlen(PIPE_STUBNAME) + +#ifdef DEBUG +#define STATUS(s) { fprintf(stderr, (s)); fflush(stderr); } +#else +#define STATUS(s) +#endif + +#ifndef FILENAME_MAX +#define FILENAME_MAX 250 +#endif + +static struct termios tty_smode, tty_rmode; +static int tty_eof = 0; +static int recv_sig = 0; +static int protocol_ver = RUN_ERL_LO_VER; /* assume lowest to begin with */ + +static int write_all(int fd, const char* buf, int len); +static int window_size_seq(char* buf, size_t bufsz); +static int version_handshake(char* buf, int len, int wfd); +#ifdef DEBUG +static void show_terminal_settings(struct termios *); +#endif + +static void handle_ctrlc(int sig) +{ + /* Reinstall the handler, and signal break flag */ + signal(SIGINT,handle_ctrlc); + recv_sig = SIGINT; +} + +static void handle_sigwinch(int sig) +{ + recv_sig = SIGWINCH; +} + +static void usage(char *pname) +{ + fprintf(stderr, "Usage: "); + fprintf(stderr,TO_ERL_USAGE,pname); +} + +int to_erl(int argc, char **argv) +{ + char FIFO1[FILENAME_MAX], FIFO2[FILENAME_MAX]; + int i, len, wfd, rfd; + fd_set readfds; + char buf[BUFSIZ]; + char pipename[FILENAME_MAX]; + int pipeIx = 1; + int force_lock = 0; + int got_some = 0; + + if (argc >= 2 && argv[1][0]=='-') { + switch (argv[1][1]) { + case 'h': + usage(argv[0]); + exit(1); + case 'F': + force_lock = 1; + break; + default: + fprintf(stderr,"Invalid option '%s'\n",argv[1]); + exit(1); + } + pipeIx = 2; + } + +#ifdef DEBUG + fprintf(stderr, "%s: pid is : %d\n", argv[0], (int)getpid()); +#endif + + strn_cpy(pipename, sizeof(pipename), + (argv[pipeIx] ? argv[pipeIx] : PIPE_DIR)); + + if(*pipename && pipename[strlen(pipename)-1] == '/') { + /* The user wishes us to find a pipe name in the specified */ + /* directory */ + int highest_pipe_num = 0; + DIR *dirp; + struct dirent *direntp; + + dirp = opendir(pipename); + if(!dirp) { + fprintf(stderr, "Can't access pipe directory %s: %s\n", pipename, strerror(errno)); + exit(1); + } + + /* Check the directory for existing pipes */ + + while((direntp=readdir(dirp)) != NULL) { + if(strncmp(direntp->d_name,PIPE_STUBNAME,PIPE_STUBLEN)==0) { + int num = atoi(direntp->d_name+PIPE_STUBLEN+1); + if(num > highest_pipe_num) + highest_pipe_num = num; + } + } + closedir(dirp); + strn_catf(pipename, sizeof(pipename), (highest_pipe_num?"%s.%d":"%s"), + PIPE_STUBNAME, highest_pipe_num); + } /* if */ + + /* read FIFO */ + sn_printf(FIFO1,sizeof(FIFO1),"%s.r",pipename); + /* write FIFO */ + sn_printf(FIFO2,sizeof(FIFO2),"%s.w",pipename); + + /* Check that nobody is running to_erl on this pipe already */ + if ((wfd = open (FIFO1, O_WRONLY|DONT_BLOCK_PLEASE, 0)) >= 0) { + /* Open as server succeeded -- to_erl is already running! */ + close(wfd); + fprintf(stderr, "Another to_erl process already attached to pipe " + "%s.\n", pipename); + if (force_lock) { + fprintf(stderr, "But we proceed anyway by force (-F).\n"); + } + else { + exit(1); + } + } + + if ((rfd = open (FIFO1, O_RDONLY|DONT_BLOCK_PLEASE, 0)) < 0) { +#ifdef DEBUG + fprintf(stderr, "Could not open FIFO %s for reading.\n", FIFO1); +#endif + fprintf(stderr, "No running Erlang on pipe %s: %s\n", pipename, strerror(errno)); + exit(1); + } +#ifdef DEBUG + fprintf(stderr, "to_erl: %s opened for reading\n", FIFO1); +#endif + + if ((wfd = open (FIFO2, O_WRONLY|DONT_BLOCK_PLEASE, 0)) < 0) { +#ifdef DEBUG + fprintf(stderr, "Could not open FIFO %s for writing.\n", FIFO2); +#endif + fprintf(stderr, "No running Erlang on pipe %s: %s\n", pipename, strerror(errno)); + close(rfd); + exit(1); + } +#ifdef DEBUG + fprintf(stderr, "to_erl: %s opened for writing\n", FIFO2); +#endif + + fprintf(stderr, "Attaching to %s (^D to exit)\n\n", pipename); + + /* Set break handler to our handler */ + signal(SIGINT,handle_ctrlc); + + /* + * Save the current state of the terminal, and set raw mode. + */ + if (tcgetattr(0, &tty_rmode) , 0) { + fprintf(stderr, "Cannot get terminals current mode\n"); + exit(-1); + } + tty_smode = tty_rmode; + tty_eof = '\004'; /* Ctrl+D to exit */ +#ifdef DEBUG + show_terminal_settings(&tty_rmode); +#endif + tty_smode.c_iflag = + 1*BRKINT |/*Signal interrupt on break.*/ + 1*IGNPAR |/*Ignore characters with parity errors.*/ + 1*ISTRIP |/*Strip character.*/ + 0; + +#if 0 +0*IGNBRK |/*Ignore break condition.*/ +0*PARMRK |/*Mark parity errors.*/ +0*INPCK |/*Enable input parity check.*/ +0*INLCR |/*Map NL to CR on input.*/ +0*IGNCR |/*Ignore CR.*/ +0*ICRNL |/*Map CR to NL on input.*/ +0*IUCLC |/*Map upper-case to lower-case on input.*/ +0*IXON |/*Enable start/stop output control.*/ +0*IXANY |/*Enable any character to restart output.*/ +0*IXOFF |/*Enable start/stop input control.*/ +0*IMAXBEL|/*Echo BEL on input line too long.*/ +#endif + + tty_smode.c_oflag = + 1*OPOST |/*Post-process output.*/ + 1*ONLCR |/*Map NL to CR-NL on output.*/ +#ifdef XTABS + 1*XTABS |/*Expand tabs to spaces. (Linux)*/ +#endif +#ifdef OXTABS + 1*OXTABS |/*Expand tabs to spaces. (FreeBSD)*/ +#endif +#ifdef NL0 + 1*NL0 |/*Select newline delays*/ +#endif +#ifdef CR0 + 1*CR0 |/*Select carriage-return delays*/ +#endif +#ifdef TAB0 + 1*TAB0 |/*Select horizontal tab delays*/ +#endif +#ifdef BS0 + 1*BS0 |/*Select backspace delays*/ +#endif +#ifdef VT0 + 1*VT0 |/*Select vertical tab delays*/ +#endif +#ifdef FF0 + 1*FF0 |/*Select form feed delays*/ +#endif + 0; + +#if 0 +0*OLCUC |/*Map lower case to upper on output.*/ +0*OCRNL |/*Map CR to NL on output.*/ +0*ONOCR |/*No CR output at column 0.*/ +0*ONLRET |/*NL performs CR function.*/ +0*OFILL |/*Use fill characters for delay.*/ +0*OFDEL |/*Fill is DEL, else NULL.*/ +0*NL1 | +0*CR1 | +0*CR2 | +0*CR3 | +0*TAB1 | +0*TAB2 | +0*TAB3 |/*Expand tabs to spaces.*/ +0*BS1 | +0*VT1 | +0*FF1 | +#endif + + /* JALI: removed setting the tty_smode.c_cflag flags, since this is not */ + /* advisable if this is a *real* terminal, such as the console. In fact */ + /* this may hang the entire machine, deep, deep down (signalling break */ + /* or toggling the abort switch doesn't help) */ + + tty_smode.c_lflag = + 0; + +#if 0 +0*ISIG |/*Enable signals.*/ +0*ICANON |/*Canonical input (erase and kill processing).*/ +0*XCASE |/*Canonical upper/lower presentation.*/ +0*ECHO |/*Enable echo.*/ +0*ECHOE |/*Echo erase character as BS-SP-BS.*/ +0*ECHOK |/*Echo NL after kill character.*/ +0*ECHONL |/*Echo NL.*/ +0*NOFLSH |/*Disable flush after interrupt or quit.*/ +0*TOSTOP |/*Send SIGTTOU for background output.*/ +0*ECHOCTL|/*Echo control characters as ^char, delete as ^?.*/ +0*ECHOPRT|/*Echo erase character as character erased.*/ +0*ECHOKE |/*BS-SP-BS erase entire line on line kill.*/ +0*FLUSHO |/*Output is being flushed.*/ +0*PENDIN |/*Retype pending input at next read or input character.*/ +0*IEXTEN |/*Enable extended (implementation-defined) functions.*/ +#endif + + tty_smode.c_cc[VMIN] =0;/* Note that VMIN is the same as VEOF! */ + tty_smode.c_cc[VTIME] =0;/* Note that VTIME is the same as VEOL! */ + tty_smode.c_cc[VINTR] =3; + + tcsetattr(0, TCSADRAIN, &tty_smode); + +#ifdef DEBUG + show_terminal_settings(&tty_smode); +#endif + /* + * "Write a ^L to the FIFO which causes the other end to redisplay + * the input line." + * This does not seem to work as was intended in old comment above. + * However, this control character is now (R12B-3) used by run_erl + * to trigger the version handshaking between to_erl and run_erl + * at the start of every new to_erl-session. + */ + + if (write(wfd, "\014", 1) < 0) { + fprintf(stderr, "Error in writing ^L to FIFO.\n"); + } + + /* + * read and write + */ + while (1) { + FD_ZERO(&readfds); + FD_SET(0, &readfds); + FD_SET(rfd, &readfds); + if (select(rfd + 1, &readfds, NULL, NULL, NULL) < 0) { + if (recv_sig) { + FD_ZERO(&readfds); + } + else { + fprintf(stderr, "Error in select.\n"); + break; + } + } + len = 0; + + /* + * Read from terminal and write to FIFO + */ + if (recv_sig) { + switch (recv_sig) { + case SIGINT: + fprintf(stderr, "[Break]\n\r"); + buf[0] = '\003'; + len = 1; + break; + case SIGWINCH: + len = window_size_seq(buf,sizeof(buf)); + break; + default: + fprintf(stderr,"Unexpected signal: %u\n",recv_sig); + } + recv_sig = 0; + } + else if (FD_ISSET(0, &readfds)) { + len = read(0, buf, sizeof(buf)); + if (len <= 0) { + close(rfd); + close(wfd); + if (len < 0) { + fprintf(stderr, "Error in reading from stdin.\n"); + } else { + fprintf(stderr, "[EOF]\n\r"); + } + break; + } + /* check if there is an eof character in input */ + for (i = 0; i < len && buf[i] != tty_eof; i++); + if (buf[i] == tty_eof) { + fprintf(stderr, "[Quit]\n\r"); + break; + } + } + + if (len) { +#ifdef DEBUG + if(write(1, buf, len)); +#endif + if (write_all(wfd, buf, len) != len) { + fprintf(stderr, "Error in writing to FIFO.\n"); + close(rfd); + close(wfd); + break; + } + STATUS("\" OK\r\n"); + } + + /* + * Read from FIFO, write to terminal. + */ + if (FD_ISSET(rfd, &readfds)) { + STATUS("FIFO read: "); + len = read(rfd, buf, BUFSIZ); + if (len < 0 && errno == EAGAIN) { + /* + * No data this time, but the writing end of the FIFO is still open. + * Do nothing. + */ + ; + } else if (len <= 0) { + /* + * Either an error or end of file. In either case, break out + * of the loop. + */ + close(rfd); + close(wfd); + if (len < 0) { + fprintf(stderr, "Error in reading from FIFO.\n"); + } else + fprintf(stderr, "[End]\n\r"); + break; + } else { + if (!got_some) { + if ((len=version_handshake(buf,len,wfd)) < 0) { + close(rfd); + close(wfd); + break; + } + if (protocol_ver >= 1) { + /* Tell run_erl size of terminal window */ + signal(SIGWINCH, handle_sigwinch); + raise(SIGWINCH); + } + got_some = 1; + } + + /* + * We successfully read at least one character. Write what we got. + */ + STATUS("Terminal write: \""); + if (write_all(1, buf, len) != len) { + fprintf(stderr, "Error in writing to terminal.\n"); + close(rfd); + close(wfd); + break; + } + STATUS("\" OK\r\n"); + } + } + } + + /* + * Reset terminal characterstics + * XXX + */ + tcsetattr(0, TCSADRAIN, &tty_rmode); + return 0; +} + +/* Call write() until entire buffer has been written or error. + * Return len or -1. + */ +static int write_all(int fd, const char* buf, int len) +{ + int left = len; + int written; + while (left) { + written = write(fd,buf,left); + if (written < 0) { + return -1; + } + left -= written; + buf += written; + } + return len; +} + +static int window_size_seq(char* buf, size_t bufsz) +{ +#ifdef TIOCGWINSZ + struct winsize ws; + static const char prefix[] = "\033_"; + static const char suffix[] = "\033\\"; + /* This Esc sequence is called "Application Program Command" + and seems suitable to use for our own customized stuff. */ + + if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == 0) { + int len = sn_printf(buf, bufsz, "%swinsize=%u,%u%s", + prefix, ws.ws_col, ws.ws_row, suffix); + return len; + } +#endif /* TIOCGWINSZ */ + return 0; +} + +/* to_erl run_erl + * | | + * |---------- '\014' -------->| (session start) + * | | + * |<---- "[run_erl v1-0]" ----| (version interval) + * | | + * |--- Esc_"version=1"Esc\ -->| (common version) + * | | + */ +static int version_handshake(char* buf, int len, int wfd) +{ + unsigned re_high=0, re_low; + char *end = find_str(buf,len,"]\n"); + + if (end && sscanf(buf,"[run_erl v%u-%u",&re_high,&re_low)==2) { + char wbuf[30]; + int wlen; + + if (re_low > RUN_ERL_HI_VER || re_high < RUN_ERL_LO_VER) { + fprintf(stderr,"Incompatible versions: to_erl=v%u-%u run_erl=v%u-%u\n", + RUN_ERL_HI_VER, RUN_ERL_LO_VER, re_high, re_low); + return -1; + } + /* Choose highest common version */ + protocol_ver = re_high < RUN_ERL_HI_VER ? re_high : RUN_ERL_HI_VER; + + wlen = sn_printf(wbuf, sizeof(wbuf), "\033_version=%u\033\\", + protocol_ver); + if (write_all(wfd, wbuf, wlen) < 0) { + fprintf(stderr,"Failed to send version handshake\n"); + return -1; + } + end += 2; + len -= (end-buf); + memmove(buf,end,len); + + } + else { /* we assume old run_erl without version handshake */ + protocol_ver = 0; + } + + if (re_high != RUN_ERL_HI_VER) { + fprintf(stderr,"run_erl has different version, " + "using common protocol level %u\n", protocol_ver); + } + + return len; +} + + +#ifdef DEBUG +#define S(x) ((x) > 0 ? 1 : 0) + +static void show_terminal_settings(struct termios *t) +{ + fprintf(stderr,"c_iflag:\n"); + fprintf(stderr,"Signal interrupt on break: BRKINT %d\n", S(t->c_iflag & BRKINT)); + fprintf(stderr,"Map CR to NL on input: ICRNL %d\n", S(t->c_iflag & ICRNL)); + fprintf(stderr,"Ignore break condition: IGNBRK %d\n", S(t->c_iflag & IGNBRK)); + fprintf(stderr,"Ignore CR: IGNCR %d\n", S(t->c_iflag & IGNCR)); + fprintf(stderr,"Ignore char with par. err's: IGNPAR %d\n", S(t->c_iflag & IGNPAR)); + fprintf(stderr,"Map NL to CR on input: INLCR %d\n", S(t->c_iflag & INLCR)); + fprintf(stderr,"Enable input parity check: INPCK %d\n", S(t->c_iflag & INPCK)); + fprintf(stderr,"Strip character ISTRIP %d\n", S(t->c_iflag & ISTRIP)); + fprintf(stderr,"Enable start/stop input ctrl IXOFF %d\n", S(t->c_iflag & IXOFF)); + fprintf(stderr,"ditto output ctrl IXON %d\n", S(t->c_iflag & IXON)); + fprintf(stderr,"Mark parity errors PARMRK %d\n", S(t->c_iflag & PARMRK)); + fprintf(stderr,"\n"); + fprintf(stderr,"c_oflag:\n"); + fprintf(stderr,"Perform output processing OPOST %d\n", S(t->c_oflag & OPOST)); + fprintf(stderr,"\n"); + fprintf(stderr,"c_cflag:\n"); + fprintf(stderr,"Ignore modem status lines CLOCAL %d\n", S(t->c_cflag & CLOCAL)); + fprintf(stderr,"\n"); + fprintf(stderr,"c_local:\n"); + fprintf(stderr,"Enable echo ECHO %d\n", S(t->c_lflag & ECHO)); + fprintf(stderr,"\n"); + fprintf(stderr,"c_cc:\n"); + fprintf(stderr,"c_cc[VEOF] %d\n", t->c_cc[VEOF]); +} +#endif diff --git a/erts/etc/common/to_erl_common.h b/erts/etc/common/to_erl_common.h new file mode 100644 index 0000000000..9967db94b8 --- /dev/null +++ b/erts/etc/common/to_erl_common.h @@ -0,0 +1,28 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2013. All Rights Reserved. + * + * 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 online 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. + * + * %CopyrightEnd% + */ +#ifndef ERL_TO_ERL_H +#define ERL_TO_ERL_H + +#define TO_ERL_USAGE "to_erl [-h|-F] %s\n" \ + "\t-h\tThis help text.\n" \ + "\t-f\tForce connection even though pipe is locked by other to_erl process." + +int to_erl(int argc, char **argv); + +#endif -- cgit v1.2.3 From 5c299e355e05a464215e49cfd95f62b5194de609 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Wed, 8 Jan 2014 11:35:29 +0100 Subject: ose: Port run_erl and to_erl --- erts/etc/common/Makefile.in | 64 +++++++++++++++----- erts/etc/common/run_erl_common.c | 38 +++++++++--- erts/etc/common/run_erl_common.h | 4 ++ erts/etc/common/to_erl_common.c | 128 +++++++++++++++++++++++++++++++++++---- 4 files changed, 200 insertions(+), 34 deletions(-) (limited to 'erts/etc/common') diff --git a/erts/etc/common/Makefile.in b/erts/etc/common/Makefile.in index f5df53ec01..5be0942952 100644 --- a/erts/etc/common/Makefile.in +++ b/erts/etc/common/Makefile.in @@ -85,6 +85,16 @@ UXETC = ../unix OSEETC = ../ose WINETC = ../win32 +ifeq ($(TARGET), win32) +ETC = $(WINETC) +else +ifeq ($(findstring ose,$(TARGET)),ose) +ETC = $(OSEETC) +else +ETC = $(UXETC) +endif +endif + ifeq ($(TARGET), win32) ERLEXEC = erlexec.dll else @@ -172,7 +182,7 @@ ENTRY_OBJ= ERLSRV_OBJECTS= MC_OUTPUTS= INET_GETHOST = -INSTALL_EMBEDDED_PROGS = +INSTALL_EMBEDDED_PROGS = $(BINDIR)/run_erl_lm INSTALL_EMBEDDED_DATA = INSTALL_TOP = Install INSTALL_TOP_BIN = @@ -183,7 +193,7 @@ INSTALL_LIBS = INSTALL_OBJS = INSTALL_INCLUDES = TEXTFILES = Install erl.src -INSTALL_PROGS = +INSTALL_PROGS = $(INSTALL_EMBEDDED_PROGS) else # UNIX (!win32 && !ose) ENTRY_LDFLAGS= ENTRY_OBJ= @@ -193,11 +203,11 @@ INET_GETHOST = $(BINDIR)/inet_gethost@EXEEXT@ INSTALL_EMBEDDED_PROGS += $(BINDIR)/typer@EXEEXT@ $(BINDIR)/dialyzer@EXEEXT@ \ $(BINDIR)/erlc@EXEEXT@ $(BINDIR)/escript@EXEEXT@ $(BINDIR)/ct_run@EXEEXT@ \ $(BINDIR)/run_erl $(BINDIR)/to_erl $(BINDIR)/dyn_erl -INSTALL_EMBEDDED_DATA = ../unix/start.src ../unix/start_erl.src +INSTALL_EMBEDDED_DATA = $(UXETC)/start.src $(UXETC)/start_erl.src INSTALL_TOP = Install INSTALL_TOP_BIN = -INSTALL_MISC = ../unix/format_man_pages ../unix/makewhatis -INSTALL_SRC = ../unix/setuid_socket_wrap.c #delivered as an example +INSTALL_MISC = $(UXETC)/format_man_pages $(UXETC)/makewhatis +INSTALL_SRC = $(UXETC)/setuid_socket_wrap.c #delivered as an example ERLEXECDIR = . INSTALL_LIBS = INSTALL_OBJS = @@ -403,24 +413,24 @@ $(BINDIR)/inet_gethost@EXEEXT@: $(OBJDIR)/inet_gethost.o $(ENTRY_OBJ) $(ERTS_LIB # run_erl $(BINDIR)/run_erl: $(OBJDIR)/safe_string.o $(OBJDIR)/run_erl.o $(OBJDIR)/run_erl_common.o $(V_LD) $(LDFLAGS) -o $@ $^ $(LIBS) -$(OBJDIR)/run_erl.o: ../unix/run_erl.c ../common/run_erl_common.h $(RC_GENERATED) - $(V_CC) $(CFLAGS) -I ../common/ -o $@ -c ../unix/run_erl.c +$(OBJDIR)/run_erl.o: $(ETC)/run_erl.c ../common/run_erl_common.h $(RC_GENERATED) + $(V_CC) $(CFLAGS) -I ../common/ -o $@ -c $(ETC)/run_erl.c $(OBJDIR)/run_erl_common.o: ../common/run_erl_common.c ../common/run_erl_common.h $(RC_GENERATED) $(V_CC) $(CFLAGS) -o $@ -c $< # to_erl $(BINDIR)/to_erl: $(OBJDIR)/safe_string.o $(OBJDIR)/to_erl.o $(OBJDIR)/to_erl_common.o $(V_LD) $(LDFLAGS) -o $@ $^ -$(OBJDIR)/to_erl.o: ../unix/to_erl.c ../common/safe_string.h $(RC_GENERATED) - $(V_CC) $(CFLAGS) -I ../common/ -o $@ -c ../unix/to_erl.c +$(OBJDIR)/to_erl.o: $(ETC)/to_erl.c ../common/safe_string.h $(RC_GENERATED) + $(V_CC) $(CFLAGS) -I ../common/ -o $@ -c $(ETC)/to_erl.c $(OBJDIR)/to_erl_common.o: ../common/to_erl_common.c ../common/to_erl_common.h $(RC_GENERATED) $(V_CC) $(CFLAGS) -o $@ -c $< # dyn_erl $(BINDIR)/dyn_erl: $(OBJDIR)/safe_string.o $(OBJDIR)/dyn_erl.o $(V_LD) $(LDFLAGS) -o $@ $(OBJDIR)/safe_string.o $(OBJDIR)/dyn_erl.o -$(OBJDIR)/dyn_erl.o: ../unix/dyn_erl.c $(RC_GENERATED) - $(V_CC) $(CFLAGS) -o $@ -c ../unix/dyn_erl.c +$(OBJDIR)/dyn_erl.o: $(UXETC)/dyn_erl.c $(RC_GENERATED) + $(V_CC) $(CFLAGS) -o $@ -c $(UXETC)/dyn_erl.c $(OBJDIR)/safe_string.o: ../common/safe_string.c $(RC_GENERATED) $(V_CC) $(CFLAGS) -o $@ -c ../common/safe_string.c @@ -464,18 +474,42 @@ $(OBJDIR)/ct_run.o: ct_run.c $(RC_GENERATED) -Install: ../unix/Install.src ../../vsn.mk $(TARGET)/Makefile +Install: $(UXETC)/Install.src ../../vsn.mk $(TARGET)/Makefile $(vsn_verbose)sed -e 's;%I_VSN%;$(VSN);' \ -e 's;%EMULATOR%;$(EMULATOR);' \ -e 's;%EMULATOR_NUMBER%;$(EMULATOR_NUMBER);' \ -e 's;%I_SYSTEM_VSN%;$(SYSTEM_VSN);' \ - ../unix/Install.src > Install + $(UXETC)/Install.src > Install -erl.src: ../unix/erl.src.src ../../vsn.mk $(TARGET)/Makefile +erl.src: $(UXETC)/erl.src.src ../../vsn.mk $(TARGET)/Makefile $(vsn_verbose)sed -e 's;%EMULATOR%;$(EMULATOR);' \ -e 's;%EMULATOR_NUMBER%;$(EMULATOR_NUMBER);' \ -e 's;%VSN%;$(VSN);' \ - ../unix/erl.src.src > erl.src + $(UXETC)/erl.src.src > erl.src + +#--------------------------------------------------------- +# OSE specific targets +#--------------------------------------------------------- +ifeq ($(findstring ose,$(TARGET)),ose) +$(OBJDIR)/ose_confd.o: $(OSE_CONFD) + $(V_CC) $(CFLAGS) -o $@ -c $< +$(OBJDIR)/crt0_lm.o: $(CRT0_LM) + $(V_CC) $(CFLAGS) -o $@ -c $< +OSE_LM_OBJS += $(OBJDIR)/ose_confd.o $(OBJDIR)/crt0_lm.o + +$(BINDIR)/run_erl_lm: $(OBJDIR)/run_erl_main.o $(OBJDIR)/safe_string.o $(OBJDIR)/run_erl.o $(OBJDIR)/run_erl_common.o $(OBJDIR)/to_erl_common.o $(OSE_LM_OBJS) + $(call build-ose-load-module, $@, $^, $(LIBS), $(LMCONF)) + + +$(OBJDIR)/run_erl_main.o: $(OSEETC)/run_erl_main.c $(OSEETC)/run_erl.h ../common/to_erl_common.h $(RC_GENERATED) + $(V_CC) $(CFLAGS) -I ../common/ -o $@ -c $(OSEETC)/run_erl_main.c + +endif + +#--------------------------------------------------------- +# End of ose specific targets. +#--------------------------------------------------------- + # ---------------------------------------------------- # Release Target diff --git a/erts/etc/common/run_erl_common.c b/erts/etc/common/run_erl_common.c index dc899c5349..bf55056090 100644 --- a/erts/etc/common/run_erl_common.c +++ b/erts/etc/common/run_erl_common.c @@ -36,6 +36,10 @@ # include #endif +#ifdef __OSE__ +# include "ramlog.h" +#endif + #include "run_erl_common.h" #include "safe_string.h" @@ -57,7 +61,9 @@ #define PIPE_STUBLEN strlen(PIPE_STUBNAME) #define PERM (S_IWUSR | S_IRUSR | S_IWOTH | S_IROTH | S_IWGRP | S_IRGRP) -#if !defined(O_SYNC) +/* OSE has defined O_SYNC but it is not recognized by open */ +#if !defined(O_SYNC) || defined(__OSE__) +#undef O_SYNC #define O_SYNC 0 #define USE_FSYNC 1 #endif @@ -81,8 +87,6 @@ static char log_alive_format[ALIVE_BUFFSIZ+1]; static int run_daemon = 0; static unsigned protocol_ver = RUN_ERL_LO_VER; /* assume lowest to begin with */ -int erts_run_erl_log_alive_minutes = DEFAULT_LOG_ALIVE_MINUTES; - /* * Current log number and log fd */ @@ -94,7 +98,11 @@ static int lfd=0; * getenv_int: */ static char *getenv_int(const char *name) { +#ifdef __OSE__ + return get_env(get_bid(current_process()),name); +#else return getenv(name); +#endif } /* @@ -189,9 +197,7 @@ static int open_log(int log_num, int flags) /* Create or continue on the current log file */ sn_printf(buf, sizeof(buf), "%s/%s%d", log_dir, LOG_STUBNAME, log_num); - do { - lfd = open(buf, flags, LOG_PERM); - } while (lfd < 0 && errno == EINTR); + lfd = sf_open(buf, flags, LOG_PERM); if(lfd <0){ ERRNO_ERR1(LOG_ERR,"Can't open log file '%s'.", buf); @@ -307,7 +313,11 @@ void erts_run_erl_log_status(const char *format,...) return; now = time(NULL); fprintf(stdstatus, "run_erl [%d] %s", +#ifdef __OSE__ + (int)current_process(), +#else (int)getpid(), +#endif ctime(&now)); va_start(args, format); vfprintf(stdstatus, format, args); @@ -330,11 +340,23 @@ void erts_run_erl_log_error(int priority, int line, const char *format, ...) vsyslog(priority,format,args); } else +#endif +#ifdef __OSE__ + if (RUN_DAEMON) { + char *buff = malloc(sizeof(char)*1024); + vsnprintf(buff,1024,format, args); + ramlog_printf(buff); + } + else #endif { time_t now = time(NULL); fprintf(stderr, "run_erl:%d [%d] %s", line, +#ifdef __OSE__ + (int)current_process(), +#else (int)getpid(), +#endif ctime(&now)); vfprintf(stderr, format, args); } @@ -544,10 +566,12 @@ int erts_run_erl_open_fifo(char *pipename,char *w_pipename,char *r_pipename) { PIPE_STUBNAME, highest_pipe_num+1); continue; } - fprintf(stderr, "Erlang already running on pipe %s.\n", pipename); + ERROR1(LOG_ERR, "Erlang already running on pipe %s.\n", pipename); + unlink(w_pipename); return 1; } if (create_fifo(r_pipename, PERM) < 0) { + unlink(w_pipename); ERRNO_ERR1(LOG_ERR,"Cannot create FIFO %s for reading.", r_pipename); return 1; diff --git a/erts/etc/common/run_erl_common.h b/erts/etc/common/run_erl_common.h index dca1af93f2..3b763ad927 100644 --- a/erts/etc/common/run_erl_common.h +++ b/erts/etc/common/run_erl_common.h @@ -51,8 +51,12 @@ int erts_run_erl_write_all(int fd, const char* buf, int len); char *simple_basename(char *path); #ifndef LOG_ERR +#ifdef __OSE__ +#define LOG_ERR 0 +#else #define LOG_ERR NULL #endif +#endif #define ERROR0(Prio,Format) erts_run_erl_log_error(Prio,__LINE__,Format"\n") #define ERROR1(Prio,Format,A1) erts_run_erl_log_error(Prio,__LINE__,Format"\n",A1) diff --git a/erts/etc/common/to_erl_common.c b/erts/etc/common/to_erl_common.c index 4c38877277..1b2f27fa04 100644 --- a/erts/etc/common/to_erl_common.c +++ b/erts/etc/common/to_erl_common.c @@ -49,10 +49,19 @@ #include #include #include -#include #include -#include #include + +#ifdef __OSE__ +#include +#include "ose.h" +#include "efs.h" +#include "ose_spi/fm.sig" +#else /* __UNIX__ */ +#include +#include +#endif + #ifdef HAVE_SYS_IOCTL_H # include #endif @@ -78,7 +87,11 @@ #define noDEBUG +#ifdef __OSE__ +#define PIPE_DIR "/pipe/" +#else #define PIPE_DIR "/tmp/" +#endif #define PIPE_STUBNAME "erlang.pipe" #define PIPE_STUBLEN strlen(PIPE_STUBNAME) @@ -92,14 +105,38 @@ #define FILENAME_MAX 250 #endif -static struct termios tty_smode, tty_rmode; static int tty_eof = 0; -static int recv_sig = 0; static int protocol_ver = RUN_ERL_LO_VER; /* assume lowest to begin with */ static int write_all(int fd, const char* buf, int len); -static int window_size_seq(char* buf, size_t bufsz); static int version_handshake(char* buf, int len, int wfd); + + +#ifdef __OSE__ + +#define SET_AIO(REQ,FD,SIZE,BUFF) \ + /* Make sure to clean data structure of previous request */ \ + memset(&(REQ),0,sizeof(REQ)); \ + (REQ).aio_fildes = FD; \ + (REQ).aio_offset = FM_POSITION_CURRENT; \ + (REQ).aio_nbytes = SIZE; \ + (REQ).aio_buf = BUFF; \ + (REQ).aio_sigevent.sigev_notify = SIGEV_NONE + +#define READ_AIO(REQ,FD,SIZE,BUFF) \ + SET_AIO(REQ,FD,SIZE,BUFF); \ + if (aio_read(&(REQ)) != 0) \ + fprintf(stderr,"aio_read of child_read_req(%d) failed\n",FD) + +union SIGNAL { + SIGSELECT signo; + struct FmReadPtr fm_read_ptr; +}; + +#else /* __UNIX__ */ +static int recv_sig = 0; +static struct termios tty_smode, tty_rmode; +static int window_size_seq(char* buf, size_t bufsz); #ifdef DEBUG static void show_terminal_settings(struct termios *); #endif @@ -115,6 +152,7 @@ static void handle_sigwinch(int sig) { recv_sig = SIGWINCH; } +#endif static void usage(char *pname) { @@ -126,13 +164,22 @@ int to_erl(int argc, char **argv) { char FIFO1[FILENAME_MAX], FIFO2[FILENAME_MAX]; int i, len, wfd, rfd; - fd_set readfds; - char buf[BUFSIZ]; char pipename[FILENAME_MAX]; int pipeIx = 1; int force_lock = 0; int got_some = 0; +#ifdef __OSE__ + struct aiocb stdin_read_req, pipe_read_req; + FmHandle stdin_fh, pipe_fh; + char *stdin_buf, *pipe_buf; + char *buf; + union SIGNAL *sig; +#else /* __UNIX__ */ + char buf[BUFSIZ]; + fd_set readfds; +#endif + if (argc >= 2 && argv[1][0]=='-') { switch (argv[1][1]) { case 'h': @@ -149,7 +196,13 @@ int to_erl(int argc, char **argv) } #ifdef DEBUG - fprintf(stderr, "%s: pid is : %d\n", argv[0], (int)getpid()); + fprintf(stderr, "%s: pid is : %d\n", argv[0],(int) +#ifdef __OSE__ + current_process() +#else /* __UNIX__ */ + getpid() +#endif + ); #endif strn_cpy(pipename, sizeof(pipename), @@ -187,6 +240,7 @@ int to_erl(int argc, char **argv) /* write FIFO */ sn_printf(FIFO2,sizeof(FIFO2),"%s.w",pipename); +#ifndef __OSE__ /* Check that nobody is running to_erl on this pipe already */ if ((wfd = open (FIFO1, O_WRONLY|DONT_BLOCK_PLEASE, 0)) >= 0) { /* Open as server succeeded -- to_erl is already running! */ @@ -200,6 +254,7 @@ int to_erl(int argc, char **argv) exit(1); } } +#endif if ((rfd = open (FIFO1, O_RDONLY|DONT_BLOCK_PLEASE, 0)) < 0) { #ifdef DEBUG @@ -226,6 +281,7 @@ int to_erl(int argc, char **argv) fprintf(stderr, "Attaching to %s (^D to exit)\n\n", pipename); +#ifndef __OSE__ /* Set break handler to our handler */ signal(SIGINT,handle_ctrlc); @@ -344,6 +400,8 @@ int to_erl(int argc, char **argv) #ifdef DEBUG show_terminal_settings(&tty_smode); #endif + +#endif /* !__OSE__ */ /* * "Write a ^L to the FIFO which causes the other end to redisplay * the input line." @@ -357,10 +415,22 @@ int to_erl(int argc, char **argv) fprintf(stderr, "Error in writing ^L to FIFO.\n"); } +#ifdef __OSE__ + /* we have a tiny stack so we malloc the buffers */ + stdin_buf = malloc(sizeof(char) * BUFSIZ); + pipe_buf = malloc(sizeof(char) * BUFSIZ); + + efs_examine_fd(rfd,FLIB_FD_HANDLE,&pipe_fh); + efs_examine_fd(0,FLIB_FD_HANDLE,&stdin_fh); + READ_AIO(stdin_read_req,0,BUFSIZ,stdin_buf); + READ_AIO(pipe_read_req,rfd,BUFSIZ,pipe_buf); +#endif + /* * read and write */ while (1) { +#ifndef __OSE__ FD_ZERO(&readfds); FD_SET(0, &readfds); FD_SET(rfd, &readfds); @@ -393,8 +463,21 @@ int to_erl(int argc, char **argv) } recv_sig = 0; } - else if (FD_ISSET(0, &readfds)) { + else +#else /* __OSE__ */ + SIGSELECT sigsel[] = {0}; + sig = receive(sigsel); + len = 0; +#endif +#ifndef __OSE__ + if (FD_ISSET(0,&readfds)) { len = read(0, buf, sizeof(buf)); +#else /* __OSE__ */ + if (sig->signo == FM_READ_PTR_REPLY && + sig->fm_read_ptr.handle == stdin_fh) { + len = sig->fm_read_ptr.status == EFS_SUCCESS ? sig->fm_read_ptr.actual : -1; + buf = sig->fm_read_ptr.buffer; +#endif if (len <= 0) { close(rfd); close(wfd); @@ -406,7 +489,7 @@ int to_erl(int argc, char **argv) break; } /* check if there is an eof character in input */ - for (i = 0; i < len && buf[i] != tty_eof; i++); + for (i = 0; i < len-1 && buf[i] != tty_eof; i++); if (buf[i] == tty_eof) { fprintf(stderr, "[Quit]\n\r"); break; @@ -424,14 +507,25 @@ int to_erl(int argc, char **argv) break; } STATUS("\" OK\r\n"); +#ifdef __OSE__ + aio_dispatch(sig); + READ_AIO(stdin_read_req, 0, BUFSIZ, stdin_buf); +#endif } /* * Read from FIFO, write to terminal. */ +#ifndef __OSE__ if (FD_ISSET(rfd, &readfds)) { STATUS("FIFO read: "); len = read(rfd, buf, BUFSIZ); +#else /* __OSE__ */ + if (sig->signo == FM_READ_PTR_REPLY && + sig->fm_read_ptr.handle == pipe_fh) { + len = sig->fm_read_ptr.status == EFS_SUCCESS ? sig->fm_read_ptr.actual : -1; + buf = sig->fm_read_ptr.buffer; +#endif if (len < 0 && errno == EAGAIN) { /* * No data this time, but the writing end of the FIFO is still open. @@ -457,11 +551,13 @@ int to_erl(int argc, char **argv) close(wfd); break; } +#ifndef __OSE__ if (protocol_ver >= 1) { /* Tell run_erl size of terminal window */ signal(SIGWINCH, handle_sigwinch); raise(SIGWINCH); } +#endif got_some = 1; } @@ -476,15 +572,21 @@ int to_erl(int argc, char **argv) break; } STATUS("\" OK\r\n"); +#ifdef __OSE__ + aio_dispatch(sig); + READ_AIO(pipe_read_req, rfd, BUFSIZ, pipe_buf); +#endif } } } +#ifndef __OSE__ /* * Reset terminal characterstics * XXX */ tcsetattr(0, TCSADRAIN, &tty_rmode); +#endif return 0; } @@ -506,6 +608,7 @@ static int write_all(int fd, const char* buf, int len) return len; } +#ifndef __OSE__ static int window_size_seq(char* buf, size_t bufsz) { #ifdef TIOCGWINSZ @@ -523,6 +626,7 @@ static int window_size_seq(char* buf, size_t bufsz) #endif /* TIOCGWINSZ */ return 0; } +#endif /* !__OSE__ */ /* to_erl run_erl * | | @@ -574,7 +678,7 @@ static int version_handshake(char* buf, int len, int wfd) } -#ifdef DEBUG +#if defined(DEBUG) && !defined(__OSE__) #define S(x) ((x) > 0 ? 1 : 0) static void show_terminal_settings(struct termios *t) @@ -604,4 +708,4 @@ static void show_terminal_settings(struct termios *t) fprintf(stderr,"c_cc:\n"); fprintf(stderr,"c_cc[VEOF] %d\n", t->c_cc[VEOF]); } -#endif +#endif /* DEBUG && !__OSE__ */ -- cgit v1.2.3 From ae561e41e5578b373311556c9f9e619f277f825b Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Wed, 8 Jan 2014 16:42:12 +0100 Subject: ose: Refactor global variables to ppdata This is needed because when starting multiple processes from the same shell command they will see the same global data if using status variables. --- erts/etc/common/run_erl_common.c | 198 ++++++++++++++++++++++++--------------- erts/etc/common/run_erl_common.h | 3 - 2 files changed, 125 insertions(+), 76 deletions(-) (limited to 'erts/etc/common') diff --git a/erts/etc/common/run_erl_common.c b/erts/etc/common/run_erl_common.c index bf55056090..dc55c2bea4 100644 --- a/erts/etc/common/run_erl_common.c +++ b/erts/etc/common/run_erl_common.c @@ -68,6 +68,54 @@ #define USE_FSYNC 1 #endif +/* Global variable definitions + * We need this complex way of handling global variables because of how + * OSE works here. We want to make it possible to run the shell command + * run_erl multiple times with different global variables without them + * effecting eachother. + */ +typedef struct run_erl_ run_erl; + +#ifdef __OSE__ +static OSPPDKEY run_erl_pp_key; +#define RE_DATA (*(run_erl**)ose_get_ppdata(run_erl_pp_key)) +#else +static run_erl re; +#define RE_DATA (&re) +#endif + +#define STATUSFILE (RE_DATA->statusfile) +#define LOG_DIR (RE_DATA->log_dir) +#define STDSTATUS (RE_DATA->stdstatus) +#define LOG_GENERATIONS (RE_DATA->log_generations) +#define LOG_MAXSIZE (RE_DATA->log_maxsize) +#define LOG_ACTIVITY_MINUTES (RE_DATA->log_activity_minutes) +#define LOG_ALIVE_IN_GMT (RE_DATA->log_alive_in_gmt) +#define LOG_ALIVE_FORMAT (RE_DATA->log_alive_format) +#define RUN_DAEMON (RE_DATA->run_daemon) +#define LOG_ALIVE_MINUTES (RE_DATA->log_alive_minutes) +#define LOG_NUM (RE_DATA->log_num) +#define LFD (RE_DATA->lfd) +#define PROTOCOL_VER (RE_DATA->protocol_ver) + +struct run_erl_ { + /* constant config data */ + char statusfile[FILENAME_BUFSIZ]; + char log_dir[FILENAME_BUFSIZ]; + FILE *stdstatus; + int log_generations; + int log_maxsize; + int log_activity_minutes; + int log_alive_in_gmt; + char log_alive_format[ALIVE_BUFFSIZ+1]; + int run_daemon; + int log_alive_minutes; + /* Current log number and log fd */ + int log_num; + int lfd; + unsigned protocol_ver; +}; + /* prototypes */ static int next_log(int log_num); @@ -75,25 +123,6 @@ static int prev_log(int log_num); static int find_next_log_num(void); static int open_log(int log_num, int flags); -/* static data */ -static char statusfile[FILENAME_BUFSIZ]; -static char log_dir[FILENAME_BUFSIZ]; -static FILE *stdstatus = NULL; -static int log_generations = DEFAULT_LOG_GENERATIONS; -static int log_maxsize = DEFAULT_LOG_MAXSIZE; -static int log_activity_minutes = DEFAULT_LOG_ACTIVITY_MINUTES; -static int log_alive_in_gmt = 0; -static char log_alive_format[ALIVE_BUFFSIZ+1]; -static int run_daemon = 0; -static unsigned protocol_ver = RUN_ERL_LO_VER; /* assume lowest to begin with */ - -/* - * Current log number and log fd - */ -static int log_num; -static int lfd=0; - - /* * getenv_int: */ @@ -111,7 +140,7 @@ static char *getenv_int(const char *name) { * (Wrapping after log_generations) */ static int next_log(int log_num) { - return log_num>=log_generations?1:log_num+1; + return log_num>=LOG_GENERATIONS?1:log_num+1; } /* @@ -120,7 +149,7 @@ static int next_log(int log_num) { * (Wrapping after log_generations) */ static int prev_log(int log_num) { - return log_num<=1?log_generations:log_num-1; + return log_num<=1?LOG_GENERATIONS:log_num-1; } /* @@ -139,11 +168,11 @@ static int find_next_log_num(void) { /* Initialize exiting log table */ - for(i=log_generations; i>=0; i--) + for(i=LOG_GENERATIONS; i>=0; i--) log_exists[i] = 0; - dirp = opendir(log_dir); + dirp = opendir(LOG_DIR); if(!dirp) { - ERRNO_ERR1(LOG_ERR,"Can't access log directory '%s'", log_dir); + ERRNO_ERR1(LOG_ERR,"Can't access log directory '%s'", LOG_DIR); exit(1); } @@ -152,7 +181,7 @@ static int find_next_log_num(void) { while((direntp=readdir(dirp)) != NULL) { if(strncmp(direntp->d_name,LOG_STUBNAME,stub_len)==0) { int num = atoi(direntp->d_name+stub_len); - if(num < 1 || num > log_generations) + if(num < 1 || num > LOG_GENERATIONS) continue; log_exists[num] = 1; } @@ -162,7 +191,7 @@ static int find_next_log_num(void) { /* Find out the next available log file number */ next_gen = 0; - for(i=log_generations; i>=0; i--) { + for(i=LOG_GENERATIONS; i>=0; i--) { if(log_exists[i]) if(next_gen) break; @@ -191,27 +220,27 @@ static int open_log(int log_num, int flags) /* Remove the next log (to keep a "hole" in the log sequence) */ sn_printf(buf, sizeof(buf), "%s/%s%d", - log_dir, LOG_STUBNAME, next_log(log_num)); + LOG_DIR, LOG_STUBNAME, next_log(log_num)); unlink(buf); /* Create or continue on the current log file */ - sn_printf(buf, sizeof(buf), "%s/%s%d", log_dir, LOG_STUBNAME, log_num); + sn_printf(buf, sizeof(buf), "%s/%s%d", LOG_DIR, LOG_STUBNAME, log_num); - lfd = sf_open(buf, flags, LOG_PERM); + LFD = sf_open(buf, flags, LOG_PERM); - if(lfd <0){ + if(LFD <0){ ERRNO_ERR1(LOG_ERR,"Can't open log file '%s'.", buf); exit(1); } /* Write a LOGGING STARTED and time stamp into the log file */ time(&now); - if (log_alive_in_gmt) { + if (LOG_ALIVE_IN_GMT) { tmptr = gmtime(&now); } else { tmptr = localtime(&now); } - if (!strftime(log_buffer, ALIVE_BUFFSIZ, log_alive_format, + if (!strftime(log_buffer, ALIVE_BUFFSIZ, LOG_ALIVE_FORMAT, tmptr)) { strn_cpy(log_buffer, sizeof(log_buffer), "(could not format time in 256 positions " @@ -221,14 +250,14 @@ static int open_log(int log_num, int flags) sn_printf(buf, sizeof(buf), "\n=====\n===== LOGGING STARTED %s\n=====\n", log_buffer); - if (erts_run_erl_write_all(lfd, buf, strlen(buf)) < 0) + if (erts_run_erl_write_all(LFD, buf, strlen(buf)) < 0) erts_run_erl_log_status("Error in writing to log.\n"); #if USE_FSYNC - fsync(lfd); + fsync(LFD); #endif - return lfd; + return LFD; } /* Instead of making sure basename exists, we do our own */ @@ -307,12 +336,12 @@ void erts_run_erl_log_status(const char *format,...) va_list args; time_t now; - if (stdstatus == NULL) - stdstatus = fopen(statusfile, "w"); - if (stdstatus == NULL) + if (STDSTATUS == NULL) + STDSTATUS = fopen(STATUSFILE, "w"); + if (STDSTATUS == NULL) return; now = time(NULL); - fprintf(stdstatus, "run_erl [%d] %s", + fprintf(STDSTATUS, "run_erl [%d] %s", #ifdef __OSE__ (int)current_process(), #else @@ -320,12 +349,17 @@ void erts_run_erl_log_status(const char *format,...) #endif ctime(&now)); va_start(args, format); - vfprintf(stdstatus, format, args); + vfprintf(STDSTATUS, format, args); va_end(args); - fflush(stdstatus); + fflush(STDSTATUS); return; } +/* Fetch the current log alive minutes */ +int erts_run_erl_log_alive_minutes() { + return LOG_ALIVE_MINUTES; +} + /* error_logf() * Prints the arguments to stderr or syslog * Works like printf (see vfprintf) @@ -336,7 +370,7 @@ void erts_run_erl_log_error(int priority, int line, const char *format, ...) va_start(args, format); #ifdef HAVE_SYSLOG_H - if (run_daemon) { + if (RUN_DAEMON) { vsyslog(priority,format,args); } else @@ -373,24 +407,24 @@ int erts_run_erl_log_write(char* buf, size_t len) ssize_t res; /* Decide if new logfile needed, and open if so */ - size = lseek(lfd,0,SEEK_END); - if(size+len > log_maxsize) { + size = lseek(LFD,0,SEEK_END); + if(size+len > LOG_MAXSIZE) { int res; do { - res = close(lfd); + res = close(LFD); } while (res < 0 && errno == EINTR); - log_num = next_log(log_num); - lfd = open_log(log_num, O_RDWR|O_CREAT|O_TRUNC|O_SYNC); + LOG_NUM = next_log(LOG_NUM); + LFD = open_log(LOG_NUM, O_RDWR|O_CREAT|O_TRUNC|O_SYNC); } /* Write to log file */ - if ((res = erts_run_erl_write_all(lfd, buf, len)) < 0) { + if ((res = erts_run_erl_write_all(LFD, buf, len)) < 0) { erts_run_erl_log_status("Error in writing to log.\n"); } #if USE_FSYNC - fsync(lfd); + fsync(LFD); #endif return res; } @@ -399,17 +433,17 @@ int erts_run_erl_log_activity(int timeout,time_t now,time_t last_activity) { char log_alive_buffer[ALIVE_BUFFSIZ+1]; char buf[BUFSIZ]; - if (timeout || now - last_activity > log_activity_minutes*60) { + if (timeout || now - last_activity > LOG_ACTIVITY_MINUTES*60) { /* Either a time out: 15 minutes without action, */ /* or something is coming in right now, but it's a long time */ /* since last time, so let's write a time stamp this message */ struct tm *tmptr; - if (log_alive_in_gmt) { + if (LOG_ALIVE_IN_GMT) { tmptr = gmtime(&now); } else { tmptr = localtime(&now); } - if (!strftime(log_alive_buffer, ALIVE_BUFFSIZ, log_alive_format, + if (!strftime(log_alive_buffer, ALIVE_BUFFSIZ, LOG_ALIVE_FORMAT, tmptr)) { strn_cpy(log_alive_buffer, sizeof(log_alive_buffer), "(could not format time in 256 positions " @@ -426,30 +460,48 @@ int erts_run_erl_log_activity(int timeout,time_t now,time_t last_activity) { int erts_run_erl_log_open() { - log_num = find_next_log_num(); - lfd = open_log(log_num, O_RDWR|O_APPEND|O_CREAT|O_SYNC); + LOG_NUM = find_next_log_num(); + LFD = open_log(LOG_NUM, O_RDWR|O_APPEND|O_CREAT|O_SYNC); return 0; } int erts_run_erl_log_init(int daemon, char* logdir) { char *p; +#ifdef __OSE__ + run_erl **re_pp; + if (!run_erl_pp_key) + ose_create_ppdata("run_erl_ppdata",&run_erl_pp_key); + re_pp = (run_erl **)ose_get_ppdata(run_erl_pp_key); + *re_pp = malloc(sizeof(run_erl)); +#endif + + STDSTATUS = NULL; + LOG_GENERATIONS = DEFAULT_LOG_GENERATIONS; + LOG_MAXSIZE = DEFAULT_LOG_MAXSIZE; + LOG_ACTIVITY_MINUTES = DEFAULT_LOG_ACTIVITY_MINUTES; + LOG_ALIVE_IN_GMT = 0; + RUN_DAEMON = 0; + LOG_ALIVE_MINUTES = DEFAULT_LOG_ALIVE_MINUTES; + LFD = 0; + PROTOCOL_VER = RUN_ERL_LO_VER; /* assume lowest to begin with */ + /* Get values for LOG file handling from the environment */ if ((p = getenv_int("RUN_ERL_LOG_ALIVE_MINUTES"))) { - erts_run_erl_log_alive_minutes = atoi(p); - if (!erts_run_erl_log_alive_minutes) { + LOG_ALIVE_MINUTES = atoi(p); + if (!LOG_ALIVE_MINUTES) { ERROR1(LOG_ERR,"Minimum value for RUN_ERL_LOG_ALIVE_MINUTES is 1 " "(current value is %s)",p); } - log_activity_minutes = erts_run_erl_log_alive_minutes / 3; - if (!log_activity_minutes) { - ++log_activity_minutes; + LOG_ACTIVITY_MINUTES = LOG_ALIVE_MINUTES / 3; + if (!LOG_ACTIVITY_MINUTES) { + ++LOG_ACTIVITY_MINUTES; } } if ((p = getenv_int( "RUN_ERL_LOG_ACTIVITY_MINUTES"))) { - log_activity_minutes = atoi(p); - if (!log_activity_minutes) { + LOG_ACTIVITY_MINUTES = atoi(p); + if (!LOG_ACTIVITY_MINUTES) { ERROR1(LOG_ERR,"Minimum value for RUN_ERL_LOG_ACTIVITY_MINUTES is 1 " "(current value is %s)",p); } @@ -459,36 +511,36 @@ int erts_run_erl_log_init(int daemon, char* logdir) { ERROR1(LOG_ERR, "RUN_ERL_LOG_ALIVE_FORMAT can contain a maximum of " "%d characters", ALIVE_BUFFSIZ); } - strn_cpy(log_alive_format, sizeof(log_alive_format), p); + strn_cpy(LOG_ALIVE_FORMAT, sizeof(LOG_ALIVE_FORMAT), p); } else { - strn_cpy(log_alive_format, sizeof(log_alive_format), + strn_cpy(LOG_ALIVE_FORMAT, sizeof(LOG_ALIVE_FORMAT), DEFAULT_LOG_ALIVE_FORMAT); } if ((p = getenv_int("RUN_ERL_LOG_ALIVE_IN_UTC")) && strcmp(p,"0")) { - ++log_alive_in_gmt; + ++LOG_ALIVE_IN_GMT; } if ((p = getenv_int("RUN_ERL_LOG_GENERATIONS"))) { - log_generations = atoi(p); - if (log_generations < LOG_MIN_GENERATIONS) + LOG_GENERATIONS = atoi(p); + if (LOG_GENERATIONS < LOG_MIN_GENERATIONS) ERROR1(LOG_ERR,"Minimum RUN_ERL_LOG_GENERATIONS is %d", LOG_MIN_GENERATIONS); - if (log_generations > LOG_MAX_GENERATIONS) + if (LOG_GENERATIONS > LOG_MAX_GENERATIONS) ERROR1(LOG_ERR,"Maximum RUN_ERL_LOG_GENERATIONS is %d", LOG_MAX_GENERATIONS); } if ((p = getenv_int("RUN_ERL_LOG_MAXSIZE"))) { - log_maxsize = atoi(p); - if (log_maxsize < LOG_MIN_MAXSIZE) + LOG_MAXSIZE = atoi(p); + if (LOG_MAXSIZE < LOG_MIN_MAXSIZE) ERROR1(LOG_ERR,"Minimum RUN_ERL_LOG_MAXSIZE is %d", LOG_MIN_MAXSIZE); } - run_daemon = daemon; + RUN_DAEMON = daemon; - strn_cpy(log_dir, sizeof(log_dir), logdir); - strn_cpy(statusfile, sizeof(statusfile), log_dir); - strn_cat(statusfile, sizeof(statusfile), STATUSFILENAME); + strn_cpy(LOG_DIR, sizeof(LOG_DIR), logdir); + strn_cpy(STATUSFILE, sizeof(STATUSFILE), LOG_DIR); + strn_cat(STATUSFILE, sizeof(STATUSFILE), STATUSFILENAME); return 0; } diff --git a/erts/etc/common/run_erl_common.h b/erts/etc/common/run_erl_common.h index 3b763ad927..c47a0db054 100644 --- a/erts/etc/common/run_erl_common.h +++ b/erts/etc/common/run_erl_common.h @@ -71,9 +71,6 @@ char *simple_basename(char *path); #define ERRNO_ERR1(Prio,Format,A1) erts_run_erl_log_error(Prio,__LINE__,ADD_ERRNO(Format),A1) #define ERRNO_ERR2(Prio,Format,A1,A2) erts_run_erl_log_error(Prio,__LINE__,ADD_ERRNO(Format),A1,A2) -/* defined in run_common.c */ -extern int erts_run_erl_log_alive_minutes; - #define RUN_ERL_USAGE \ "%s (pipe_name|pipe_dir/) log_dir \"command [parameters ...]\"" \ "\n\nDESCRIPTION:\n" \ -- cgit v1.2.3 From 6d010bd4ea3a5bb182cab4aff4436eb4f058c301 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Thu, 20 Feb 2014 18:02:26 +0100 Subject: win32: Compile erl_log.exe erl_log is used together with debug emulator. Use 'erl -debug -console' to get a denug console. --- erts/etc/common/Makefile.in | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'erts/etc/common') diff --git a/erts/etc/common/Makefile.in b/erts/etc/common/Makefile.in index 5be0942952..4e50058b00 100644 --- a/erts/etc/common/Makefile.in +++ b/erts/etc/common/Makefile.in @@ -161,7 +161,8 @@ INSTALL_TOP_BIN = $(BINDIR)/Install.exe INSTALL_PROGS = \ $(INET_GETHOST) \ $(BINDIR)/heart.exe $(BINDIR)/erlsrv.exe \ - $(BINDIR)/erl.exe $(BINDIR)/werl.exe \ + $(BINDIR)/erl.exe $(BINDIR)/erl_log.exe \ + $(BINDIR)/werl.exe \ $(BINDIR)/$(ERLEXEC) \ $(INSTALL_EMBEDDED_PROGS) @@ -271,6 +272,7 @@ endif rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/ct_run.o rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/vxcall.o rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/erl.o + rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/erl_log.o rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/werl.o rm -f $(TEXTFILES) rm -f *~ core @@ -294,6 +296,9 @@ $(BINDIR)/erl@EXEEXT@: $(OBJDIR)/erl.o $(OBJDIR)/init_file.o $(OBJDIR)/$(ERLRES_ $(BINDIR)/werl@EXEEXT@: $(OBJDIR)/werl.o $(OBJDIR)/init_file.o $(OBJDIR)/$(ERLRES_OBJ) $(V_LD) $(LDFLAGS) -o $@ $(OBJDIR)/werl.o $(OBJDIR)/init_file.o $(OBJDIR)/$(ERLRES_OBJ) +$(BINDIR)/erl_log@EXEEXT@: $(OBJDIR)/erl_log.o + $(V_LD) $(LDFLAGS) -o $@ $(OBJDIR)/erl_log.o + $(BINDIR)/start_erl@EXEEXT@: $(OBJDIR)/start_erl.o $(V_LD) $(LDFLAGS) -o $@ $(OBJDIR)/start_erl.o @@ -347,6 +352,10 @@ $(OBJDIR)/werl.o: $(WINETC)/erl.c $(WINETC)/init_file.h $(RC_GENERATED) $(V_CC) $(CFLAGS) -DBUILD_TYPE=\"-$(TYPE)\" -DERL_RUN_SHARED_LIB=1 \ -DWIN32_WERL -o $@ -c $(WINETC)/erl.c +$(OBJDIR)/erl_log.o: $(WINETC)/erl_log.c $(RC_GENERATED) + $(V_CC) $(CFLAGS) -DBUILD_TYPE=\"-$(TYPE)\" -DERL_RUN_SHARED_LIB=1 \ + -o $@ -c $(WINETC)/erl_log.c + $(OBJDIR)/erl.o: $(WINETC)/erl.c $(WINETC)/init_file.h $(RC_GENERATED) $(V_CC) $(CFLAGS) -DBUILD_TYPE=\"-$(TYPE)\" -DERL_RUN_SHARED_LIB=1 \ -o $@ -c $(WINETC)/erl.c -- cgit v1.2.3 From 13ed57745c639f72be8ae1f25fbd206f6e7307f3 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Fri, 21 Feb 2014 15:19:53 +0100 Subject: ose: Expand OSE docs --- erts/etc/common/to_erl_common.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'erts/etc/common') diff --git a/erts/etc/common/to_erl_common.c b/erts/etc/common/to_erl_common.c index 1b2f27fa04..a49be44b6c 100644 --- a/erts/etc/common/to_erl_common.c +++ b/erts/etc/common/to_erl_common.c @@ -279,7 +279,11 @@ int to_erl(int argc, char **argv) fprintf(stderr, "to_erl: %s opened for writing\n", FIFO2); #endif +#ifndef __OSE__ fprintf(stderr, "Attaching to %s (^D to exit)\n\n", pipename); +#else + fprintf(stderr, "Attaching to %s (^C to exit)\n\n", pipename); +#endif #ifndef __OSE__ /* Set break handler to our handler */ -- cgit v1.2.3