Commit 120a1d3f authored by rswindell's avatar rswindell
Browse files

New VDD function: hangup (disconnect) for "drop DTR" support in FOSSIL driver

and virtual UART VDD.
New hangup named event, for VDD to use to disconnect socket at program's
request (dropped DTR).
parent c1e426c5
......@@ -71,6 +71,8 @@ BYTE uart_divisor_latch_msb = 0x00;
BOOL virtualize_uart=TRUE;
double yield_interval=1.0;
BOOL hangup_supported=TRUE;
HANDLE hangup_event=NULL;
HANDLE hungup_event=NULL;
HANDLE interrupt_event=NULL;
HANDLE rdslot=INVALID_HANDLE_VALUE;
......@@ -106,6 +108,14 @@ static void lprintf(int level, const char *fmt, ...)
lputs(level,sbuf);
}
void hangup()
{
if(hangup_supported && hangup_event!=NULL) {
lprintf(LOG_DEBUG,"Hanging-up at application request");
SetEvent(hangup_event);
}
}
void parse_ini(char* program)
{
char section[MAX_PATH+1];
......@@ -118,6 +128,7 @@ void parse_ini(char* program)
if(iniGetBool(ini,program,"Debug",FALSE))
log_level=LOG_DEBUG;
yield_interval=iniGetFloat(ini,program,"YieldInterval",yield_interval);
hangup_supported=iniGetBool(ini,program,"CanDisconnect",hangup_supported);
lprintf(LOG_INFO,"Parsed %s section of %s"
,program==ROOT_SECTION ? "root" : program
......@@ -322,6 +333,8 @@ VOID uart_wrport(WORD port, BYTE data)
break;
case UART_MCR:
uart_mcr_reg = data;
if((uart_mcr_reg&UART_MSR_DCD) == 0)
hangup();
break;
case UART_SCRATCH:
uart_scratch_reg = data;
......@@ -506,6 +519,18 @@ __declspec(dllexport) void __cdecl VDDDispatch(void)
break;
}
sprintf(str,"sbbsexec_hangup%d",node_num);
hangup_event=OpenEvent(
EVENT_ALL_ACCESS, /* access flag */
FALSE, /* inherit flag */
str); /* pointer to event-object name */
if(hangup_event==NULL) {
lprintf(LOG_ERR,"!VDD_OPEN: Error %d opening %s"
,GetLastError(),str);
retval=4;
break;
}
status_poll=0;
inbuf_poll=0;
online_poll=0;
......@@ -554,6 +579,9 @@ __declspec(dllexport) void __cdecl VDDDispatch(void)
CloseHandle(wrslot);
if(hungup_event!=NULL)
CloseHandle(hungup_event);
if(hangup_event!=NULL)
CloseHandle(hangup_event);
RingBufDispose(&rdbuf);
status_poll=0;
retval=0;
......@@ -740,6 +768,10 @@ __declspec(dllexport) void __cdecl VDDDispatch(void)
lputs(LOG_INFO, p);
break;
case VDD_HANGUP:
hangup();
break;
default:
lprintf(LOG_ERR,"!UNKNOWN VDD_OP: %d",getBL());
break;
......
......@@ -351,6 +351,7 @@ static void add_env_var(str_list_t* list, const char* var, const char* val)
if(wrslot!=INVALID_HANDLE_VALUE) CloseHandle(wrslot); \
if(start_event!=NULL) CloseHandle(start_event); \
if(hungup_event!=NULL) CloseHandle(hungup_event); \
if(hangup_event!=NULL) CloseHandle(hangup_event); \
ReleaseMutex(exec_mutex); \
SetLastError(last_error)
......@@ -388,6 +389,7 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir)
HANDLE wrslot=INVALID_HANDLE_VALUE;
HANDLE start_event=NULL;
HANDLE hungup_event=NULL;
HANDLE hangup_event=NULL;
HANDLE rdoutpipe;
HANDLE wrinpipe;
PROCESS_INFORMATION process_info;
......@@ -542,6 +544,18 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir)
return(GetLastError());
}
sprintf(str,"sbbsexec_hangup%d",cfg.node_num);
if((hangup_event=CreateEvent(
NULL // pointer to security attributes
,TRUE // flag for manual-reset event
,FALSE // flag for initial state
,str // pointer to event-object name
))==NULL) {
XTRN_CLEANUP;
errormsg(WHERE, ERR_CREATE, str, 0);
return(GetLastError());
}
sprintf(str,"\\\\.\\mailslot\\sbbsexec\\rd%d"
,cfg.node_num);
rdslot=CreateMailslot(str
......@@ -976,9 +990,18 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir)
/* only check process termination after 300 milliseconds of no I/O */
/* to allow for last minute reception of output from DOS programs */
if(loop_since_io>=3
&& WaitForSingleObject(process_info.hProcess,0)==WAIT_OBJECT_0)
break; /* Process Terminated */
if(loop_since_io>=3) {
if(hangup_event!=NULL
&& WaitForSingleObject(hangup_event,0)==WAIT_OBJECT_0) {
lprintf(LOG_NOTICE,"Node %d External program requested hangup (dropped DTR)"
,cfg.node_num);
hangup();
}
if(WaitForSingleObject(process_info.hProcess,0)==WAIT_OBJECT_0)
break; /* Process Terminated */
}
/* only check node for interrupt flag every 3 seconds of no I/O */
if((loop_since_io%30)==0) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment