fix redirect headers, postpone i/o errors until calling operation recovers them
parent
87331addba
commit
2c5413cec5
|
@ -3,18 +3,13 @@
|
||||||
- maple-like: press enter at old commands to evaluate there
|
- maple-like: press enter at old commands to evaluate there
|
||||||
- standalone listener input style
|
- standalone listener input style
|
||||||
- add a socket timeout
|
- add a socket timeout
|
||||||
- drop test in http server
|
|
||||||
- jedit bug? +line doesn't always work when switching into an existing
|
- jedit bug? +line doesn't always work when switching into an existing
|
||||||
buffer with a remembered first line
|
buffer with a remembered first line
|
||||||
- jedit bug? ' in noWordSep ignored
|
|
||||||
- word names containing ' not quoted properly
|
|
||||||
- completion: enter no good
|
|
||||||
- completion: don't show automatically
|
|
||||||
- balance needs USE:
|
- balance needs USE:
|
||||||
- postpone errors until actual read/write op
|
|
||||||
- command line arguments
|
- command line arguments
|
||||||
- socket protocol
|
- socket protocol
|
||||||
- irc: stack underflow?
|
- irc: stack underflow?
|
||||||
|
- ignore SIGPIPE
|
||||||
|
|
||||||
+ docs:
|
+ docs:
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
VFSManager.waitForRequests();
|
VFSManager.waitForRequests();
|
||||||
factorEval(view,
|
factorEval(view,
|
||||||
"\""
|
"\""
|
||||||
+ MiscUtilities.charsToEscapes(buffer.path)
|
+ factor.FactorReader.charsToEscapes(buffer.path)
|
||||||
+ "\" run-file");
|
+ "\" run-file");
|
||||||
</CODE>
|
</CODE>
|
||||||
</ACTION>
|
</ACTION>
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
textArea.selectWord();
|
textArea.selectWord();
|
||||||
factorEval(view,
|
factorEval(view,
|
||||||
"\""
|
"\""
|
||||||
+ MiscUtilities.charsToEscapes(
|
+ factor.FactorReader.charsToEscapes(
|
||||||
textArea.selectedText)
|
textArea.selectedText)
|
||||||
+ "\" apropos.");
|
+ "\" apropos.");
|
||||||
</CODE>
|
</CODE>
|
||||||
|
|
|
@ -56,7 +56,7 @@ public class FactorCompletion extends SideKickCompletion
|
||||||
|
|
||||||
public String getLongestPrefix()
|
public String getLongestPrefix()
|
||||||
{
|
{
|
||||||
return "";
|
return MiscUtilities.getLongestPrefix(items,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insert(int index)
|
public void insert(int index)
|
||||||
|
@ -78,7 +78,7 @@ public class FactorCompletion extends SideKickCompletion
|
||||||
|
|
||||||
public boolean handleKeystroke(int selectedIndex, char keyChar)
|
public boolean handleKeystroke(int selectedIndex, char keyChar)
|
||||||
{
|
{
|
||||||
if(keyChar == '\t')
|
if(keyChar == '\t' || keyChar == '\n')
|
||||||
insert(selectedIndex);
|
insert(selectedIndex);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
plugin.factor.jedit.FactorPlugin.activate=defer
|
plugin.factor.jedit.FactorPlugin.activate=defer
|
||||||
|
|
||||||
plugin.factor.jedit.FactorPlugin.name=Factor
|
plugin.factor.jedit.FactorPlugin.name=Factor
|
||||||
plugin.factor.jedit.FactorPlugin.version=0.63
|
plugin.factor.jedit.FactorPlugin.version=0.64
|
||||||
plugin.factor.jedit.FactorPlugin.author=Slava Pestov
|
plugin.factor.jedit.FactorPlugin.author=Slava Pestov
|
||||||
plugin.factor.jedit.FactorPlugin.docs=/doc/plugin.html
|
plugin.factor.jedit.FactorPlugin.docs=/doc/plugin.html
|
||||||
|
|
||||||
plugin.factor.jedit.FactorPlugin.depend.0=jedit 04.02.15.00
|
plugin.factor.jedit.FactorPlugin.depend.0=jedit 04.02.15.00
|
||||||
plugin.factor.jedit.FactorPlugin.depend.1=plugin errorlist.ErrorListPlugin 1.3.2
|
plugin.factor.jedit.FactorPlugin.depend.1=plugin errorlist.ErrorListPlugin 1.3.2
|
||||||
plugin.factor.jedit.FactorPlugin.depend.2=plugin sidekick.SideKickPlugin 0.3
|
plugin.factor.jedit.FactorPlugin.depend.2=plugin sidekick.SideKickPlugin 0.3.1
|
||||||
|
|
||||||
plugin.factor.jedit.FactorPlugin.menu=factor \
|
plugin.factor.jedit.FactorPlugin.menu=factor \
|
||||||
- \
|
- \
|
||||||
|
|
|
@ -168,6 +168,19 @@ public class FactorSideKickParser extends SideKickParser
|
||||||
== ReadTable.WHITESPACE);
|
== ReadTable.WHITESPACE);
|
||||||
} //}}}
|
} //}}}
|
||||||
|
|
||||||
|
//{{{ canCompleteAnywhere() method
|
||||||
|
/**
|
||||||
|
* Returns if completion popups should be shown after any period of
|
||||||
|
* inactivity. Otherwise, they are only shown if explicitly requested
|
||||||
|
* by the user.
|
||||||
|
*
|
||||||
|
* Returns false by default.
|
||||||
|
*/
|
||||||
|
public boolean canCompleteAnywhere()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
} //}}}
|
||||||
|
|
||||||
//{{{ complete() method
|
//{{{ complete() method
|
||||||
/**
|
/**
|
||||||
* Returns completions suitable for insertion at the specified position.
|
* Returns completions suitable for insertion at the specified position.
|
||||||
|
|
|
@ -13,7 +13,7 @@ factorWord(view)
|
||||||
if(textArea.selectionCount == 0)
|
if(textArea.selectionCount == 0)
|
||||||
textArea.selectWord();
|
textArea.selectWord();
|
||||||
return "\""
|
return "\""
|
||||||
+ MiscUtilities.charsToEscapes(textArea.selectedText)
|
+ factor.FactorReader.charsToEscapes(textArea.selectedText)
|
||||||
+ "\" " + factor.FactorReader.unparseObject(data.use)
|
+ "\" " + factor.FactorReader.unparseObject(data.use)
|
||||||
+ " search";
|
+ " search";
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,9 @@ USE: httpd
|
||||||
|
|
||||||
: redirect ( to -- )
|
: redirect ( to -- )
|
||||||
"301 Moved Permanently" "text/plain" response write
|
"301 Moved Permanently" "text/plain" response write
|
||||||
"Location: " write print ;
|
"Location: " write write
|
||||||
|
terpri terpri
|
||||||
|
"The resource has moved." print ;
|
||||||
|
|
||||||
: get-responder ( name -- responder )
|
: get-responder ( name -- responder )
|
||||||
"httpd-responders" get get* ;
|
"httpd-responders" get get* ;
|
||||||
|
|
|
@ -62,6 +62,8 @@ USE: vectors
|
||||||
"Incomparable types: "
|
"Incomparable types: "
|
||||||
"Float format: "
|
"Float format: "
|
||||||
"Signal "
|
"Signal "
|
||||||
|
"Adding I/O task twice on port: "
|
||||||
|
"No I/O tasks"
|
||||||
} ?vector-nth ;
|
} ?vector-nth ;
|
||||||
|
|
||||||
: ?kernel-error ( cons -- error# param )
|
: ?kernel-error ( cons -- error# param )
|
||||||
|
|
|
@ -14,5 +14,7 @@ USE: test
|
||||||
"20 <sbuf> \"foo\" set" eval
|
"20 <sbuf> \"foo\" set" eval
|
||||||
"garbage-collection" eval
|
"garbage-collection" eval
|
||||||
|
|
||||||
[ drop ] [ drop ] catch
|
[
|
||||||
[ drop ] [ drop ] catch
|
[ drop ] [ drop ] catch
|
||||||
|
[ drop ] [ drop ] catch
|
||||||
|
] keep-datastack
|
||||||
|
|
|
@ -59,14 +59,3 @@ void range_error(CELL tagged, CELL index, CELL max)
|
||||||
tag_cons(cons(tag_fixnum(max),F)))));
|
tag_cons(cons(tag_fixnum(max),F)))));
|
||||||
general_error(ERROR_RANGE,tag_cons(c));
|
general_error(ERROR_RANGE,tag_cons(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
void io_error(const char* func)
|
|
||||||
{
|
|
||||||
STRING* function = from_c_string(func);
|
|
||||||
STRING* error = from_c_string(strerror(errno));
|
|
||||||
|
|
||||||
CONS* c = cons(tag_object(function),tag_cons(
|
|
||||||
cons(tag_object(error),F)));
|
|
||||||
|
|
||||||
general_error(ERROR_IO,tag_cons(c));
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#define ERROR_INCOMPARABLE (7<<3)
|
#define ERROR_INCOMPARABLE (7<<3)
|
||||||
#define ERROR_FLOAT_FORMAT (8<<3)
|
#define ERROR_FLOAT_FORMAT (8<<3)
|
||||||
#define ERROR_SIGNAL (9<<3)
|
#define ERROR_SIGNAL (9<<3)
|
||||||
|
#define ERROR_IO_TASK_TWICE (10<<3)
|
||||||
|
#define ERROR_IO_TASK_NONE (11<<3)
|
||||||
|
|
||||||
void fatal_error(char* msg, CELL tagged);
|
void fatal_error(char* msg, CELL tagged);
|
||||||
void critical_error(char* msg, CELL tagged);
|
void critical_error(char* msg, CELL tagged);
|
||||||
|
@ -16,4 +18,3 @@ void throw_error(CELL object);
|
||||||
void general_error(CELL error, CELL tagged);
|
void general_error(CELL error, CELL tagged);
|
||||||
void type_error(CELL type, CELL tagged);
|
void type_error(CELL type, CELL tagged);
|
||||||
void range_error(CELL tagged, CELL index, CELL max);
|
void range_error(CELL tagged, CELL index, CELL max);
|
||||||
void io_error(const char* func);
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ IO_TASK* add_io_task(
|
||||||
int fd = port->fd;
|
int fd = port->fd;
|
||||||
|
|
||||||
if(io_tasks[fd].port != F)
|
if(io_tasks[fd].port != F)
|
||||||
critical_error("Adding I/O task twice",fd);
|
general_error(ERROR_IO_TASK_TWICE,tag_object(port));
|
||||||
|
|
||||||
io_tasks[fd].type = type;
|
io_tasks[fd].type = type;
|
||||||
io_tasks[fd].port = tag_object(port);
|
io_tasks[fd].port = tag_object(port);
|
||||||
|
@ -193,7 +193,7 @@ CELL next_io_task(void)
|
||||||
write_fd_count,write_io_tasks);
|
write_fd_count,write_io_tasks);
|
||||||
|
|
||||||
if(!reading && !writing)
|
if(!reading && !writing)
|
||||||
critical_error("next_io_task() called with no IO tasks",0);
|
general_error(ERROR_IO_TASK_NONE,F);
|
||||||
|
|
||||||
set_up_fd_set(&except_fd_set,
|
set_up_fd_set(&except_fd_set,
|
||||||
read_fd_count,read_io_tasks);
|
read_fd_count,read_io_tasks);
|
||||||
|
|
|
@ -25,6 +25,7 @@ PORT* port(PORT_MODE type, CELL fd)
|
||||||
port->line_ready = false;
|
port->line_ready = false;
|
||||||
port->buf_fill = 0;
|
port->buf_fill = 0;
|
||||||
port->buf_pos = 0;
|
port->buf_pos = 0;
|
||||||
|
port->io_error = F;
|
||||||
|
|
||||||
if(type == PORT_SPECIAL)
|
if(type == PORT_SPECIAL)
|
||||||
port->buffer = NULL;
|
port->buffer = NULL;
|
||||||
|
@ -58,6 +59,7 @@ void fixup_port(PORT* port)
|
||||||
fixup(&port->line);
|
fixup(&port->line);
|
||||||
fixup(&port->client_host);
|
fixup(&port->client_host);
|
||||||
fixup(&port->client_port);
|
fixup(&port->client_port);
|
||||||
|
fixup(&port->io_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void collect_port(PORT* port)
|
void collect_port(PORT* port)
|
||||||
|
@ -67,4 +69,36 @@ void collect_port(PORT* port)
|
||||||
copy_object(&port->line);
|
copy_object(&port->line);
|
||||||
copy_object(&port->client_host);
|
copy_object(&port->client_host);
|
||||||
copy_object(&port->client_port);
|
copy_object(&port->client_port);
|
||||||
|
copy_object(&port->io_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
CELL make_io_error(const char* func)
|
||||||
|
{
|
||||||
|
STRING* function = from_c_string(func);
|
||||||
|
STRING* error = from_c_string(strerror(errno));
|
||||||
|
|
||||||
|
CONS* c = cons(tag_object(function),tag_cons(
|
||||||
|
cons(tag_object(error),F)));
|
||||||
|
|
||||||
|
return tag_cons(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void postpone_io_error(PORT* port, const char* func)
|
||||||
|
{
|
||||||
|
port->io_error = make_io_error(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
void io_error(const char* func)
|
||||||
|
{
|
||||||
|
general_error(ERROR_IO,make_io_error(func));
|
||||||
|
}
|
||||||
|
|
||||||
|
void pending_io_error(PORT* port)
|
||||||
|
{
|
||||||
|
CELL io_error = port->io_error;
|
||||||
|
if(io_error != F)
|
||||||
|
{
|
||||||
|
port->io_error = F;
|
||||||
|
general_error(ERROR_IO,io_error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,9 @@ typedef struct {
|
||||||
CELL client_port;
|
CELL client_port;
|
||||||
/* untagged fd of accepted connection */
|
/* untagged fd of accepted connection */
|
||||||
CELL client_socket;
|
CELL client_socket;
|
||||||
|
|
||||||
|
/* a pending I/O error or F */
|
||||||
|
CELL io_error;
|
||||||
} PORT;
|
} PORT;
|
||||||
|
|
||||||
PORT* untag_port(CELL tagged);
|
PORT* untag_port(CELL tagged);
|
||||||
|
@ -36,3 +39,6 @@ void init_line_buffer(PORT* port, FIXNUM count);
|
||||||
void primitive_portp(void);
|
void primitive_portp(void);
|
||||||
void fixup_port(PORT* port);
|
void fixup_port(PORT* port);
|
||||||
void collect_port(PORT* port);
|
void collect_port(PORT* port);
|
||||||
|
void postpone_io_error(PORT* port, const char* func);
|
||||||
|
void io_error(const char* func);
|
||||||
|
void pending_io_error(PORT* port);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
/* Return true if something was read */
|
/* Return true if something was read */
|
||||||
bool read_step(PORT* port)
|
bool read_step(PORT* port)
|
||||||
{
|
{
|
||||||
FIXNUM amount = 0;
|
FIXNUM amount = 0;
|
||||||
|
|
||||||
if(port->type == PORT_RECV)
|
if(port->type == PORT_RECV)
|
||||||
{
|
{
|
||||||
|
@ -24,8 +24,12 @@ bool read_step(PORT* port)
|
||||||
if(amount < 0)
|
if(amount < 0)
|
||||||
{
|
{
|
||||||
if(errno != EAGAIN)
|
if(errno != EAGAIN)
|
||||||
io_error(__FUNCTION__);
|
{
|
||||||
return false;
|
postpone_io_error(port,__FUNCTION__);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -76,6 +80,8 @@ bool read_line_step(PORT* port)
|
||||||
|
|
||||||
bool can_read_line(PORT* port)
|
bool can_read_line(PORT* port)
|
||||||
{
|
{
|
||||||
|
pending_io_error(port);
|
||||||
|
|
||||||
if(port->line_ready)
|
if(port->line_ready)
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
|
@ -133,6 +139,9 @@ bool perform_read_line_io_task(PORT* port)
|
||||||
void primitive_read_line_8(void)
|
void primitive_read_line_8(void)
|
||||||
{
|
{
|
||||||
PORT* port = untag_port(dpeek());
|
PORT* port = untag_port(dpeek());
|
||||||
|
|
||||||
|
pending_io_error(port);
|
||||||
|
|
||||||
if(port->line_ready)
|
if(port->line_ready)
|
||||||
{
|
{
|
||||||
drepl(port->line);
|
drepl(port->line);
|
||||||
|
@ -170,6 +179,8 @@ bool read_count_step(PORT* port)
|
||||||
|
|
||||||
bool can_read_count(PORT* port, FIXNUM count)
|
bool can_read_count(PORT* port, FIXNUM count)
|
||||||
{
|
{
|
||||||
|
pending_io_error(port);
|
||||||
|
|
||||||
if(port->line != F && CAN_READ_COUNT(port,count))
|
if(port->line != F && CAN_READ_COUNT(port,count))
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
|
@ -222,6 +233,9 @@ void primitive_read_count_8(void)
|
||||||
FIXNUM len = to_fixnum(dpop());
|
FIXNUM len = to_fixnum(dpop());
|
||||||
if(port->count != len)
|
if(port->count != len)
|
||||||
critical_error("read# counts don't match",port);
|
critical_error("read# counts don't match",port);
|
||||||
|
|
||||||
|
pending_io_error(port);
|
||||||
|
|
||||||
dpush(port->line);
|
dpush(port->line);
|
||||||
port->line = F;
|
port->line = F;
|
||||||
port->line_ready = false;
|
port->line_ready = false;
|
||||||
|
|
|
@ -8,8 +8,11 @@ void signal_handler(int signal, siginfo_t* siginfo, void* uap)
|
||||||
void init_signals(void)
|
void init_signals(void)
|
||||||
{
|
{
|
||||||
struct sigaction custom_sigaction;
|
struct sigaction custom_sigaction;
|
||||||
|
struct sigaction ign_sigaction;
|
||||||
custom_sigaction.sa_sigaction = signal_handler;
|
custom_sigaction.sa_sigaction = signal_handler;
|
||||||
custom_sigaction.sa_flags = SA_SIGINFO;
|
custom_sigaction.sa_flags = SA_SIGINFO;
|
||||||
|
ign_sigaction.sa_handler = SIG_IGN;
|
||||||
|
ign_sigaction.sa_flags = 0;
|
||||||
sigaction(SIGABRT,&custom_sigaction,NULL);
|
sigaction(SIGABRT,&custom_sigaction,NULL);
|
||||||
sigaction(SIGFPE,&custom_sigaction,NULL);
|
sigaction(SIGFPE,&custom_sigaction,NULL);
|
||||||
sigaction(SIGBUS,&custom_sigaction,NULL);
|
sigaction(SIGBUS,&custom_sigaction,NULL);
|
||||||
|
|
|
@ -11,8 +11,12 @@ bool write_step(PORT* port)
|
||||||
if(amount == -1)
|
if(amount == -1)
|
||||||
{
|
{
|
||||||
if(errno != EAGAIN)
|
if(errno != EAGAIN)
|
||||||
io_error(__FUNCTION__);
|
{
|
||||||
return false;
|
postpone_io_error(port,__FUNCTION__);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -25,6 +29,8 @@ bool can_write(PORT* port, FIXNUM len)
|
||||||
{
|
{
|
||||||
CELL buf_capacity;
|
CELL buf_capacity;
|
||||||
|
|
||||||
|
pending_io_error(port);
|
||||||
|
|
||||||
switch(port->type)
|
switch(port->type)
|
||||||
{
|
{
|
||||||
case PORT_READ:
|
case PORT_READ:
|
||||||
|
@ -111,6 +117,8 @@ void primitive_write_8(void)
|
||||||
CELL text = dpop();
|
CELL text = dpop();
|
||||||
CELL type = type_of(text);
|
CELL type = type_of(text);
|
||||||
|
|
||||||
|
pending_io_error(port);
|
||||||
|
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case FIXNUM_TYPE:
|
case FIXNUM_TYPE:
|
||||||
|
|
Loading…
Reference in New Issue