📄 cmd.c
字号:
/* * File : cmd.c * Date : 2002-04-20 * Author : yfy001 * Description : process commands input by user * Copyright (C) 2001, 2002 yfy001 */#include <stdio.h> // printf, fprintf, fgets#include <string.h> // strcpy#include <limits.h> // NAME_MAX, CHAR_MAX#include <stdlib.h> // exit#include <sys/types.h> // pid_t#include <unistd.h> // fork, vfork, _exit#include <sys/wait.h> // wait#include <ctype.h> // isspace#include "types.h" // p_packge_info_t, p_portinfo_t#include "tty.h" // tty_write#include "prompt.h" // prompt#include "strings.h" // str_nonspace#include "cmd.h"static void cmd_makeargv(char *cmd_line, char **argv);static INT8 cmd_is_valid(char **argv);static char *cmd_get_shell();static void cmd_help(char **argv);static void cmd_shell(char **argv);static void cmd_display(char **argv);static void cmd_send(char **argv);static void cmd_open(char **argv);static void cmd_close(char **argv);static void cmd_clear(char **argv);static void cmd_error(char **argv);static void cmd_exit(char **argv);static pid_t pid_recv; // pid of receiving processtypedef struct { char *name; void (*func) (char **);} cmds_t;static cmds_t cmds[] = { {"bye", cmd_exit}, {"clear", cmd_clear}, {"close", cmd_close}, {"display", cmd_display}, {"exit", cmd_exit}, {"help", cmd_help}, {"open", cmd_open}, {"quit", cmd_exit}, {"usage", cmd_help}, {"!", cmd_shell}, {"@", cmd_send}, {"?", cmd_help}, {NULL, cmd_error}};/* * Arguments : none * Return value : none * Decription : wait for users' input command to execute */void cmd(){ static char *argv[NAME_MAX]; static char cmd_line[NAME_MAX + 1]; switch ((pid_recv = fork())) { case -1: return; case 0: // child close(STDIN_FILENO); tty_set_sig_on(); while (1) { sleep(2); } exit(0); break; default: // parent while (1) { prompt(); fgets(cmd_line, sizeof(cmd_line), stdin); cmd_makeargv(cmd_line, argv); if (!cmd_is_valid(argv)) break; } }}/* * Arguments : * argv[0]==NULL, no commands at all, just white space, return(1) * Return value : * 1, continue; * 0, break; */static INT8 cmd_is_valid(char **argv){ cmds_t *cmdp = cmds; if (NULL == *argv) return 1; while (cmdp->name && strcmp(*argv, cmdp->name)) { cmdp++; } cmdp->func(argv); return 1;}/* * Arguments : * argv[0]: pointer to shell name * Return value : none * Description : execute a comman in a sub shell */static void cmd_shell(char **argv){ char **shell_argv = argv; char *cmd_line = argv[1]; char *cp = str_fnws(cmd_line); *argv++ = cmd_get_shell(); if (*cp) { // with extra arguments *argv++ = "-c"; *argv++ = cp; } *argv = NULL; switch (fork()) { case -1: perror("Fork failed\r\n"); break; case 0: { execvp(shell_argv[0], shell_argv); perror("execvp"); _exit(1); } default: wait((int *) 0); // Wait for the shell to complete break; }}/* * Arguments : char *cmd_line, char **argv * Description : * argv[0]: stores first command * argv[0]: NULL, no command, just white space * Return value : none */static void cmd_makeargv(char *cmd_line, char **argv){ char *cp = cmd_line; int newword = 1; cp = str_fnws(cp); if ('!' == *cp || '@' == *cp || '?' == *cp) { *argv++ = *cp == '!' ? "!" : *cp == '@' ? "@" : "?"; *argv++ = ++cp; *argv = NULL; return; } for (newword = 1; *cp; cp++) { if (isspace(*cp)) { *cp = '\0'; newword = 1; } else if (newword) { newword = 0; *argv++ = cp; } } *argv = NULL;}/* * Arguments : char **argv * Return value : none * Description : show help message; */static void cmd_help(char **argv){ char *program_name = basename(p_args->p_pkginfo->program_name); fprintf(stdout, "Commands are:\n\n" "clear \t\tclear screen\n" "close \t\tclose an open serial port\n" "display\t\tdisplay operating parameters\n" "exit \t\texit %s\n" "help \t\tprint help information\n" "open \t\topen a serail port\n" "quit \t\tquit %s\n" "@ \t\tsend messages\n" "! \t\tinvoke a subshell, example: !ls /bin /usr\n" "? \t\tprint help information\n", program_name, program_name);}/* * Arguments : char **argv * Return value : none * Description : display operating parameters */static void cmd_display(char **argv){ portinfo_t *p_port = p_args->p_portinfo; printf("\n" "baudrate \t%d\n" "databit \t%d\n" "debug \t%s\n" "echo \t%s\n" "flowcontrol\t%s\n" "parity \t%s\n" "prompt \t%s\n" "stopbit \t%d\n" "tty \tttyS%d\n", p_port->baudrate, p_port->databit, p_port->debug ? "on" : "off", p_port->echo ? "on" : "off", p_port->fctrl == 0 ? "none" : p_port->fctrl == 1 ? "hardware" : "software", p_port->parity == 0 ? "none" : p_port->parity == 1 ? "odd" : "even", p_port->prompt ? "on" : "off", p_port->stopbit, p_port->tty);}/* * Arguments : char **argv * Return value : none * Description : send data */static void cmd_send(char **argv){ char *data = *++argv; int retval = tty_write(data, strlen(data)); if (E_NOTOPEN == retval) { fprintf(stderr, "/dev/ttyS%d is not open\n", p_args->p_portinfo->tty); } else if (strlen(data) != retval) { fprintf(stderr, "cannot send data correctly\n"); }}/* * Arguments : char **argv * Return value : none * Description : open a serial port and then print success or failure. */static void cmd_open(char **argv){ int retval = 0; retval = tty_open(p_args->p_portinfo); if (retval) { fprintf(stderr, "Make sure /dev/ttyS%d " "not in use or you have enough privilege.\n\n", p_args->p_portinfo->tty); } else { printf("/dev/ttyS%d opened\n", p_args->p_portinfo->tty); }}/* * Arguments : char **argv * Return value : none * Description : close com port and print whether it is successful. */static void cmd_close(char **argv){ tty_close(); printf("/dev/ttyS%d closed\n", p_args->p_portinfo->tty);}/* * Arguments : char **argv * Return value : none * Description : print error message if coming accross invalid command */static void cmd_error(char **argv){ char *command = *argv; fprintf(stderr, "Invalid command: %s\n" "type \"?\" to show commands\n", command);}/* * Arguments : char **argv * Return value : none * Description : reset and clear the screen */static void cmd_clear(char **argv){ argv[0] = "!"; argv[1] = "reset >/dev/null 2>&1"; argv[2] = NULL; cmd_shell(argv); argv[0] = "!"; argv[1] = "clear"; argv[2] = NULL; cmd_shell(argv);}/* * Arguments : none * Return value : char *shellp pointer to shell path and name */static char *cmd_get_shell(){ char *shellp = getenv("SHELL"); return shellp ? shellp : "/bin/sh";}/* * Arguments : char **argv * Return value : none * Description : close child process receive, and exit */static void cmd_exit(char **argv){ if (pid_recv > 0) kill(pid_recv, SIGTERM); // terminate recv process exit(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -