Disable console bell in FreeBSD

I use Bash and frequently utilize tab completion. On my FreeBSD, when there are multiple options during tab completion, the annoying console bell rings. For C programmers, it is the ‘\a’ that you included in your printf() calls when first learning C to drive others crazy.

To disable it, as root user you can run:

# sysctl hw.syscons.bell=0
hw.syscons.bel;: 1-> 0

Add that command to /etc/sysctl.conf to permanently disable it.  Good riddance!

Erlang Programming Exercise 12-3: The Database Server as an Application

First create an OTP Application directory structure. The work flow resembles something like the following if you’re on UNIX.

cd ~/work/erlang
mkdir ~/work/erlang/chapter12/{src,ebin,include,priv}
cp db_server_otp.erl db_server_sup.erl ~/work/erlang/chapter12/src
cd ~/work/erlang/chapter12/src
erlc *.erl
mv *.beam ../ebin

With the source code and BEAM files ready, now create an app file, db_server_app.erl:

-module(db_server_app).
-export([start/2,stop/1]).
-behavior(application).

start(_Type, _StartArgs) ->
    db_server_sup:start().

stop(_State) ->
    ok.

Compile this code and then move the BEAM file to the ebin folder. Create an application resource file describing the application, db_server.app in the ebin folder:

{application,
 db_server,
 [{description, "Erlang Prgramming Ch. 12 DB Server"},
  {vsn, "1.0"},
  {modules, [db_server_otp, db_server_sup, db_server_app]},
  {registered, [db_server_sup]},
  {applications, [kernel, stdlib]},
  {env, []},
  {mod, {db_server_app, []}}
 ]
}.

The final directory structure should look like this:

~/work/erlang/chapter12$ ls -1
ebin
include
priv
src
~/work/erlang/chapter12$ ls -1 ebin
db_server.app
db_server_app.beam
db_server_otp.beam
db_server_sup.beam
~/work/erlang/chapter12$ ls -1 src
db_server_app.erl
db_server_otp.erl
db_server_sup.erl

With the BEAM files and app files in the ebin directory, the application can now be tested with the Erlang shell.

Erlang R13B03 (erts-5.7.4)  [64-bit] [smp:8:2] [rq:8] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.7.4  (abort with ^G)
1> code:add_path("/home/bryan/work/erlang/chapter12/ebin").
true
2> application:start(db_server).                               
ok
3> db_server_otp:write("Ted", "7").
ok
4> db_server_otp:read("Ted").
{ok,"7"}
5> application:stop(db_server).
ok

=INFO REPORT==== 3-Nov-2011::16:32:08 ===
    application: db_server
    exited: stopped
    type: temporary
6> whereis(db_server_sup).
undefined

Success! (Note: this was much easier than the first time I tried to get a Tomcat servlet working…)

Erlang Proramming Exercise 12-2: Supervising the Database Server


-module(db_server_sup).
-export([start/0,init/1]).
-behavior(supervisor).

start() ->
    supervisor:start_link({local, ?MODULE}, ?MODULE, []).

init(_Arguments) ->
    DbServerOtp = {db_server_otp,                %% Id
                   {db_server_otp, start, []},   %% child process
                   permanent,                    %% restart 
                   30000,                        %% shutdown (ms)
                   worker,                       %% type
                   [db_server_otp]},             %% required modules
    {ok, 
     {{one_for_all,           %% terminate all children and restart
       5,                     %% max of n restarts in MaxSeconds
       3600},                 %% MaxSeconds (s)
      [DbServerOtp]}}.        %% child process list

EP Exercise 12-1: Database Server Revisited

-module(db_server_otp).
-export([start/0,stop/0]).
-export([write/2,read/1,delete/1,match/1]).
-export([init/1,terminate/2,handle_cast/2,handle_call/3]).
-behavior(gen_server).

%%
%% Operations & Maintenance API
%%

start() ->
    gen_server:start({local, ?MODULE}, ?MODULE, [], []).


stop() ->
    gen_server:cast(?MODULE, stop).

%%
%% DB Server API
%%

write(Key, Data) ->
    gen_server:call(?MODULE, {write, Key, Data}).

read(Key) ->
    gen_server:call(?MODULE, {read, Key}).

delete(Key) ->
    gen_server:call(?MODULE, {delete, Key}).

match(Element) ->
    gen_server:call(?MODULE, {match, Element}).

%%
%% OTP gen_server Callback Functions
%%


init(_Arguments) ->
    {ok, []}.

terminate(_Reason, _LoopData) ->
    ok.

handle_cast(stop, LoopData) ->
    {stop, normal, LoopData}.

handle_call({write, Key, Data}, _From, LoopData) ->
    case lists:keymember(Key, 1, LoopData) of
        true ->
            NewLoopData = lists:keyreplace(Key, 1, LoopData, {Key, Data}),
            Reply = ok;
        false ->
            NewLoopData = LoopData ++ [{Key, Data}],
            Reply = ok
    end,
    {reply, Reply, NewLoopData};
handle_call({read, Key}, _From, LoopData) ->
    case lists:keymember(Key, 1, LoopData) of
        true ->
            {_, Value} = lists:keyfind(Key, 1, LoopData),
            Reply = {ok, Value};
        false ->
            Reply = {error, instance}
    end,
    {reply, Reply, LoopData};

handle_call({delete, Key}, _From, LoopData) ->
    case lists:keymember(Key, 1, LoopData) of
        true ->
            NewLoopData = lists:keydelete(Key, 1, LoopData),
            Reply = ok;
        false ->
            NewLoopData = LoopData,
            Reply = ok
    end,
    {reply, Reply, NewLoopData};

handle_call({match, Element}, _From, LoopData) ->
    Matches = lists:filter(
                fun({_ ,Value}) ->
                  if 
                     Value =:= Element -> true;
                     true -> false
                  end end, 
                LoopData),
   Reply = get_db_keys(Matches, []),
   {reply, Reply, LoopData}.
                                   

get_db_keys([], KeyList) -> KeyList;
get_db_keys(ListOfTuples, KeyList) ->
    [H|T] = ListOfTuples,
    {Key, _} = H,
    get_db_keys(T, KeyList ++ [Key]).

EP Exercise 5-1: A Database Server


-module(db_server).
-export([start/0,stop/0,upgrade/1,code_upgrade/0]).
-export([write/2,read/1,delete/1]).
-export([init/0,loop/1]).
-vsn(1.0).

start() ->
    register(deb_server, spawn(db_server, init, [])).

stop() ->
    db_server ! stop.

upgrade(Data) ->
    db_server ! {upgrade, Data}.

write(Key, Data) ->
    db_server ! {write, Key, Data}.

read(Key) ->
    db_server ! {read, self(), Key},
    receive Reply ->
             Reply end.

delete(Key) ->
    db_server ! {delete, Key}.

code_upgrade(Data) ->
    db_server ! {code_upgrade, Data}.

init() ->
    loop(db:new()).

loop(Db) ->
    receive
        {write, Key, Data} ->
            loop(db:write(Key, Data, Db));
        {read, Pid, Key} ->
            Pid ! db:read(Key, Db),
            loop(Db);
        {delete, Key} ->
            loop(db:delete(Key, Db));
        {upgrade, Data} ->
            NewDb = db:convert(Data, Db),
            db_server:loop(NewDb);
        code_upgrade ->
            loop(db:code_upgrade(Data));
        stop ->
            db:destroy(Db)
    end.

EP Exercise 4-2: The Process Ring

My solution for Exercise 4-2 in the book Erlang Programming

%%
%% Erlang Programming Exercise 4-2
%%

-module(ring).
-export([start/3,create_node/3,stop/0]).

create_node(M,N,Msg) ->
    io:format("Creating node ~w (~w)~n", [N,self()]),
    if  
        N-1 > 0  -> NextPid = spawn(ring,create_node,[M,N-1,Msg]);
        N-1 == 0 -> NextPid = head
    end,
    print_m_times(NextPid,N,Msg,M),
    loop(NextPid).

start(M, N, Msg) ->
    io:format("Spawning ~w nodes!~n",[N]),
    Pid = spawn(ring,create_node,[M,N,Msg]),
    register(head, Pid),
    ok. 

stop() ->
    head ! quit,
    ok. 

loop(NextPid) ->
    receive
        {print, Pid, NodeNum, MsgContents} when Pid /= self() ->  
            io:format("(~w) msg from node ~w: ~s~n",[self(),NodeNum,MsgContents]),
            NextPid ! {print, Pid, NodeNum, MsgContents},
            loop(NextPid);
        quit ->  
            NextPid ! quit,
            io:format("Destroying node (~w)~n", [self()]),
            true
    end.

print_m_times(_,_,_,0) ->
    true;
print_m_times(NextPid,FromNode,Msg,M_Times) ->
    NextPid ! {print, self(), FromNode, Msg},
    print_m_times(NextPid,FromNode,Msg,M_Times-1).

EP Exercise 4-1: An Echo Server

My solution for Exercise 4-1 in the book Erlang Programming.

%%
%% Erlang Programming Exercise 4-1
%%

-module(echo).
-export([start/0,print/1,stop/0,loop/0]).

start() ->
    %% function specified in spawn/3 must be exported !!
    Pid = spawn(echo, loop, []),
    register(echo_server, Pid),
    ok. 

stop() ->
    echo_server ! stop,
    ok. 

print(Term) ->
    echo_server ! {print, Term},
    ok. 

loop() ->
    receive
        {print, Msg} -> io:format("~s~n",[Msg]),
                        loop();
        stop -> true
    end.
Follow

Get every new post delivered to your Inbox.