2004-08-12 17:36:36 -04:00
|
|
|
#include "factor.h"
|
|
|
|
|
2004-12-10 21:46:42 -05:00
|
|
|
F_PORT* untag_port(CELL tagged)
|
2004-08-12 17:36:36 -04:00
|
|
|
{
|
2004-12-10 21:46:42 -05:00
|
|
|
F_PORT* p;
|
2004-08-12 17:36:36 -04:00
|
|
|
type_check(PORT_TYPE,tagged);
|
2004-12-10 21:46:42 -05:00
|
|
|
p = (F_PORT*)UNTAG(tagged);
|
2004-08-12 17:36:36 -04:00
|
|
|
/* after image load & save, ports are no longer valid */
|
|
|
|
if(p->fd == -1)
|
2004-09-21 22:58:54 -04:00
|
|
|
general_error(ERROR_EXPIRED,tagged);
|
2004-08-12 17:36:36 -04:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2004-12-10 21:46:42 -05:00
|
|
|
F_PORT* port(PORT_MODE type, CELL fd)
|
2004-08-12 17:36:36 -04:00
|
|
|
{
|
2004-12-10 21:46:42 -05:00
|
|
|
F_PORT* port = allot_object(PORT_TYPE,sizeof(F_PORT));
|
2004-08-16 19:29:07 -04:00
|
|
|
port->type = type;
|
2004-10-31 14:36:42 -05:00
|
|
|
port->closed = false;
|
2004-08-12 17:36:36 -04:00
|
|
|
port->fd = fd;
|
2004-08-15 22:45:08 -04:00
|
|
|
port->client_host = F;
|
|
|
|
port->client_port = F;
|
|
|
|
port->client_socket = F;
|
2004-08-16 19:29:07 -04:00
|
|
|
port->line = F;
|
2004-08-16 20:42:30 -04:00
|
|
|
port->line_ready = false;
|
2004-08-12 17:36:36 -04:00
|
|
|
port->buf_fill = 0;
|
|
|
|
port->buf_pos = 0;
|
2004-08-20 21:16:47 -04:00
|
|
|
port->io_error = F;
|
2004-08-15 21:50:44 -04:00
|
|
|
|
2004-08-16 19:29:07 -04:00
|
|
|
if(type == PORT_SPECIAL)
|
2004-11-27 22:26:05 -05:00
|
|
|
port->buffer = F;
|
2004-08-16 19:29:07 -04:00
|
|
|
else
|
2004-11-27 22:26:05 -05:00
|
|
|
port->buffer = tag_object(string(BUF_SIZE,'\0'));
|
2004-08-16 19:29:07 -04:00
|
|
|
|
2004-12-11 15:02:34 -05:00
|
|
|
#ifndef WIN32
|
2004-08-15 21:50:44 -04:00
|
|
|
if(fcntl(port->fd,F_SETFL,O_NONBLOCK,1) == -1)
|
2004-08-18 15:23:42 -04:00
|
|
|
io_error(__FUNCTION__);
|
2004-12-11 15:02:34 -05:00
|
|
|
#endif
|
2004-08-15 21:50:44 -04:00
|
|
|
|
|
|
|
return port;
|
2004-08-12 17:36:36 -04:00
|
|
|
}
|
|
|
|
|
2004-12-10 21:46:42 -05:00
|
|
|
void init_line_buffer(F_PORT* port, F_FIXNUM count)
|
2004-08-20 01:49:14 -04:00
|
|
|
{
|
|
|
|
if(port->line == F)
|
|
|
|
port->line = tag_object(sbuf(LINE_SIZE));
|
|
|
|
}
|
|
|
|
|
2004-12-10 21:46:42 -05:00
|
|
|
void fixup_port(F_PORT* port)
|
2004-08-12 17:36:36 -04:00
|
|
|
{
|
2004-12-10 22:21:08 -05:00
|
|
|
port->fd = (F_FIXNUM)INVALID_HANDLE_VALUE;
|
2004-11-27 22:26:05 -05:00
|
|
|
fixup(&port->buffer);
|
2004-08-15 21:50:44 -04:00
|
|
|
fixup(&port->line);
|
2004-08-15 22:45:08 -04:00
|
|
|
fixup(&port->client_host);
|
|
|
|
fixup(&port->client_port);
|
2004-08-20 21:16:47 -04:00
|
|
|
fixup(&port->io_error);
|
2004-08-12 17:36:36 -04:00
|
|
|
}
|
|
|
|
|
2004-12-10 21:46:42 -05:00
|
|
|
void collect_port(F_PORT* port)
|
2004-08-12 17:36:36 -04:00
|
|
|
{
|
2004-11-27 22:26:05 -05:00
|
|
|
copy_object(&port->buffer);
|
2004-08-15 21:50:44 -04:00
|
|
|
copy_object(&port->line);
|
2004-08-15 22:45:08 -04:00
|
|
|
copy_object(&port->client_host);
|
|
|
|
copy_object(&port->client_port);
|
2004-08-20 21:16:47 -04:00
|
|
|
copy_object(&port->io_error);
|
|
|
|
}
|
|
|
|
|
2004-12-10 22:21:08 -05:00
|
|
|
#ifdef WIN32
|
|
|
|
CELL make_io_error(const char* func)
|
|
|
|
{
|
|
|
|
F_STRING *function = from_c_string(func);
|
|
|
|
|
2004-12-17 12:22:16 -05:00
|
|
|
return cons(tag_object(function),cons(tag_object(last_error()),F));
|
2004-12-10 22:21:08 -05:00
|
|
|
}
|
|
|
|
#else
|
2004-08-20 21:16:47 -04:00
|
|
|
CELL make_io_error(const char* func)
|
|
|
|
{
|
2004-12-10 21:46:42 -05:00
|
|
|
F_STRING* function = from_c_string(func);
|
|
|
|
F_STRING* error = from_c_string(strerror(errno));
|
2004-08-20 21:16:47 -04:00
|
|
|
|
2004-09-03 18:49:04 -04:00
|
|
|
return cons(tag_object(function),cons(tag_object(error),F));
|
2004-08-20 21:16:47 -04:00
|
|
|
}
|
2004-12-10 22:21:08 -05:00
|
|
|
#endif
|
2004-08-20 21:16:47 -04:00
|
|
|
|
2004-12-10 21:46:42 -05:00
|
|
|
void postpone_io_error(F_PORT* port, const char* func)
|
2004-08-20 21:16:47 -04:00
|
|
|
{
|
|
|
|
port->io_error = make_io_error(func);
|
|
|
|
}
|
|
|
|
|
|
|
|
void io_error(const char* func)
|
|
|
|
{
|
|
|
|
general_error(ERROR_IO,make_io_error(func));
|
|
|
|
}
|
|
|
|
|
2004-12-10 21:46:42 -05:00
|
|
|
void pending_io_error(F_PORT* port)
|
2004-08-20 21:16:47 -04:00
|
|
|
{
|
|
|
|
CELL io_error = port->io_error;
|
|
|
|
if(io_error != F)
|
|
|
|
{
|
|
|
|
port->io_error = F;
|
|
|
|
general_error(ERROR_IO,io_error);
|
|
|
|
}
|
2004-10-31 14:36:42 -05:00
|
|
|
else if(port->closed)
|
|
|
|
general_error(ERROR_CLOSED,tag_object(port));
|
2004-08-12 17:36:36 -04:00
|
|
|
}
|
2004-09-02 21:51:19 -04:00
|
|
|
|
|
|
|
void primitive_pending_io_error(void)
|
|
|
|
{
|
|
|
|
pending_io_error(untag_port(dpop()));
|
|
|
|
}
|