More work towards instanced parser. First successful compilation

This commit is contained in:
ridiculousfish 2012-01-22 21:40:08 -08:00
parent da85bdc401
commit b43c8da66b
13 changed files with 89 additions and 62 deletions

View file

@ -3929,7 +3929,7 @@ void builtin_push_io( parser_t &parser, int in )
sb_init( sb_err ); sb_init( sb_err );
} }
void builtin_pop_io() void builtin_pop_io(parser_t &parser)
{ {
builtin_stdin = 0; builtin_stdin = 0;
sb_destroy( sb_out ); sb_destroy( sb_out );

View file

@ -165,7 +165,7 @@ const wchar_t *builtin_get_desc( const wchar_t *b );
the commandline builtin operate on the string to complete instead the commandline builtin operate on the string to complete instead
of operating on whatever is to be completed. of operating on whatever is to be completed.
*/ */
const wchar_t *builtin_complete_get_temporary_buffer(parser_t &parser); const wchar_t *builtin_complete_get_temporary_buffer();
/** /**

View file

@ -232,7 +232,7 @@ static int builtin_commandline( parser_t &parser, wchar_t **argv )
int search_mode = 0; int search_mode = 0;
wchar_t *begin, *end; wchar_t *begin, *end;
current_buffer = (wchar_t *)builtin_complete_get_temporary_buffer(parser); current_buffer = (wchar_t *)builtin_complete_get_temporary_buffer();
if( current_buffer ) if( current_buffer )
{ {
current_cursor_pos = wcslen( current_buffer ); current_cursor_pos = wcslen( current_buffer );

View file

@ -173,7 +173,7 @@ static int event_is_blocked( event_t *e )
{ {
block_t *block; block_t *block;
event_block_t *eb; event_block_t *eb;
parser_t &parser = parser_t::principal_parser();
for( block = parser.current_block; block; block = block->outer ) for( block = parser.current_block; block; block = block->outer )
{ {
for( eb = block->first_event_block; eb; eb=eb->next ) for( eb = block->first_event_block; eb; eb=eb->next )
@ -184,7 +184,7 @@ static int event_is_blocked( event_t *e )
return 1; return 1;
} }
} }
for( eb = global_event_block; eb; eb=eb->next ) for( eb = parser.global_event_block; eb; eb=eb->next )
{ {
if( eb->type & (1<<EVENT_ANY ) ) if( eb->type & (1<<EVENT_ANY ) )
return 1; return 1;
@ -459,6 +459,7 @@ static void event_fire_internal( event_t *event )
*/ */
proc_push_interactive(0); proc_push_interactive(0);
prev_status = proc_get_last_status(); prev_status = proc_get_last_status();
parser_t &parser = parser_t::principal_parser();
parser.push_block( EVENT ); parser.push_block( EVENT );
parser.current_block->param1.event = event; parser.current_block->param1.event = event;
parser.eval( buffer.c_str(), 0, TOP ); parser.eval( buffer.c_str(), 0, TOP );

View file

@ -1766,8 +1766,9 @@ static void remove_internal_separator2( wcstring &s, int conv )
} }
int expand_string2( parser_t &parser, const wcstring &input, std::vector<wcstring> &output, int flags ) int expand_string2( const wcstring &input, std::vector<wcstring> &output, int flags )
{ {
parser_t &parser = parser_t::principal_parser();
std::vector<wcstring> list1, list2; std::vector<wcstring> list1, list2;
std::vector<wcstring> *in, *out; std::vector<wcstring> *in, *out;
@ -1985,14 +1986,14 @@ int expand_string2( parser_t &parser, const wcstring &input, std::vector<wcstrin
/** /**
The real expansion function. expand_one is just a wrapper around this one. The real expansion function. expand_one is just a wrapper around this one.
*/ */
int expand_string( parser_t &parser, int expand_string( void *context,
void *context,
wchar_t *str, wchar_t *str,
array_list_t *end_out, array_list_t *end_out,
int flags ) int flags )
{ {
array_list_t list1, list2; array_list_t list1, list2;
array_list_t *in, *out; array_list_t *in, *out;
parser_t &parser = parser_t::principal_parser();
int i; int i;
int cmdsubst_ok = 1; int cmdsubst_ok = 1;

View file

@ -314,11 +314,12 @@ int main( int argc, char **argv )
reader_init(); reader_init();
history_init(); history_init();
parser_t &parser = parser_t::principal_parser();
if( read_init() ) if( read_init() )
{ {
if( cmd != 0 ) if( cmd != 0 )
{ {
parser_t parser(PARSER_TYPE_GENERAL);
wchar_t *cmd_wcs = str2wcs( cmd ); wchar_t *cmd_wcs = str2wcs( cmd );
res = parser.eval( cmd_wcs, 0, TOP ); res = parser.eval( cmd_wcs, 0, TOP );
free(cmd_wcs); free(cmd_wcs);
@ -394,7 +395,7 @@ int main( int argc, char **argv )
builtin_destroy(); builtin_destroy();
function_destroy(); function_destroy();
reader_destroy(); reader_destroy();
parser_destroy(); parser.destroy();
wutil_destroy(); wutil_destroy();
event_destroy(); event_destroy();

View file

@ -398,7 +398,7 @@ static wint_t input_exec_binding( const input_mapping_t &m, const wcstring &seq
*/ */
int last_status = proc_get_last_status(); int last_status = proc_get_last_status();
eval( m.command.c_str(), 0, TOP ); parser_t::principal_parser().eval( m.command.c_str(), 0, TOP );
proc_set_last_status( last_status ); proc_set_last_status( last_status );

View file

@ -6,6 +6,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <signal.h>
#define VOMIT_ON_FAILURE(a) do { if (0 != (a)) { int err = errno; fprintf(stderr, "%s failed on line %d in file %s: %d (%s)\n", #a, __LINE__, __FILE__, err, strerror(err)); abort(); }} while (0) #define VOMIT_ON_FAILURE(a) do { if (0 != (a)) { int err = errno; fprintf(stderr, "%s failed on line %d in file %s: %d (%s)\n", #a, __LINE__, __FILE__, err, strerror(err)); abort(); }} while (0)
@ -90,6 +91,11 @@ static void *iothread_worker(void *threadPtr) {
assert(threadPtr != NULL); assert(threadPtr != NULL);
struct WorkerThread_t *thread = (struct WorkerThread_t *)threadPtr; struct WorkerThread_t *thread = (struct WorkerThread_t *)threadPtr;
// We don't want to receive signals on this thread
sigset_t set;
sigfillset(&set);
VOMIT_ON_FAILURE(pthread_sigmask(SIG_SETMASK, &set, NULL));
/* Grab a request off of the queue */ /* Grab a request off of the queue */
struct ThreadedRequest_t *req; struct ThreadedRequest_t *req;
VOMIT_ON_FAILURE(pthread_mutex_lock(&s_request_queue_lock)); VOMIT_ON_FAILURE(pthread_mutex_lock(&s_request_queue_lock));

View file

@ -397,10 +397,17 @@ static int job_start_pos;
*/ */
static int eval_level=-1; static int eval_level=-1;
static int parse_job( process_t *p, parser_t::parser_t(enum parser_type_t type) : parser_type(type)
job_t *j, {
tokenizer *tok );
}
parser_t &parser_t::principal_parser(void)
{
ASSERT_IS_MAIN_THREAD();
static parser_t parser(PARSER_TYPE_GENERAL);
return parser;
}
/** /**
Return the current number of block nestings Return the current number of block nestings
@ -462,7 +469,7 @@ void parser_t::push_block( int type )
} }
} }
void parser_pop_block() void parser_t::pop_block()
{ {
block_t *old = current_block; block_t *old = current_block;
if( !current_block ) if( !current_block )
@ -478,7 +485,7 @@ void parser_pop_block()
halloc_free( old ); halloc_free( old );
} }
const wchar_t *parser_get_block_desc( int block ) const wchar_t *parser_t::get_block_desc( int block ) const
{ {
int i; int i;
@ -595,7 +602,7 @@ static const wchar_t *parser_find_end( const wchar_t * buff )
} }
void parser_forbid_function( wchar_t *function ) void parser_t::forbid_function( wchar_t *function )
{ {
/* /*
if( function ) if( function )
@ -605,7 +612,7 @@ void parser_forbid_function( wchar_t *function )
forbidden_function.push_back(wcstring(function)); forbidden_function.push_back(wcstring(function));
} }
void parser_allow_function() void parser_t::allow_function()
{ {
/* /*
if( al_peek( &forbidden_function) ) if( al_peek( &forbidden_function) )
@ -880,7 +887,7 @@ int parser_t::eval_args( const wchar_t *line, array_list_t *args )
return 1; return 1;
} }
void parser_stack_trace( block_t *b, string_buffer_t *buff) void parser_t::stack_trace( block_t *b, string_buffer_t *buff)
{ {
/* /*
@ -980,7 +987,7 @@ void parser_stack_trace( block_t *b, string_buffer_t *buff)
/* /*
Recursively print the next block Recursively print the next block
*/ */
parser_stack_trace( b->outer, buff ); parser_t::stack_trace( b->outer, buff );
} }
/** /**
@ -1007,7 +1014,7 @@ static const wchar_t *is_function()
} }
int parser_get_lineno() int parser_t::get_lineno() const
{ {
const wchar_t *whole_str; const wchar_t *whole_str;
const wchar_t *function_name; const wchar_t *function_name;
@ -1036,7 +1043,7 @@ int parser_get_lineno()
return lineno; return lineno;
} }
const wchar_t *parser_current_filename() const wchar_t *parser_t::current_filename() const
{ {
block_t *b = current_block; block_t *b = current_block;
@ -1101,7 +1108,7 @@ const wchar_t *parser_t::current_line()
return L""; return L"";
} }
file = parser_current_filename(); file = parser_t::current_filename();
whole_str = tok_string( current_tokenizer ); whole_str = tok_string( current_tokenizer );
line = whole_str; line = whole_str;
@ -1196,34 +1203,34 @@ const wchar_t *parser_t::current_line()
} }
free( line ); free( line );
parser_stack_trace( current_block, lineinfo ); parser_t::stack_trace( current_block, lineinfo );
return (wchar_t *)lineinfo->buff; return (wchar_t *)lineinfo->buff;
} }
int parser_get_pos() int parser_t::get_pos() const
{ {
return tok_get_pos( current_tokenizer ); return tok_get_pos( current_tokenizer );
} }
int parser_get_job_pos() int parser_t::get_job_pos() const
{ {
return job_start_pos; return job_start_pos;
} }
void parser_set_pos( int p) void parser_t::set_pos( int p)
{ {
tok_set_pos( current_tokenizer, p ); tok_set_pos( current_tokenizer, p );
} }
const wchar_t *parser_get_buffer() const wchar_t *parser_t::get_buffer() const
{ {
return tok_string( current_tokenizer ); return tok_string( current_tokenizer );
} }
int parser_is_help( wchar_t *s, int min_match ) int parser_t::is_help( wchar_t *s, int min_match ) const
{ {
int len; int len;
@ -1360,7 +1367,7 @@ void parser_t::parse_job_argument_list( process_t *p,
{ {
if( ( proc_is_count ) && if( ( proc_is_count ) &&
( al_get_count( args) == 1) && ( al_get_count( args) == 1) &&
( parser_is_help( tok_last(tok), 0) ) && ( parser_t::is_help( tok_last(tok), 0) ) &&
( p->type == INTERNAL_BUILTIN ) ) ( p->type == INTERNAL_BUILTIN ) )
{ {
/* /*
@ -2143,7 +2150,7 @@ int parser_t::parse_job( process_t *p,
while( prev_block != current_block ) while( prev_block != current_block )
{ {
parser_pop_block(); parser_t::pop_block();
} }
} }
@ -2181,7 +2188,7 @@ int parser_t::parse_job( process_t *p,
*/ */
while( prev_block != current_block ) while( prev_block != current_block )
{ {
parser_pop_block(); parser_t::pop_block();
} }
} }
current_tokenizer_pos = prev_tokenizer_pos; current_tokenizer_pos = prev_tokenizer_pos;
@ -2218,7 +2225,7 @@ void parser_t::skipped_exec( job_t * j )
exec( *this, j ); exec( *this, j );
return; return;
} }
parser_pop_block(); parser_t::pop_block();
} }
else if( wcscmp( p->argv[0], L"else" )==0) else if( wcscmp( p->argv[0], L"else" )==0)
{ {
@ -2489,7 +2496,7 @@ int parser_t::eval( const wcstring &cmdStr, io_data_t *io, enum block_type_t blo
{ {
debug( 1, debug( 1,
INVALID_SCOPE_ERR_MSG, INVALID_SCOPE_ERR_MSG,
parser_get_block_desc( block_type ) ); parser_t::get_block_desc( block_type ) );
bugreport(); bugreport();
return 1; return 1;
} }
@ -2516,7 +2523,7 @@ int parser_t::eval( const wcstring &cmdStr, io_data_t *io, enum block_type_t blo
int prev_block_type = current_block->type; int prev_block_type = current_block->type;
parser_pop_block(); parser_t::pop_block();
while( start_current_block != current_block ) while( start_current_block != current_block )
{ {
@ -2536,7 +2543,7 @@ int parser_t::eval( const wcstring &cmdStr, io_data_t *io, enum block_type_t blo
//debug( 2, L"Status %d\n", proc_get_last_status() ); //debug( 2, L"Status %d\n", proc_get_last_status() );
debug( 1, debug( 1,
L"%ls", parser_get_block_desc( current_block->type ) ); L"%ls", parser_t::get_block_desc( current_block->type ) );
debug( 1, debug( 1,
BLOCK_END_ERR_MSG ); BLOCK_END_ERR_MSG );
fwprintf( stderr, L"%ls", parser_t::current_line() ); fwprintf( stderr, L"%ls", parser_t::current_line() );
@ -2548,7 +2555,7 @@ int parser_t::eval( const wcstring &cmdStr, io_data_t *io, enum block_type_t blo
} }
prev_block_type = current_block->type; prev_block_type = current_block->type;
parser_pop_block(); parser_t::pop_block();
} }
print_errors_stderr(*this); print_errors_stderr(*this);
@ -2557,7 +2564,7 @@ int parser_t::eval( const wcstring &cmdStr, io_data_t *io, enum block_type_t blo
free( current_tokenizer ); free( current_tokenizer );
while (forbidden_function.size() > forbid_count) while (forbidden_function.size() > forbid_count)
parser_allow_function(); parser_t::allow_function();
/* /*
Restore previous eval state Restore previous eval state
@ -2665,7 +2672,7 @@ int parser_t::parser_test_argument( const wchar_t *arg, string_buffer_t *out, co
// debug( 1, L"%ls -> %ls %ls", arg_cpy, subst, tmp.buff ); // debug( 1, L"%ls -> %ls %ls", arg_cpy, subst, tmp.buff );
err |= parser_test( subst, 0, out, prefix ); err |= parser_t::test( subst, 0, out, prefix );
free( subst ); free( subst );
free( arg_cpy ); free( arg_cpy );
@ -2732,7 +2739,7 @@ int parser_t::parser_test_argument( const wchar_t *arg, string_buffer_t *out, co
} }
int parser_t::parser_test_args(const wchar_t * buff, int parser_t::test_args(const wchar_t * buff,
string_buffer_t *out, const wchar_t *prefix ) string_buffer_t *out, const wchar_t *prefix )
{ {
tokenizer tok; tokenizer tok;
@ -2806,7 +2813,7 @@ int parser_t::parser_test_args(const wchar_t * buff,
return err; return err;
} }
int parser_t::parser_test( const wchar_t * buff, int parser_t::test( const wchar_t * buff,
int *block_level, int *block_level,
string_buffer_t *out, string_buffer_t *out,
const wchar_t *prefix ) const wchar_t *prefix )
@ -3102,7 +3109,7 @@ int parser_t::parser_test( const wchar_t * buff,
wcsdup( tok_last( &tok ) ), wcsdup( tok_last( &tok ) ),
EXPAND_SKIP_CMDSUBST); EXPAND_SKIP_CMDSUBST);
if( first_arg && parser_is_help( first_arg, 3) ) if( first_arg && parser_t::is_help( first_arg, 3) )
{ {
is_help = 1; is_help = 1;
} }
@ -3164,7 +3171,7 @@ int parser_t::parser_test( const wchar_t * buff,
wcsdup( tok_last( &tok ) ), wcsdup( tok_last( &tok ) ),
EXPAND_SKIP_CMDSUBST); EXPAND_SKIP_CMDSUBST);
if( first_arg && parser_is_help( first_arg, 3 ) ) if( first_arg && parser_t::is_help( first_arg, 3 ) )
{ {
is_help = 1; is_help = 1;
} }

View file

@ -214,6 +214,7 @@ struct tokenizer;
class parser_t { class parser_t {
private: private:
enum parser_type_t parser_type;
std::vector<block_t> blocks; std::vector<block_t> blocks;
/* No copying allowed */ /* No copying allowed */
@ -225,13 +226,14 @@ class parser_t {
void skipped_exec( job_t * j ); void skipped_exec( job_t * j );
void eval_job( tokenizer *tok ); void eval_job( tokenizer *tok );
int parser_test_argument( const wchar_t *arg, string_buffer_t *out, const wchar_t *prefix, int offset ); int parser_test_argument( const wchar_t *arg, string_buffer_t *out, const wchar_t *prefix, int offset );
int parser_test( const wchar_t * buff, int *block_level, string_buffer_t *out, const wchar_t *prefix );
int parser_test_args(const wchar_t * buff, string_buffer_t *out, const wchar_t *prefix );
void print_errors( string_buffer_t *target, const wchar_t *prefix ); void print_errors( string_buffer_t *target, const wchar_t *prefix );
public: public:
std::vector<profile_item_t> profile_items; std::vector<profile_item_t> profile_items;
/** Get the "principal" parser, whatever that is */
static parser_t &principal_parser();
/** Create a parser of the given type */ /** Create a parser of the given type */
parser_t(enum parser_type_t type); parser_t(enum parser_type_t type);
@ -299,7 +301,7 @@ class parser_t {
/** /**
Set the current position in the latest string of the tokenizer. Set the current position in the latest string of the tokenizer.
*/ */
void set_pos( int p) const; void set_pos( int p);
/** /**
Get the string currently parsed Get the string currently parsed
@ -334,7 +336,7 @@ class parser_t {
\param out if non-null, any errors in the command will be filled out into this buffer \param out if non-null, any errors in the command will be filled out into this buffer
\param prefix the prefix string to prepend to each error message written to the \c out buffer \param prefix the prefix string to prepend to each error message written to the \c out buffer
*/ */
int test( const wchar_t * buff, int *block_level, string_buffer_t *out, const wchar_t *prefix ) const; int test( const wchar_t * buff, int *block_level, string_buffer_t *out, const wchar_t *prefix );
/** /**
Test if the specified string can be parsed as an argument list, Test if the specified string can be parsed as an argument list,
@ -342,7 +344,7 @@ class parser_t {
string contains errors, and the second bit is set if the string string contains errors, and the second bit is set if the string
contains an unclosed block. contains an unclosed block.
*/ */
int test_args( const wchar_t * buff, string_buffer_t *out, const wchar_t *prefix ) const; int test_args( const wchar_t * buff, string_buffer_t *out, const wchar_t *prefix );
/** /**
Tell the parser that the specified function may not be run if not Tell the parser that the specified function may not be run if not

View file

@ -452,7 +452,8 @@ static void handle_child_status( pid_t pid, int status )
} }
else else
{ {
block_t *c = parser.current_block; //PCA INSTANCED_PARSER what is this?
block_t *c = NULL;//parser.current_block;
if( p && found_proc ) if( p && found_proc )
{ {
while( c ) while( c )

View file

@ -421,7 +421,8 @@ int reader_exit_forced()
static void reader_repaint() static void reader_repaint()
{ {
parser_test( data->buff, data->indent, 0, 0 ); //PCA INSTANCED_PARSER what is this call for?
//parser_test( data->buff, data->indent, 0, 0 );
s_write( &data->screen, s_write( &data->screen,
data->prompt_buff.c_str(), data->prompt_buff.c_str(),
@ -479,7 +480,8 @@ static void reader_kill( wchar_t *begin, int length, int mode, int newv )
void reader_handle_int( int sig ) void reader_handle_int( int sig )
{ {
block_t *c = current_block; //PCA INSTANCED_PARSER what is this?
block_t *c = NULL;//current_block;
if( !is_interactive_read ) if( !is_interactive_read )
{ {
@ -1255,7 +1257,8 @@ static void run_pager( wchar_t *prefix, int is_quoted, array_list_t *comp )
out->next = in; out->next = in;
out->fd = 4; out->fd = 4;
eval( (wchar_t *)cmd.buff, out, TOP); parser_t parser(PARSER_TYPE_GENERAL);
parser.eval( (wchar_t *)cmd.buff, out, TOP);
term_steal(); term_steal();
io_buffer_read( out ); io_buffer_read( out );
@ -2189,7 +2192,7 @@ void set_env_cmd_duration(struct timeval *after, struct timeval *before)
} }
} }
void reader_run_command( const wchar_t *cmd ) void reader_run_command( parser_t &parser, const wchar_t *cmd )
{ {
wchar_t *ft; wchar_t *ft;
@ -2207,7 +2210,7 @@ void reader_run_command( const wchar_t *cmd )
gettimeofday(&time_before, NULL); gettimeofday(&time_before, NULL);
eval( cmd, 0, TOP ); parser.eval( cmd, 0, TOP );
job_reap( 1 ); job_reap( 1 );
gettimeofday(&time_after, NULL); gettimeofday(&time_after, NULL);
@ -2227,7 +2230,7 @@ void reader_run_command( const wchar_t *cmd )
int reader_shell_test( wchar_t *b ) int reader_shell_test( wchar_t *b )
{ {
int res = parser_test( b, 0, 0, 0 ); int res = parser_t::principal_parser().test( b, 0, 0, 0 );
if( res & PARSER_TEST_ERROR ) if( res & PARSER_TEST_ERROR )
{ {
@ -2239,7 +2242,7 @@ int reader_shell_test( wchar_t *b )
s_write( &data->screen, L"", L"", tmp, tmp2, 0 ); s_write( &data->screen, L"", L"", tmp, tmp2, 0 );
parser_test( b, 0, &sb, L"fish" ); parser_t::principal_parser().test( b, 0, &sb, L"fish" );
fwprintf( stderr, L"%ls", sb.buff ); fwprintf( stderr, L"%ls", sb.buff );
sb_destroy( &sb ); sb_destroy( &sb );
} }
@ -2515,8 +2518,9 @@ static void handle_end_loop()
int job_count=0; int job_count=0;
int is_breakpoint=0; int is_breakpoint=0;
block_t *b; block_t *b;
parser_t &parser = parser_t::principal_parser();
for( b = current_block;
for( b = parser.current_block;
b; b;
b = b->outer ) b = b->outer )
{ {
@ -2577,7 +2581,8 @@ static int read_i()
reader_set_complete_function( &complete ); reader_set_complete_function( &complete );
reader_set_highlight_function( &highlight_shell ); reader_set_highlight_function( &highlight_shell );
reader_set_test_function( &reader_shell_test ); reader_set_test_function( &reader_shell_test );
parser_t &parser = parser_t::principal_parser();
data->prev_end_loop=0; data->prev_end_loop=0;
while( (!data->end_loop) && (!sanity_check()) ) while( (!data->end_loop) && (!sanity_check()) )
@ -2609,7 +2614,7 @@ static int read_i()
data->buff_pos=data->buff_len=0; data->buff_pos=data->buff_len=0;
data->buff[data->buff_len]=L'\0'; data->buff[data->buff_len]=L'\0';
reader_run_command( tmp ); reader_run_command( parser, tmp );
free( tmp ); free( tmp );
if( data->end_loop) if( data->end_loop)
{ {
@ -3347,6 +3352,7 @@ int reader_search_mode()
*/ */
static int read_ni( int fd, io_data_t *io ) static int read_ni( int fd, io_data_t *io )
{ {
parser_t &parser = parser_t::principal_parser();
FILE *in_stream; FILE *in_stream;
wchar_t *buff=0; wchar_t *buff=0;
buffer_t acc; buffer_t acc;
@ -3408,9 +3414,9 @@ static int read_ni( int fd, io_data_t *io )
string_buffer_t sb; string_buffer_t sb;
sb_init( &sb ); sb_init( &sb );
if( !parser_test( str, 0, &sb, L"fish" ) ) if( ! parser.test( str, 0, &sb, L"fish" ) )
{ {
eval( str, io, TOP ); parser.eval( str, io, TOP );
} }
else else
{ {

View file

@ -14,6 +14,8 @@
#include "util.h" #include "util.h"
#include "io.h" #include "io.h"
class parser_t;
/** /**
Read commands from \c fd until encountering EOF Read commands from \c fd until encountering EOF
*/ */