/* create vty for stdio */
static struct termios stdio_orig_termios;
static struct vty *stdio_vty = NULL;
-static void (*stdio_vty_atclose)(void);
+static bool stdio_termios = false;
+static void (*stdio_vty_atclose)(int isexit);
-static void vty_stdio_reset(void)
+static void vty_stdio_reset(int isexit)
{
if (stdio_vty) {
- tcsetattr(0, TCSANOW, &stdio_orig_termios);
+ if (stdio_termios)
+ tcsetattr(0, TCSANOW, &stdio_orig_termios);
+ stdio_termios = false;
+
stdio_vty = NULL;
if (stdio_vty_atclose)
- stdio_vty_atclose();
+ stdio_vty_atclose(isexit);
stdio_vty_atclose = NULL;
}
}
-struct vty *vty_stdio(void (*atclose)())
+static void vty_stdio_atexit(void)
+{
+ vty_stdio_reset(1);
+}
+
+void vty_stdio_suspend(void)
+{
+ if (!stdio_vty)
+ return;
+
+ if (stdio_vty->t_write)
+ thread_cancel(stdio_vty->t_write);
+ if (stdio_vty->t_read)
+ thread_cancel(stdio_vty->t_read);
+ if (stdio_vty->t_timeout)
+ thread_cancel(stdio_vty->t_timeout);
+
+ if (stdio_termios)
+ tcsetattr(0, TCSANOW, &stdio_orig_termios);
+ stdio_termios = false;
+}
+
+void vty_stdio_resume(void)
+{
+ if (!stdio_vty)
+ return;
+
+ if (!tcgetattr(0, &stdio_orig_termios)) {
+ struct termios termios;
+
+ termios = stdio_orig_termios;
+ termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR
+ | IGNCR | ICRNL | IXON);
+ termios.c_oflag &= ~OPOST;
+ termios.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN);
+ termios.c_cflag &= ~(CSIZE | PARENB);
+ termios.c_cflag |= CS8;
+ tcsetattr(0, TCSANOW, &termios);
+ stdio_termios = true;
+ }
+
+ vty_prompt(stdio_vty);
+
+ /* Add read/write thread. */
+ vty_event(VTY_WRITE, 1, stdio_vty);
+ vty_event(VTY_READ, 0, stdio_vty);
+}
+
+void vty_stdio_close(void)
+{
+ if (!stdio_vty)
+ return;
+ vty_close(stdio_vty);
+}
+
+struct vty *vty_stdio(void (*atclose)(int isexit))
{
struct vty *vty;
- struct termios termios;
/* refuse creating two vtys on stdio */
if (stdio_vty)
vty->v_timeout = 0;
strcpy(vty->address, "console");
- if (!tcgetattr(0, &stdio_orig_termios)) {
- termios = stdio_orig_termios;
- termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR
- | IGNCR | ICRNL | IXON);
- termios.c_oflag &= ~OPOST;
- termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
- termios.c_cflag &= ~(CSIZE | PARENB);
- termios.c_cflag |= CS8;
- tcsetattr(0, TCSANOW, &termios);
- }
-
- vty_prompt(vty);
-
- /* Add read/write thread. */
- vty_event(VTY_WRITE, 1, vty);
- vty_event(VTY_READ, 0, vty);
-
+ vty_stdio_resume();
return vty;
}
ret = getaddrinfo(hostname, port_str, &req, &ainfo);
if (ret != 0) {
- fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(ret));
+ zlog_err("getaddrinfo failed: %s", gai_strerror(ret));
exit(1);
}
XFREE(MTYPE_VTY, vty);
if (was_stdio)
- vty_stdio_reset();
+ vty_stdio_reset(0);
}
/* When time out occur output message then close connection. */
if (!((ret == CMD_SUCCESS) || (ret == CMD_ERR_NOTHING_TODO))) {
const char *message = NULL;
+ char *nl;
+
switch (ret) {
case CMD_ERR_AMBIGUOUS:
- message =
- "*** Error reading config: Ambiguous command.";
+ message = "Ambiguous command";
break;
case CMD_ERR_NO_MATCH:
- message =
- "*** Error reading config: There is no such command.";
+ message = "No such command";
break;
}
- fprintf(stderr, "%s\n", message);
- zlog_err("%s", message);
- fprintf(stderr,
- "*** Error occurred processing line %u, below:\n%s\n",
- line_num, vty->error_buf);
- zlog_err("*** Error occurred processing line %u, below:\n%s",
- line_num, vty->error_buf);
+
+ nl = strchr(vty->error_buf, '\n');
+ if (nl)
+ *nl = '\0';
+ zlog_err("ERROR: %s on config line %u: %s",
+ message, line_num, vty->error_buf);
}
vty_close(vty);
if (config_file != NULL) {
if (!IS_DIRECTORY_SEP(config_file[0])) {
if (getcwd(cwd, MAXPATHLEN) == NULL) {
- fprintf(stderr,
- "Failure to determine Current Working Directory %d!\n",
+ zlog_err("Failure to determine Current Working Directory %d!",
errno);
exit(1);
}
confp = fopen(fullpath, "r");
if (confp == NULL) {
- fprintf(stderr,
- "%s: failed to open configuration file %s: %s\n",
+ zlog_err("%s: failed to open configuration file %s: %s",
__func__, fullpath, safe_strerror(errno));
confp = vty_use_backup_config(fullpath);
if (confp)
- fprintf(stderr,
- "WARNING: using backup configuration file!\n");
+ zlog_warn("WARNING: using backup configuration file!");
else {
- fprintf(stderr,
- "can't open configuration file [%s]\n",
+ zlog_err("can't open configuration file [%s]",
config_file);
exit(1);
}
#endif /* VTYSH */
confp = fopen(config_default_dir, "r");
if (confp == NULL) {
- fprintf(stderr,
- "%s: failed to open configuration file %s: %s\n",
+ zlog_err("%s: failed to open configuration file %s: %s",
__func__, config_default_dir,
safe_strerror(errno));
confp = vty_use_backup_config(config_default_dir);
if (confp) {
- fprintf(stderr,
- "WARNING: using backup configuration file!\n");
+ zlog_warn("WARNING: using backup configuration file!");
fullpath = config_default_dir;
} else {
- fprintf(stderr,
- "can't open configuration file [%s]\n",
+ zlog_err("can't open configuration file [%s]",
config_default_dir);
goto tmp_free_and_out;
}
* Hence not worrying about it too much.
*/
if (!chdir(SYSCONFDIR)) {
- fprintf(stderr, "Failure to chdir to %s, errno: %d\n",
+ zlog_err("Failure to chdir to %s, errno: %d",
SYSCONFDIR, errno);
exit(-1);
}
if (getcwd(cwd, MAXPATHLEN) == NULL) {
- fprintf(stderr, "Failure to getcwd, errno: %d\n",
+ zlog_err("Failure to getcwd, errno: %d",
errno);
exit(-1);
}
vty_master = master_thread;
- atexit(vty_stdio_reset);
+ atexit(vty_stdio_atexit);
/* Initilize server thread vector. */
Vvty_serv_thread = vector_init(VECTOR_MIN_SIZE);