50
51
register(?NAME,Id),
54
%% Return the pid of the shell process.
55
%% Note: We can't ask the user process for this info since it
56
%% may be busy waiting for data from the port.
58
case process_info(User, dictionary) of
60
case lists:keysearch(shell, 1, Dict) of
61
{value,Sh={shell,Shell}} when pid(Shell) ->
53
71
server(Pid) when pid(Pid) ->
54
72
process_flag(trap_exit, true),
65
83
case init:get_argument(noshell) of
66
84
%% non-empty list -> noshell
69
87
server_loop(P, queue:new());
71
89
group_leader(self(), self()),
72
catch_loop(P, start_new_shell())
90
catch_loop(P, start_init_shell())
75
93
catch_loop(Port, Shell) ->
116
link_and_save_shell(Shell) ->
121
start_init_shell() ->
122
link_and_save_shell(shell:start(init)).
98
124
start_new_shell() ->
99
Shell = shell:start(),
125
link_and_save_shell(shell:start()).
103
127
server_loop(Port, Q) ->
105
129
{Port,{data,Bytes}} ->
108
case string_chr(Bytes, 7) of
132
case string_chr(Bytes, [7,3]) of
110
134
server_loop(Port, queue:snoc(Q, Bytes));
129
153
%% Check if shell has exited
130
154
{'EXIT',SomePid,What} ->
133
throw({unknown_exit,{SomePid,What},Q});
157
server_loop(Port, Q); % Ignore
135
server_loop(Port, Q) % Ignore
159
throw({unknown_exit,{SomePid,What},Q})
138
162
_Other -> % Ignore other messages
139
163
server_loop(Port, Q)
282
306
%% Second loop. Pass data to client as long as it wants more.
283
307
%% A ^G in data interrupts loop if 'noshell' is not undefined.
284
308
get_chars_bytes(State, M, F, Xa, Port, Q, Bytes) ->
287
case string_chr(Bytes, 7) of
311
get_chars_apply(State, M, F, Xa, Port, queue:snoc(Q, Bytes));
313
case string_chr(Bytes, [7,3]) of
289
315
get_chars_apply(State, M, F, Xa, Port,
290
316
queue:snoc(Q, Bytes));
295
get_chars_apply(State, M, F, Xa, Port, queue:snoc(Q, Bytes))
298
322
get_chars_apply(State0, M, F, Xa, Port, Q) ->
357
381
err_func(_, F, _) ->
360
%% Search for a character in a list or binary
361
string_chr(Bin, Character) when binary(Bin), integer(Character) ->
362
string_chr_bin(0, Bin, Character);
363
string_chr(List, Character) when list(List), integer(Character) ->
364
string_chr_list(1, List, Character).
384
%% Search for characters in a list or binary
385
string_chr(Bin, Characters) when is_binary(Bin), is_list(Characters) ->
386
string_chr_bin(0, Bin, Characters);
387
string_chr(List, Characters) when is_list(List), is_list(Characters) ->
388
string_chr_list(1, List, Characters).
366
string_chr_bin(I, B, C) when I < size(B) ->
390
string_chr_bin(I, B, Cs) when I < size(B) ->
392
case string_chr_bin_check(I, B, Cs) of
396
string_chr_bin(J, B, Cs)
398
string_chr_bin(_, _, _) ->
401
string_chr_bin_check(I, B, [C|Cs]) ->
369
403
<<_:I/binary,C,_/binary>> ->
372
string_chr_bin(J, B, C)
406
string_chr_bin_check(I, B, Cs)
374
string_chr_bin(_, _, _) ->
408
string_chr_bin_check(_, _, []) ->
411
string_chr_list(I, [C|T], Cs) ->
412
case lists:member(C, Cs) of
416
string_chr_list(I+1, T, Cs)
377
418
string_chr_list(_, [], _) ->
379
string_chr_list(I, [C|_], C) ->
381
string_chr_list(I, [_|T], C) ->
382
string_chr_list(I+1, T, C).
384
421
%% Convert a buffer between list and binary