telnetd: Convert pty driver to new Termios API

Update #3526.
This commit is contained in:
Sebastian Huber
2018-10-01 12:28:10 +02:00
parent ac9f80874f
commit b980f36306
3 changed files with 145 additions and 456 deletions
+16 -49
View File
@@ -16,58 +16,25 @@
extern "C" {
#endif
#include <rtems.h>
#include <rtems/termiostypes.h>
/* Number of ptys to setup */
extern size_t rtems_pty_maximum_ptys;
#define RTEMS_PTY_SB_MAX 16
/* Return the devname for a free pty slot.
* If no slot available (socket>=0)
* then the socket argument is closed
*/
char * rtems_pty_get(int socket);
typedef struct {
rtems_termios_device_context base;
rtems_termios_tty *ttyp;
tcflag_t c_cflag;
int socket;
int last_cr;
unsigned iac_mode;
unsigned char sb_buf[RTEMS_PTY_SB_MAX];
int sb_ind;
int width;
int height;
char name[sizeof("/dev/pty18446744073709551615")];
} rtems_pty_context;
/* OBSOLETE */
#define get_pty rtems_pty_get
rtems_device_driver pty_initialize(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg);
rtems_device_driver pty_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg);
rtems_device_driver pty_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg);
rtems_device_driver pty_read(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg);
rtems_device_driver pty_write(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg);
rtems_device_driver pty_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg);
#define PTY_DRIVER_TABLE_ENTRY \
{ pty_initialize , pty_open , pty_close , \
pty_read , pty_write , pty_control }
/* Internal functions */
int telnet_pty_initialize(void);
int telnet_pty_finalize(void);
char *telnet_get_pty(int);
char *telnet_get_pty(rtems_pty_context *ctx, int socket);
#ifdef __cplusplus
}
+104 -374
View File
File diff suppressed because it is too large Load Diff
+25 -33
View File
@@ -64,14 +64,11 @@
#define PARANOIA
extern char *telnet_get_pty(int socket);
extern int telnet_pty_initialize(void);
struct shell_args {
char *devname;
void *arg;
char peername[16];
char delete_myself;
rtems_pty_context pty;
void *arg;
char peername[16];
char delete_myself;
};
typedef union uni_sa {
@@ -107,17 +104,23 @@ static const rtems_id (*telnetd_spawn_task)(
void *
) = telnetd_dflt_spawn;
static char *grab_a_Connection(
static struct shell_args *grab_a_Connection(
int des_socket,
uni_sa *srv,
char *peername,
int sz
)
{
char *rval = 0;
struct shell_args *args = NULL;
socklen_t size_adr = sizeof(srv->sin);
int acp_sock;
args = malloc(sizeof(*args));
if (args == NULL) {
perror("telnetd:malloc");
goto bailout;
}
acp_sock = accept(des_socket,&srv->sa,&size_adr);
if (acp_sock<0) {
@@ -125,7 +128,7 @@ static char *grab_a_Connection(
goto bailout;
};
if ( !(rval=telnet_get_pty(acp_sock)) ) {
if (telnet_get_pty(&args->pty, acp_sock) == NULL) {
syslog( LOG_DAEMON | LOG_ERR, "telnetd: unable to obtain PTY");
/* NOTE: failing 'do_get_pty()' closed the socket */
goto bailout;
@@ -138,12 +141,12 @@ static char *grab_a_Connection(
syslog(LOG_DAEMON | LOG_INFO,
"telnetd: accepted connection from %s on %s",
peername,
rval);
args->pty.name);
#endif
bailout:
return rval;
return args;
}
@@ -160,6 +163,7 @@ static void release_a_Connection(char *devname, char *peername, FILE **pstd, int
while (--n>=0)
if (pstd[n]) fclose(pstd[n]);
unlink(devname);
}
static int sockpeername(int sock, char *buf, int bufsz)
@@ -186,7 +190,6 @@ rtems_task_telnetd(void *task_argument)
{
int des_socket;
uni_sa srv;
char *devname;
char peername[16];
int i=1;
int size_adr;
@@ -243,22 +246,19 @@ rtems_task_telnetd(void *task_argument)
);
}
} else {
devname = grab_a_Connection(des_socket, &srv, peername, sizeof(peername));
arg = grab_a_Connection(des_socket, &srv, peername, sizeof(peername));
if ( !devname ) {
if (arg == NULL) {
/* if something went wrong, sleep for some time */
sleep(10);
continue;
}
arg = malloc( sizeof(*arg) );
arg->devname = devname;
arg->arg = telnetd_config->arg;
strncpy(arg->peername, peername, sizeof(arg->peername));
telnetd_task_id = telnetd_spawn_task(
devname,
arg->pty.name,
telnetd_config->priority,
telnetd_config->stack_size,
spawned_shell,
@@ -278,9 +278,9 @@ rtems_task_telnetd(void *task_argument)
* a stream...
*/
if ( !(dummy=fopen(devname,"r+")) )
if ( !(dummy=fopen(arg->pty.name,"r+")) )
perror("Unable to dummy open the pty, losing a slot :-(");
release_a_Connection(devname, peername, &dummy, 1);
release_a_Connection(arg->pty.name, peername, &dummy, 1);
free(arg);
sleep(2); /* don't accept connections too fast */
}
@@ -315,14 +315,6 @@ rtems_status_code rtems_telnetd_start(const rtems_telnetd_config_table* config)
return RTEMS_NO_MEMORY;
}
if ( !telnet_pty_initialize() ) {
fprintf(stderr, "telnetd cannot initialize PTY driver\n");
free(telnetd_config);
telnetd_config = NULL;
return RTEMS_IO_ERROR;
}
*telnetd_config = *config;
/* Check priority */
@@ -396,7 +388,7 @@ spawned_shell(void *targ)
/* redirect stdio */
for (i=0; i<3; i++) {
if ( !(nstd[i]=fopen(arg->devname,"r+")) ) {
if ( !(nstd[i]=fopen(arg->pty.name,"r+")) ) {
perror("unable to open stdio");
goto cleanup;
}
@@ -418,13 +410,13 @@ spawned_shell(void *targ)
start = rtems_shell_login_prompt(
stdin,
stderr,
arg->devname,
arg->pty.name,
telnetd_config->login_check
);
login_failed = !start;
}
if (start) {
telnetd_config->command( arg->devname, arg->arg);
telnetd_config->command( arg->pty.name, arg->arg);
}
stdin = ostd[0];
@@ -440,7 +432,7 @@ spawned_shell(void *targ)
}
cleanup:
release_a_Connection(arg->devname, arg->peername, nstd, i);
release_a_Connection(arg->pty.name, arg->peername, nstd, i);
free(arg);
}