Created
November 4, 2015 00:13
-
-
Save Teino1978-Corp/215c259f1c6c82366319 to your computer and use it in GitHub Desktop.
chatroom written in erlang/cowboy
This gist exceeds the recommended number of files (~10).
To access all files, please clone this gist.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/Users/xiaofwa/IdeaProjects/chatroom/deps/cowboy | |
/Users/xiaofwa/IdeaProjects/chatroom/deps/cowlib | |
/Users/xiaofwa/IdeaProjects/chatroom/deps/ranch |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
chatroom |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="CompilerConfiguration"> | |
<resourceExtensions /> | |
<wildcardResourcePatterns> | |
<entry name="!?*.java" /> | |
<entry name="!?*.form" /> | |
<entry name="!?*.class" /> | |
<entry name="!?*.groovy" /> | |
<entry name="!?*.scala" /> | |
<entry name="!?*.flex" /> | |
<entry name="!?*.kt" /> | |
<entry name="!?*.clj" /> | |
<entry name="!?*.aj" /> | |
</wildcardResourcePatterns> | |
<annotationProcessing> | |
<profile default="true" name="Default" enabled="false"> | |
<processorPath useClasspath="true" /> | |
</profile> | |
</annotationProcessing> | |
</component> | |
</project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<component name="CopyrightManager"> | |
<settings default="" /> | |
</component> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="MavenImportPreferences"> | |
<option name="generalSettings"> | |
<MavenGeneralSettings> | |
<option name="mavenHome" value="Bundled (Maven 3)" /> | |
</MavenGeneralSettings> | |
</option> | |
</component> | |
<component name="ProjectLevelVcsManager" settingsEditedManually="false"> | |
<OptionsSetting value="true" id="Add" /> | |
<OptionsSetting value="true" id="Remove" /> | |
<OptionsSetting value="true" id="Checkout" /> | |
<OptionsSetting value="true" id="Update" /> | |
<OptionsSetting value="true" id="Status" /> | |
<OptionsSetting value="true" id="Edit" /> | |
<ConfirmationsSetting value="0" id="Add" /> | |
<ConfirmationsSetting value="0" id="Remove" /> | |
</component> | |
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="Erlang 17" project-jdk-type="Erlang SDK"> | |
<output url="file://$PROJECT_DIR$/out" /> | |
</component> | |
<component name="masterDetails"> | |
<states> | |
<state key="ProjectJDKs.UI"> | |
<settings> | |
<last-edited>Erlang 17</last-edited> | |
<splitter-proportions> | |
<option name="proportions"> | |
<list> | |
<option value="0.2" /> | |
</list> | |
</option> | |
</splitter-proportions> | |
</settings> | |
</state> | |
</states> | |
</component> | |
</project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="ProjectModuleManager"> | |
<modules> | |
<module fileurl="file://$PROJECT_DIR$/chatroom.iml" filepath="$PROJECT_DIR$/chatroom.iml" /> | |
</modules> | |
</component> | |
</project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="VcsDirectoryMappings"> | |
<mapping directory="" vcs="" /> | |
</component> | |
</project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
set -e | |
SCRIPT_DIR="$(dirname "$0")" | |
RELEASE_ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" | |
REL_NAME="chatroom_release" | |
REL_VSN="1" | |
ERTS_VSN="6.4" | |
CODE_LOADING_MODE="${CODE_LOADING_MODE:-embedded}" | |
REL_DIR="$RELEASE_ROOT_DIR/releases/$REL_VSN" | |
ERL_OPTS="" | |
RUNNER_LOG_DIR="${RUNNER_LOG_DIR:-$RELEASE_ROOT_DIR/log}" | |
find_erts_dir() { | |
local erts_dir="$RELEASE_ROOT_DIR/erts-$ERTS_VSN" | |
if [ -d "$erts_dir" ]; then | |
ERTS_DIR="$erts_dir"; | |
ROOTDIR="$RELEASE_ROOT_DIR" | |
else | |
local erl="$(which erl)" | |
code="io:format(\"~s\", [code:root_dir()]), halt()." | |
local erl_root="$("$erl" -noshell -eval "$code")" | |
ERTS_DIR="$erl_root/erts-$ERTS_VSN" | |
ROOTDIR="$erl_root" | |
fi | |
} | |
# Get node pid | |
relx_get_pid() { | |
if output="$(relx_nodetool rpcterms os getpid)" | |
then | |
echo "$output" | sed -e 's/"//g' | |
return 0 | |
else | |
echo "$output" | |
return 1 | |
fi | |
} | |
relx_get_longname() { | |
id="longname$(relx_gen_id)-${NAME}" | |
"$BINDIR/erl" -boot start_clean -eval 'io:format("~s~n", [node()]), halt()' -noshell -name $id | sed -e 's/.*@//g' | |
} | |
# Connect to a remote node | |
relx_rem_sh() { | |
# Generate a unique id used to allow multiple remsh to the same node | |
# transparently | |
id="remsh$(relx_gen_id)-${NAME}" | |
# Get the node's ticktime so that we use the same thing. | |
TICKTIME="$(relx_nodetool rpcterms net_kernel get_net_ticktime)" | |
# Setup remote shell command to control node | |
exec "$BINDIR/erl" "$NAME_TYPE" "$id" -remsh "$NAME" -boot start_clean \ | |
-boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \ | |
-setcookie "$COOKIE" -kernel net_ticktime $TICKTIME | |
} | |
# Generate a random id | |
relx_gen_id() { | |
od -X /dev/urandom | head -n1 | awk '{print $2}' | |
} | |
# Control a node | |
relx_nodetool() { | |
command="$1"; shift | |
"$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \ | |
-setcookie "$COOKIE" "$command" $@ | |
} | |
# Run an escript in the node's environment | |
relx_escript() { | |
shift; scriptpath="$1"; shift | |
export RELEASE_ROOT_DIR | |
"$ERTS_DIR/bin/escript" "$ROOTDIR/$scriptpath" $@ | |
} | |
# Output a start command for the last argument of run_erl | |
relx_start_command() { | |
printf "exec \"%s\" \"%s\"" "$RELEASE_ROOT_DIR/bin/$REL_NAME" \ | |
"$START_OPTION" | |
} | |
# Use $CWD/vm.args if exists, otherwise releases/VSN/vm.args | |
if [ -z "$VMARGS_PATH" ]; then | |
if [ -f "$RELEASE_ROOT_DIR/vm.args" ]; then | |
VMARGS_PATH="$RELEASE_ROOT_DIR/vm.args" | |
USE_DIR="$RELEASE_ROOT_DIR" | |
else | |
USE_DIR="$REL_DIR" | |
VMARGS_PATH="$REL_DIR/vm.args" | |
fi | |
fi | |
if [ $RELX_REPLACE_OS_VARS ]; then | |
awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < $VMARGS_PATH > $VMARGS_PATH.2.config | |
VMARGS_PATH=$VMARGS_PATH.2.config | |
fi | |
# Make sure log directory exists | |
mkdir -p "$RUNNER_LOG_DIR" | |
if [ -z "$RELX_CONFIG_PATH" ]; then | |
if [ -f "$USE_DIR/sys.config" ]; then | |
RELX_CONFIG_PATH="$USE_DIR/sys.config" | |
else | |
RELX_CONFIG_PATH="$REL_DIR/sys.config" | |
fi | |
fi | |
if [ $RELX_REPLACE_OS_VARS ]; then | |
awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < $RELX_CONFIG_PATH > $RELX_CONFIG_PATH.2.config | |
RELX_CONFIG_PATH=$RELX_CONFIG_PATH.2.config | |
fi | |
# Extract the target node name from node.args | |
NAME_ARG=$(egrep '^-s?name' "$VMARGS_PATH") | |
if [ -z "$NAME_ARG" ]; then | |
echo "vm.args needs to have either -name or -sname parameter." | |
exit 1 | |
fi | |
# Extract the name type and name from the NAME_ARG for REMSH | |
NAME_TYPE="$(echo "$NAME_ARG" | awk '{print $1}')" | |
NAME="$(echo "$NAME_ARG" | awk '{print $2}')" | |
PIPE_DIR="${PIPE_DIR:-/tmp/erl_pipes/$NAME/}" | |
# Extract the target cookie | |
COOKIE_ARG="$(grep '^-setcookie' "$VMARGS_PATH")" | |
if [ -z "$COOKIE_ARG" ]; then | |
echo "vm.args needs to have a -setcookie parameter." | |
exit 1 | |
fi | |
# Extract cookie name from COOKIE_ARG | |
COOKIE="$(echo "$COOKIE_ARG" | awk '{print $2}')" | |
find_erts_dir | |
export ROOTDIR="$RELEASE_ROOT_DIR" | |
export BINDIR="$ERTS_DIR/bin" | |
export EMU="beam" | |
export PROGNAME="erl" | |
export LD_LIBRARY_PATH="$ERTS_DIR/lib:$LD_LIBRARY_PATH" | |
ERTS_LIB_DIR="$ERTS_DIR/../lib" | |
cd "$ROOTDIR" | |
# User can specify an sname without @hostname | |
# This will fail when creating remote shell | |
# So here we check for @ and add @hostname if missing | |
case $NAME in | |
*@*) | |
# Nothing to do | |
;; | |
*) | |
# Add @hostname | |
case $NAME_TYPE in | |
-sname) | |
NAME=$NAME@`hostname -s` | |
;; | |
-name) | |
NAME=$NAME@$(relx_get_longname) | |
;; | |
esac | |
;; | |
esac | |
# Check the first argument for instructions | |
case "$1" in | |
start|start_boot) | |
# Make sure there is not already a node running | |
#RES=`$NODETOOL ping` | |
#if [ "$RES" = "pong" ]; then | |
# echo "Node is already running!" | |
# exit 1 | |
#fi | |
# Save this for later. | |
CMD=$1 | |
case "$1" in | |
start) | |
shift | |
START_OPTION="console" | |
HEART_OPTION="start" | |
;; | |
start_boot) | |
shift | |
START_OPTION="console_boot" | |
HEART_OPTION="start_boot" | |
;; | |
esac | |
RUN_PARAM="$@" | |
# Set arguments for the heart command | |
set -- "$SCRIPT_DIR/$REL_NAME" "$HEART_OPTION" | |
[ "$RUN_PARAM" ] && set -- "$@" "$RUN_PARAM" | |
# Export the HEART_COMMAND | |
HEART_COMMAND="$RELEASE_ROOT_DIR/bin/$REL_NAME $CMD" | |
export HEART_COMMAND | |
mkdir -p "$PIPE_DIR" | |
"$BINDIR/run_erl" -daemon "$PIPE_DIR" "$RUNNER_LOG_DIR" \ | |
"$(relx_start_command)" | |
;; | |
stop) | |
# Wait for the node to completely stop... | |
PID="$(relx_get_pid)" | |
if ! relx_nodetool "stop"; then | |
exit 1 | |
fi | |
while $(kill -0 "$PID" 2>/dev/null); | |
do | |
sleep 1 | |
done | |
;; | |
restart) | |
## Restart the VM without exiting the process | |
if ! relx_nodetool "restart"; then | |
exit 1 | |
fi | |
;; | |
reboot) | |
## Restart the VM completely (uses heart to restart it) | |
if ! relx_nodetool "reboot"; then | |
exit 1 | |
fi | |
;; | |
pid) | |
## Get the VM's pid | |
if ! relx_get_pid; then | |
exit 1 | |
fi | |
;; | |
ping) | |
## See if the VM is alive | |
if ! relx_nodetool "ping"; then | |
exit 1 | |
fi | |
;; | |
escript) | |
## Run an escript under the node's environment | |
if ! relx_escript $@; then | |
exit 1 | |
fi | |
;; | |
attach) | |
# Make sure a node IS running | |
if ! relx_nodetool "ping" > /dev/null; then | |
echo "Node is not running!" | |
exit 1 | |
fi | |
shift | |
exec "$BINDIR/to_erl" "$PIPE_DIR" | |
;; | |
remote_console) | |
# Make sure a node IS running | |
if ! relx_nodetool "ping" > /dev/null; then | |
echo "Node is not running!" | |
exit 1 | |
fi | |
shift | |
relx_rem_sh | |
;; | |
upgrade|downgrade|install) | |
if [ -z "$2" ]; then | |
echo "Missing package argument" | |
echo "Usage: $REL_NAME $1 {package base name}" | |
echo "NOTE {package base name} MUST NOT include the .tar.gz suffix" | |
exit 1 | |
fi | |
# Make sure a node IS running | |
if ! relx_nodetool "ping" > /dev/null; then | |
echo "Node is not running!" | |
exit 1 | |
fi | |
exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \ | |
"install" "$REL_NAME" "$NAME" "$COOKIE" "$2" | |
;; | |
unpack) | |
if [ -z "$2" ]; then | |
echo "Missing package argument" | |
echo "Usage: $REL_NAME $1 {package base name}" | |
echo "NOTE {package base name} MUST NOT include the .tar.gz suffix" | |
exit 1 | |
fi | |
# Make sure a node IS running | |
if ! relx_nodetool "ping" > /dev/null; then | |
echo "Node is not running!" | |
exit 1 | |
fi | |
exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \ | |
"unpack" "$REL_NAME" "$NAME" "$COOKIE" "$2" | |
;; | |
console|console_clean|console_boot) | |
# .boot file typically just $REL_NAME (ie, the app name) | |
# however, for debugging, sometimes start_clean.boot is useful. | |
# For e.g. 'setup', one may even want to name another boot script. | |
case "$1" in | |
console) | |
if [ -f "$REL_DIR/$REL_NAME.boot" ]; then | |
BOOTFILE="$REL_DIR/$REL_NAME" | |
else | |
BOOTFILE="$REL_DIR/start" | |
fi | |
;; | |
console_clean) | |
BOOTFILE="$ROOTDIR/bin/start_clean" | |
;; | |
console_boot) | |
shift | |
BOOTFILE="$1" | |
shift | |
;; | |
esac | |
# Setup beam-required vars | |
EMU="beam" | |
PROGNAME="${0#*/}" | |
export EMU | |
export PROGNAME | |
# Store passed arguments since they will be erased by `set` | |
ARGS="$@" | |
# Build an array of arguments to pass to exec later on | |
# Build it here because this command will be used for logging. | |
set -- "$BINDIR/erlexec" -boot "$BOOTFILE" \ | |
-boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \ | |
-env ERL_LIBS "$REL_DIR/lib" -config "$RELX_CONFIG_PATH" \ | |
-args_file "$VMARGS_PATH" | |
# Dump environment info for logging purposes | |
echo "Exec: $@" -- ${1+$ARGS} | |
echo "Root: $ROOTDIR" | |
# Log the startup | |
echo "$RELEASE_ROOT_DIR" | |
logger -t "$REL_NAME[$$]" "Starting up" | |
# Start the VM | |
exec "$@" -- ${1+$ARGS} | |
;; | |
foreground) | |
# start up the release in the foreground for use by runit | |
# or other supervision services | |
[ -f "$REL_DIR/$REL_NAME.boot" ] && BOOTFILE="$REL_NAME" || BOOTFILE=start | |
FOREGROUNDOPTIONS="-noshell -noinput +Bd" | |
# Setup beam-required vars | |
EMU=beam | |
PROGNAME="${0#*/}" | |
export EMU | |
export PROGNAME | |
# Store passed arguments since they will be erased by `set` | |
ARGS="$@" | |
# Build an array of arguments to pass to exec later on | |
# Build it here because this command will be used for logging. | |
set -- "$BINDIR/erlexec" $FOREGROUNDOPTIONS \ | |
-boot "$REL_DIR/$BOOTFILE" -mode "$CODE_LOADING_MODE" -config "$RELX_CONFIG_PATH" \ | |
-boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \ | |
-args_file "$VMARGS_PATH" | |
# Dump environment info for logging purposes | |
echo "Exec: $@" -- ${1+$ARGS} | |
echo "Root: $ROOTDIR" | |
# Start the VM | |
exec "$@" -- ${1+$ARGS} | |
;; | |
rpc) | |
# Make sure a node IS running | |
if ! relx_nodetool "ping" > /dev/null; then | |
echo "Node is not running!" | |
exit 1 | |
fi | |
shift | |
relx_nodetool rpc $@ | |
;; | |
rpcterms) | |
# Make sure a node IS running | |
if ! relx_nodetool "ping" > /dev/null; then | |
echo "Node is not running!" | |
exit 1 | |
fi | |
shift | |
relx_nodetool rpcterms $@ | |
;; | |
*) | |
echo "Usage: $REL_NAME {start|start_boot <file>|foreground|stop|restart|reboot|pid|ping|console|console_clean|console_boot <file>|attach|remote_console|upgrade|escript|rpc|rpcterms}" | |
exit 1 | |
;; | |
esac | |
exit 0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
set -e | |
SCRIPT_DIR="$(dirname "$0")" | |
RELEASE_ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" | |
REL_NAME="chatroom_release" | |
REL_VSN="1" | |
ERTS_VSN="6.4" | |
CODE_LOADING_MODE="${CODE_LOADING_MODE:-embedded}" | |
REL_DIR="$RELEASE_ROOT_DIR/releases/$REL_VSN" | |
ERL_OPTS="" | |
RUNNER_LOG_DIR="${RUNNER_LOG_DIR:-$RELEASE_ROOT_DIR/log}" | |
find_erts_dir() { | |
local erts_dir="$RELEASE_ROOT_DIR/erts-$ERTS_VSN" | |
if [ -d "$erts_dir" ]; then | |
ERTS_DIR="$erts_dir"; | |
ROOTDIR="$RELEASE_ROOT_DIR" | |
else | |
local erl="$(which erl)" | |
code="io:format(\"~s\", [code:root_dir()]), halt()." | |
local erl_root="$("$erl" -noshell -eval "$code")" | |
ERTS_DIR="$erl_root/erts-$ERTS_VSN" | |
ROOTDIR="$erl_root" | |
fi | |
} | |
# Get node pid | |
relx_get_pid() { | |
if output="$(relx_nodetool rpcterms os getpid)" | |
then | |
echo "$output" | sed -e 's/"//g' | |
return 0 | |
else | |
echo "$output" | |
return 1 | |
fi | |
} | |
relx_get_longname() { | |
id="longname$(relx_gen_id)-${NAME}" | |
"$BINDIR/erl" -boot start_clean -eval 'io:format("~s~n", [node()]), halt()' -noshell -name $id | sed -e 's/.*@//g' | |
} | |
# Connect to a remote node | |
relx_rem_sh() { | |
# Generate a unique id used to allow multiple remsh to the same node | |
# transparently | |
id="remsh$(relx_gen_id)-${NAME}" | |
# Get the node's ticktime so that we use the same thing. | |
TICKTIME="$(relx_nodetool rpcterms net_kernel get_net_ticktime)" | |
# Setup remote shell command to control node | |
exec "$BINDIR/erl" "$NAME_TYPE" "$id" -remsh "$NAME" -boot start_clean \ | |
-boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \ | |
-setcookie "$COOKIE" -kernel net_ticktime $TICKTIME | |
} | |
# Generate a random id | |
relx_gen_id() { | |
od -X /dev/urandom | head -n1 | awk '{print $2}' | |
} | |
# Control a node | |
relx_nodetool() { | |
command="$1"; shift | |
"$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \ | |
-setcookie "$COOKIE" "$command" $@ | |
} | |
# Run an escript in the node's environment | |
relx_escript() { | |
shift; scriptpath="$1"; shift | |
export RELEASE_ROOT_DIR | |
"$ERTS_DIR/bin/escript" "$ROOTDIR/$scriptpath" $@ | |
} | |
# Output a start command for the last argument of run_erl | |
relx_start_command() { | |
printf "exec \"%s\" \"%s\"" "$RELEASE_ROOT_DIR/bin/$REL_NAME" \ | |
"$START_OPTION" | |
} | |
# Use $CWD/vm.args if exists, otherwise releases/VSN/vm.args | |
if [ -z "$VMARGS_PATH" ]; then | |
if [ -f "$RELEASE_ROOT_DIR/vm.args" ]; then | |
VMARGS_PATH="$RELEASE_ROOT_DIR/vm.args" | |
USE_DIR="$RELEASE_ROOT_DIR" | |
else | |
USE_DIR="$REL_DIR" | |
VMARGS_PATH="$REL_DIR/vm.args" | |
fi | |
fi | |
if [ $RELX_REPLACE_OS_VARS ]; then | |
awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < $VMARGS_PATH > $VMARGS_PATH.2.config | |
VMARGS_PATH=$VMARGS_PATH.2.config | |
fi | |
# Make sure log directory exists | |
mkdir -p "$RUNNER_LOG_DIR" | |
if [ -z "$RELX_CONFIG_PATH" ]; then | |
if [ -f "$USE_DIR/sys.config" ]; then | |
RELX_CONFIG_PATH="$USE_DIR/sys.config" | |
else | |
RELX_CONFIG_PATH="$REL_DIR/sys.config" | |
fi | |
fi | |
if [ $RELX_REPLACE_OS_VARS ]; then | |
awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < $RELX_CONFIG_PATH > $RELX_CONFIG_PATH.2.config | |
RELX_CONFIG_PATH=$RELX_CONFIG_PATH.2.config | |
fi | |
# Extract the target node name from node.args | |
NAME_ARG=$(egrep '^-s?name' "$VMARGS_PATH") | |
if [ -z "$NAME_ARG" ]; then | |
echo "vm.args needs to have either -name or -sname parameter." | |
exit 1 | |
fi | |
# Extract the name type and name from the NAME_ARG for REMSH | |
NAME_TYPE="$(echo "$NAME_ARG" | awk '{print $1}')" | |
NAME="$(echo "$NAME_ARG" | awk '{print $2}')" | |
PIPE_DIR="${PIPE_DIR:-/tmp/erl_pipes/$NAME/}" | |
# Extract the target cookie | |
COOKIE_ARG="$(grep '^-setcookie' "$VMARGS_PATH")" | |
if [ -z "$COOKIE_ARG" ]; then | |
echo "vm.args needs to have a -setcookie parameter." | |
exit 1 | |
fi | |
# Extract cookie name from COOKIE_ARG | |
COOKIE="$(echo "$COOKIE_ARG" | awk '{print $2}')" | |
find_erts_dir | |
export ROOTDIR="$RELEASE_ROOT_DIR" | |
export BINDIR="$ERTS_DIR/bin" | |
export EMU="beam" | |
export PROGNAME="erl" | |
export LD_LIBRARY_PATH="$ERTS_DIR/lib:$LD_LIBRARY_PATH" | |
ERTS_LIB_DIR="$ERTS_DIR/../lib" | |
cd "$ROOTDIR" | |
# User can specify an sname without @hostname | |
# This will fail when creating remote shell | |
# So here we check for @ and add @hostname if missing | |
case $NAME in | |
*@*) | |
# Nothing to do | |
;; | |
*) | |
# Add @hostname | |
case $NAME_TYPE in | |
-sname) | |
NAME=$NAME@`hostname -s` | |
;; | |
-name) | |
NAME=$NAME@$(relx_get_longname) | |
;; | |
esac | |
;; | |
esac | |
# Check the first argument for instructions | |
case "$1" in | |
start|start_boot) | |
# Make sure there is not already a node running | |
#RES=`$NODETOOL ping` | |
#if [ "$RES" = "pong" ]; then | |
# echo "Node is already running!" | |
# exit 1 | |
#fi | |
# Save this for later. | |
CMD=$1 | |
case "$1" in | |
start) | |
shift | |
START_OPTION="console" | |
HEART_OPTION="start" | |
;; | |
start_boot) | |
shift | |
START_OPTION="console_boot" | |
HEART_OPTION="start_boot" | |
;; | |
esac | |
RUN_PARAM="$@" | |
# Set arguments for the heart command | |
set -- "$SCRIPT_DIR/$REL_NAME" "$HEART_OPTION" | |
[ "$RUN_PARAM" ] && set -- "$@" "$RUN_PARAM" | |
# Export the HEART_COMMAND | |
HEART_COMMAND="$RELEASE_ROOT_DIR/bin/$REL_NAME $CMD" | |
export HEART_COMMAND | |
mkdir -p "$PIPE_DIR" | |
"$BINDIR/run_erl" -daemon "$PIPE_DIR" "$RUNNER_LOG_DIR" \ | |
"$(relx_start_command)" | |
;; | |
stop) | |
# Wait for the node to completely stop... | |
PID="$(relx_get_pid)" | |
if ! relx_nodetool "stop"; then | |
exit 1 | |
fi | |
while $(kill -0 "$PID" 2>/dev/null); | |
do | |
sleep 1 | |
done | |
;; | |
restart) | |
## Restart the VM without exiting the process | |
if ! relx_nodetool "restart"; then | |
exit 1 | |
fi | |
;; | |
reboot) | |
## Restart the VM completely (uses heart to restart it) | |
if ! relx_nodetool "reboot"; then | |
exit 1 | |
fi | |
;; | |
pid) | |
## Get the VM's pid | |
if ! relx_get_pid; then | |
exit 1 | |
fi | |
;; | |
ping) | |
## See if the VM is alive | |
if ! relx_nodetool "ping"; then | |
exit 1 | |
fi | |
;; | |
escript) | |
## Run an escript under the node's environment | |
if ! relx_escript $@; then | |
exit 1 | |
fi | |
;; | |
attach) | |
# Make sure a node IS running | |
if ! relx_nodetool "ping" > /dev/null; then | |
echo "Node is not running!" | |
exit 1 | |
fi | |
shift | |
exec "$BINDIR/to_erl" "$PIPE_DIR" | |
;; | |
remote_console) | |
# Make sure a node IS running | |
if ! relx_nodetool "ping" > /dev/null; then | |
echo "Node is not running!" | |
exit 1 | |
fi | |
shift | |
relx_rem_sh | |
;; | |
upgrade|downgrade|install) | |
if [ -z "$2" ]; then | |
echo "Missing package argument" | |
echo "Usage: $REL_NAME $1 {package base name}" | |
echo "NOTE {package base name} MUST NOT include the .tar.gz suffix" | |
exit 1 | |
fi | |
# Make sure a node IS running | |
if ! relx_nodetool "ping" > /dev/null; then | |
echo "Node is not running!" | |
exit 1 | |
fi | |
exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \ | |
"install" "$REL_NAME" "$NAME" "$COOKIE" "$2" | |
;; | |
unpack) | |
if [ -z "$2" ]; then | |
echo "Missing package argument" | |
echo "Usage: $REL_NAME $1 {package base name}" | |
echo "NOTE {package base name} MUST NOT include the .tar.gz suffix" | |
exit 1 | |
fi | |
# Make sure a node IS running | |
if ! relx_nodetool "ping" > /dev/null; then | |
echo "Node is not running!" | |
exit 1 | |
fi | |
exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \ | |
"unpack" "$REL_NAME" "$NAME" "$COOKIE" "$2" | |
;; | |
console|console_clean|console_boot) | |
# .boot file typically just $REL_NAME (ie, the app name) | |
# however, for debugging, sometimes start_clean.boot is useful. | |
# For e.g. 'setup', one may even want to name another boot script. | |
case "$1" in | |
console) | |
if [ -f "$REL_DIR/$REL_NAME.boot" ]; then | |
BOOTFILE="$REL_DIR/$REL_NAME" | |
else | |
BOOTFILE="$REL_DIR/start" | |
fi | |
;; | |
console_clean) | |
BOOTFILE="$ROOTDIR/bin/start_clean" | |
;; | |
console_boot) | |
shift | |
BOOTFILE="$1" | |
shift | |
;; | |
esac | |
# Setup beam-required vars | |
EMU="beam" | |
PROGNAME="${0#*/}" | |
export EMU | |
export PROGNAME | |
# Store passed arguments since they will be erased by `set` | |
ARGS="$@" | |
# Build an array of arguments to pass to exec later on | |
# Build it here because this command will be used for logging. | |
set -- "$BINDIR/erlexec" -boot "$BOOTFILE" \ | |
-boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \ | |
-env ERL_LIBS "$REL_DIR/lib" -config "$RELX_CONFIG_PATH" \ | |
-args_file "$VMARGS_PATH" | |
# Dump environment info for logging purposes | |
echo "Exec: $@" -- ${1+$ARGS} | |
echo "Root: $ROOTDIR" | |
# Log the startup | |
echo "$RELEASE_ROOT_DIR" | |
logger -t "$REL_NAME[$$]" "Starting up" | |
# Start the VM | |
exec "$@" -- ${1+$ARGS} | |
;; | |
foreground) | |
# start up the release in the foreground for use by runit | |
# or other supervision services | |
[ -f "$REL_DIR/$REL_NAME.boot" ] && BOOTFILE="$REL_NAME" || BOOTFILE=start | |
FOREGROUNDOPTIONS="-noshell -noinput +Bd" | |
# Setup beam-required vars | |
EMU=beam | |
PROGNAME="${0#*/}" | |
export EMU | |
export PROGNAME | |
# Store passed arguments since they will be erased by `set` | |
ARGS="$@" | |
# Build an array of arguments to pass to exec later on | |
# Build it here because this command will be used for logging. | |
set -- "$BINDIR/erlexec" $FOREGROUNDOPTIONS \ | |
-boot "$REL_DIR/$BOOTFILE" -mode "$CODE_LOADING_MODE" -config "$RELX_CONFIG_PATH" \ | |
-boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \ | |
-args_file "$VMARGS_PATH" | |
# Dump environment info for logging purposes | |
echo "Exec: $@" -- ${1+$ARGS} | |
echo "Root: $ROOTDIR" | |
# Start the VM | |
exec "$@" -- ${1+$ARGS} | |
;; | |
rpc) | |
# Make sure a node IS running | |
if ! relx_nodetool "ping" > /dev/null; then | |
echo "Node is not running!" | |
exit 1 | |
fi | |
shift | |
relx_nodetool rpc $@ | |
;; | |
rpcterms) | |
# Make sure a node IS running | |
if ! relx_nodetool "ping" > /dev/null; then | |
echo "Node is not running!" | |
exit 1 | |
fi | |
shift | |
relx_nodetool rpcterms $@ | |
;; | |
*) | |
echo "Usage: $REL_NAME {start|start_boot <file>|foreground|stop|restart|reboot|pid|ping|console|console_clean|console_boot <file>|attach|remote_console|upgrade|escript|rpc|rpcterms}" | |
exit 1 | |
;; | |
esac | |
exit 0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env escript | |
%%! -noshell -noinput | |
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- | |
%% ex: ft=erlang ts=4 sw=4 et | |
-define(TIMEOUT, 300000). | |
-define(INFO(Fmt,Args), io:format(Fmt,Args)). | |
%% Unpack or upgrade to a new tar.gz release | |
main(["unpack", RelName, NodeName, Cookie, VersionArg]) -> | |
TargetNode = start_distribution(NodeName, Cookie), | |
WhichReleases = which_releases(TargetNode), | |
Version = parse_version(VersionArg), | |
case proplists:get_value(Version, WhichReleases) of | |
undefined -> | |
%% not installed, so unpack tarball: | |
?INFO("Release ~s not found, attempting to unpack releases/~s/~s.tar.gz~n",[Version,Version,RelName]), | |
ReleasePackage = Version ++ "/" ++ RelName, | |
case rpc:call(TargetNode, release_handler, unpack_release, | |
[ReleasePackage], ?TIMEOUT) of | |
{ok, Vsn} -> | |
?INFO("Unpacked successfully: ~p~n", [Vsn]); | |
{error, UnpackReason} -> | |
print_existing_versions(TargetNode), | |
?INFO("Unpack failed: ~p~n",[UnpackReason]), | |
erlang:halt(2) | |
end; | |
old -> | |
%% no need to unpack, has been installed previously | |
?INFO("Release ~s is marked old, switching to it.~n",[Version]); | |
unpacked -> | |
?INFO("Release ~s is already unpacked, now installing.~n",[Version]); | |
current -> | |
?INFO("Release ~s is already installed and current. Making permanent.~n",[Version]); | |
permanent -> | |
?INFO("Release ~s is already installed, and set permanent.~n",[Version]) | |
end; | |
main(["install", RelName, NodeName, Cookie, VersionArg]) -> | |
TargetNode = start_distribution(NodeName, Cookie), | |
WhichReleases = which_releases(TargetNode), | |
Version = parse_version(VersionArg), | |
case proplists:get_value(Version, WhichReleases) of | |
undefined -> | |
%% not installed, so unpack tarball: | |
?INFO("Release ~s not found, attempting to unpack releases/~s/~s.tar.gz~n",[Version,Version,RelName]), | |
ReleasePackage = Version ++ "/" ++ RelName, | |
case rpc:call(TargetNode, release_handler, unpack_release, | |
[ReleasePackage], ?TIMEOUT) of | |
{ok, Vsn} -> | |
?INFO("Unpacked successfully: ~p~n", [Vsn]), | |
install_and_permafy(TargetNode, RelName, Vsn); | |
{error, UnpackReason} -> | |
print_existing_versions(TargetNode), | |
?INFO("Unpack failed: ~p~n",[UnpackReason]), | |
erlang:halt(2) | |
end; | |
old -> | |
%% no need to unpack, has been installed previously | |
?INFO("Release ~s is marked old, switching to it.~n",[Version]), | |
install_and_permafy(TargetNode, RelName, Version); | |
unpacked -> | |
?INFO("Release ~s is already unpacked, now installing.~n",[Version]), | |
install_and_permafy(TargetNode, RelName, Version); | |
current -> %% installed and in-use, just needs to be permanent | |
?INFO("Release ~s is already installed and current. Making permanent.~n",[Version]), | |
permafy(TargetNode, RelName, Version); | |
permanent -> | |
?INFO("Release ~s is already installed, and set permanent.~n",[Version]) | |
end; | |
main(_) -> | |
erlang:halt(1). | |
parse_version(V) when is_list(V) -> | |
hd(string:tokens(V,"/")). | |
install_and_permafy(TargetNode, RelName, Vsn) -> | |
case rpc:call(TargetNode, release_handler, check_install_release, [Vsn], ?TIMEOUT) of | |
{ok, _OtherVsn, _Desc} -> | |
ok; | |
{error, Reason} -> | |
?INFO("ERROR: release_handler:check_install_release failed: ~p~n",[Reason]), | |
erlang:halt(3) | |
end, | |
case rpc:call(TargetNode, release_handler, install_release, [Vsn], ?TIMEOUT) of | |
{ok, _, _} -> | |
?INFO("Installed Release: ~s~n", [Vsn]), | |
permafy(TargetNode, RelName, Vsn), | |
ok; | |
{error, {no_such_release, Vsn}} -> | |
VerList = | |
iolist_to_binary( | |
[io_lib:format("* ~s\t~s~n",[V,S]) || {V,S} <- which_releases(TargetNode)]), | |
?INFO("Installed versions:~n~s", [VerList]), | |
?INFO("ERROR: Unable to revert to '~s' - not installed.~n", [Vsn]), | |
erlang:halt(2) | |
end. | |
permafy(TargetNode, RelName, Vsn) -> | |
ok = rpc:call(TargetNode, release_handler, make_permanent, [Vsn], ?TIMEOUT), | |
file:copy(filename:join(["bin", RelName++"-"++Vsn]), | |
filename:join(["bin", RelName])), | |
?INFO("Made release permanent: ~p~n", [Vsn]), | |
ok. | |
which_releases(TargetNode) -> | |
R = rpc:call(TargetNode, release_handler, which_releases, [], ?TIMEOUT), | |
[ {V, S} || {_,V,_, S} <- R ]. | |
print_existing_versions(TargetNode) -> | |
VerList = iolist_to_binary([ | |
io_lib:format("* ~s\t~s~n",[V,S]) | |
|| {V,S} <- which_releases(TargetNode) ]), | |
?INFO("Installed versions:~n~s", [VerList]). | |
start_distribution(NodeName, Cookie) -> | |
MyNode = make_script_node(NodeName), | |
{ok, _Pid} = net_kernel:start([MyNode, longnames]), | |
erlang:set_cookie(node(), list_to_atom(Cookie)), | |
TargetNode = list_to_atom(NodeName), | |
case {net_kernel:connect_node(TargetNode), | |
net_adm:ping(TargetNode)} of | |
{true, pong} -> | |
ok; | |
{_, pang} -> | |
io:format("Node ~p not responding to pings.\n", [TargetNode]), | |
erlang:halt(1) | |
end, | |
{ok, Cwd} = file:get_cwd(), | |
ok = rpc:call(TargetNode, file, set_cwd, [Cwd], ?TIMEOUT), | |
TargetNode. | |
make_script_node(Node) -> | |
[Name, Host] = string:tokens(Node, "@"), | |
list_to_atom(lists:concat([Name, "_upgrader_", os:getpid(), "@", Host])). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- | |
%% ex: ft=erlang ts=4 sw=4 et | |
%% ------------------------------------------------------------------- | |
%% | |
%% nodetool: Helper Script for interacting with live nodes | |
%% | |
%% ------------------------------------------------------------------- | |
main(Args) -> | |
ok = start_epmd(), | |
%% Extract the args | |
{RestArgs, TargetNode} = process_args(Args, [], undefined), | |
%% See if the node is currently running -- if it's not, we'll bail | |
case {net_kernel:hidden_connect_node(TargetNode), net_adm:ping(TargetNode)} of | |
{true, pong} -> | |
ok; | |
{_, pang} -> | |
io:format("Node ~p not responding to pings.\n", [TargetNode]), | |
halt(1) | |
end, | |
case RestArgs of | |
["ping"] -> | |
%% If we got this far, the node already responsed to a ping, so just dump | |
%% a "pong" | |
io:format("pong\n"); | |
["stop"] -> | |
io:format("~p\n", [rpc:call(TargetNode, init, stop, [], 60000)]); | |
["restart"] -> | |
io:format("~p\n", [rpc:call(TargetNode, init, restart, [], 60000)]); | |
["reboot"] -> | |
io:format("~p\n", [rpc:call(TargetNode, init, reboot, [], 60000)]); | |
["rpc", Module, Function | RpcArgs] -> | |
case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function), | |
[RpcArgs], 60000) of | |
ok -> | |
ok; | |
{badrpc, Reason} -> | |
io:format("RPC to ~p failed: ~p\n", [TargetNode, Reason]), | |
halt(1); | |
_ -> | |
halt(1) | |
end; | |
["rpcterms", Module, Function | ArgsAsString] -> | |
case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function), | |
consult(lists:flatten(ArgsAsString)), 60000) of | |
{badrpc, Reason} -> | |
io:format("RPC to ~p failed: ~p\n", [TargetNode, Reason]), | |
halt(1); | |
Other -> | |
io:format("~p\n", [Other]) | |
end; | |
Other -> | |
io:format("Other: ~p\n", [Other]), | |
io:format("Usage: nodetool {ping|stop|restart|reboot}\n") | |
end, | |
net_kernel:stop(). | |
process_args([], Acc, TargetNode) -> | |
{lists:reverse(Acc), TargetNode}; | |
process_args(["-setcookie", Cookie | Rest], Acc, TargetNode) -> | |
erlang:set_cookie(node(), list_to_atom(Cookie)), | |
process_args(Rest, Acc, TargetNode); | |
process_args(["-name", TargetName | Rest], Acc, _) -> | |
ThisNode = append_node_suffix(TargetName, "_maint_"), | |
{ok, _} = net_kernel:start([ThisNode, longnames]), | |
process_args(Rest, Acc, nodename(TargetName)); | |
process_args(["-sname", TargetName | Rest], Acc, _) -> | |
ThisNode = append_node_suffix(TargetName, "_maint_"), | |
{ok, _} = net_kernel:start([ThisNode, shortnames]), | |
process_args(Rest, Acc, nodename(TargetName)); | |
process_args([Arg | Rest], Acc, Opts) -> | |
process_args(Rest, [Arg | Acc], Opts). | |
start_epmd() -> | |
[] = os:cmd("\"" ++ epmd_path() ++ "\" -daemon"), | |
ok. | |
epmd_path() -> | |
ErtsBinDir = filename:dirname(escript:script_name()), | |
Name = "epmd", | |
case os:find_executable(Name, ErtsBinDir) of | |
false -> | |
case os:find_executable(Name) of | |
false -> | |
io:format("Could not find epmd.~n"), | |
halt(1); | |
GlobalEpmd -> | |
GlobalEpmd | |
end; | |
Epmd -> | |
Epmd | |
end. | |
nodename(Name) -> | |
case string:tokens(Name, "@") of | |
[_Node, _Host] -> | |
list_to_atom(Name); | |
[Node] -> | |
[_, Host] = string:tokens(atom_to_list(node()), "@"), | |
list_to_atom(lists:concat([Node, "@", Host])) | |
end. | |
append_node_suffix(Name, Suffix) -> | |
case string:tokens(Name, "@") of | |
[Node, Host] -> | |
list_to_atom(lists:concat([Node, Suffix, os:getpid(), "@", Host])); | |
[Node] -> | |
list_to_atom(lists:concat([Node, Suffix, os:getpid()])) | |
end. | |
%% | |
%% Given a string or binary, parse it into a list of terms, ala file:consult/0 | |
%% | |
consult(Str) when is_list(Str) -> | |
consult([], Str, []); | |
consult(Bin) when is_binary(Bin)-> | |
consult([], binary_to_list(Bin), []). | |
consult(Cont, Str, Acc) -> | |
case erl_scan:tokens(Cont, Str, 0) of | |
{done, Result, Remaining} -> | |
case Result of | |
{ok, Tokens, _} -> | |
{ok, Term} = erl_parse:parse_term(Tokens), | |
consult([], Remaining, [Term | Acc]); | |
{eof, _Other} -> | |
lists:reverse(Acc); | |
{error, Info, _} -> | |
{error, Info} | |
end; | |
{more, Cont1} -> | |
consult(Cont1, eof, Acc) | |
end. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
�hd scripthk | |
Erlang/OTPk 17l hd preLoadedl | |
d erl_prim_loaderd erlangd erts_internald initd otp_ring0d prim_evald prim_filed prim_inetd prim_zipd zlibjhd progressd preloadedhd pathl k $ROOT/lib/kernel-3.2/ebink $ROOT/lib/stdlib-2.4/ebinjhd primLoadl d error_handlerjhd kernel_load_completedhd progressd kernel_load_completedhd pathl k $ROOT/lib/kernel-3.2/ebinjhd primLoadl ?d applicationd application_controllerd application_masterd application_starterd authd coded code_serverd disk_logd | |
disk_log_1d disk_log_serverd disk_log_supd dist_acd dist_utild erl_boot_serverd erl_ddlld erl_distributiond erl_epmdd erl_replyd error_loggerd | |
erts_debugd filed file_io_serverd file_serverd gen_sctpd gen_tcpd gen_udpd globald global_groupd global_searchd groupd heartd hipe_unified_loaderd inetd | |
inet6_sctpd inet6_tcpd inet6_tcp_distd inet6_udpd inet_configd inet_dbd inet_dnsd inet_gethost_natived | |
inet_hostsd | |
inet_parsed inet_resd inet_sctpd inet_tcpd inet_tcp_distd inet_udpd kerneld kernel_configd netd net_admd | |
net_kerneld osd pg2d ram_filed rpcd seq_traced standard_errord userd user_drvd user_supd wrap_log_readerjhd pathl k $ROOT/lib/stdlib-2.4/ebinjhd primLoadl Od arrayd base64d beam_libd binaryd cd calendard detsd dets_serverd dets_supd | |
dets_utilsd dets_v8d dets_v9d dictd digraphd digraph_utilsd edlind edlin_expandd eppd erl_bitsd erl_compiled erl_evald erl_expand_recordsd erl_internald erl_lintd erl_parsed erl_posix_msgd erl_ppd erl_scand erl_tard error_logger_file_hd error_logger_tty_hd escriptd etsd eval_bitsd file_sorterd filelibd filenamed gb_setsd gb_treesd gend gen_eventd gen_fsmd | |
gen_serverd iod io_libd io_lib_formatd io_lib_freadd io_lib_prettyd libd listsd log_mf_hd mapsd mathd ms_transformd orddictd ordsetsd otp_internald pgd poold proc_libd proplistsd qlcd qlc_ptd queued randomd red setsd shelld shell_defaultd slaved sofsd stringd | |
supervisord supervisor_bridged sysd timerd unicoded win32regd zipjhd progressd modules_loadedhd pathl k $ROOT/lib/kernel-3.2/ebink $ROOT/lib/stdlib-2.4/ebinjhd kernelProcessd hearthd heartd startjhd kernelProcessd error_loggerhd error_loggerd | |
start_linkjhd kernelProcessd application_controllerhd application_controllerd startl hd applicationd kernell hd descriptionk ERTS CXC 138 10hd vsnk 3.2hd idjhd modulesl @d applicationd application_controllerd application_masterd application_starterd authd coded code_serverd dist_utild erl_boot_serverd erl_distributiond erl_replyd error_handlerd error_loggerd filed file_serverd file_io_serverd globald global_groupd global_searchd groupd heartd hipe_unified_loaderd inet6_tcpd inet6_tcp_distd inet6_udpd | |
inet6_sctpd inet_configd | |
inet_hostsd inet_gethost_natived inet_tcp_distd kerneld kernel_configd netd net_admd | |
net_kerneld osd ram_filed rpcd userd user_drvd user_supd disk_logd | |
disk_log_1d disk_log_serverd disk_log_supd dist_acd erl_ddlld erl_epmdd | |
erts_debugd gen_tcpd gen_udpd gen_sctpd inetd inet_dbd inet_dnsd | |
inet_parsed inet_resd inet_tcpd inet_udpd inet_sctpd pg2d seq_traced standard_errord wrap_log_readerjhd | |
registeredl d application_controllerd erl_replyd authd boot_serverd code_serverd disk_log_serverd disk_log_supd erl_prim_loaderd error_loggerd file_server_2d fixtable_serverd global_groupd global_name_serverd heartd initd kernel_configd | |
kernel_supd | |
net_kerneld net_supd rexd userd os_serverd ddll_serverd erl_epmdd inet_dbd pg2jhd applicationsjhd included_applicationsjhd envl hd error_loggerd ttyjhd maxTd infinityhd maxPd infinityhd modhd kerneljjjhd progressd init_kernel_startedhd applyhd applicationd loadl hd applicationd stdlibl | |
hd descriptionk ERTS CXC 138 10hd vsnk 2.4hd idjhd modulesl Od arrayd base64d beam_libd binaryd cd calendard detsd dets_serverd dets_supd | |
dets_utilsd dets_v8d dets_v9d dictd digraphd digraph_utilsd edlind edlin_expandd eppd eval_bitsd erl_bitsd erl_compiled erl_evald erl_expand_recordsd erl_internald erl_lintd erl_parsed erl_posix_msgd erl_ppd erl_scand erl_tard error_logger_file_hd error_logger_tty_hd escriptd etsd file_sorterd filelibd filenamed gb_treesd gb_setsd gend gen_eventd gen_fsmd | |
gen_serverd iod io_libd io_lib_formatd io_lib_freadd io_lib_prettyd libd listsd log_mf_hd mapsd mathd ms_transformd orddictd ordsetsd otp_internald pgd poold proc_libd proplistsd qlcd qlc_ptd queued randomd red setsd shelld shell_defaultd slaved sofsd stringd | |
supervisord supervisor_bridged sysd timerd unicoded win32regd zipjhd | |
registeredl d timer_serverd rsh_starterd take_over_monitord pool_masterd detsjhd applicationsl d kerneljhd included_applicationsjhd envjhd maxTd infinityhd maxPd infinityjjhd progressd applications_loadedhd applyhd applicationd | |
start_bootl d kerneld permanentjhd applyhd applicationd | |
start_bootl d stdlibd permanentjhd applyhd cd erlangrcjhd progressd startedj |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PROJECT = chatroom | |
DEPS = cowboy | |
include erlang.mk |
This file has been truncated, but you can view the full file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
���� � � � H __PAGEZERO � __TEXT �" |