📄 cmd.c
字号:
#include <stdio.h> //* printf, 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, fork, _exit */#include <sys/wait.h> //* wait */#include <ctype.h> //* isspace */#include "basename.h" //* basename */#include "types.h" //* INT32, INT16, P_PORT_INFO, P_PACKAGE_INFO */#include "serial.h" //* WriteComPort */#include "cmd.h"#include "prompt.h"static char cmd_line[NAME_MAX + 1];static char save_cmd_line[NAME_MAX + 1];static pid_t pid_recv;static int is_valid (char **argv);static void usage (void);static void shell (char **argv);static void makeargv (char **argv);/* * Function: void cmd () * Arguments: void; */void cmd (){ static char *argv[NAME_MAX]; INT32 RecvData = 0; switch ((pid_recv = fork ())) { case -1: return; case 0: //* child */ close (STDIN_FILENO); SetPortSig (&RecvData); while (1) { if (RecvData) { } sleep (1); } exit (0); break; } for (;;) { prompt (); fgets (cmd_line, sizeof (cmd_line), stdin); if (!is_valid (argv)) break; } //* end for (;;) */}/* * Function: is_valid(char **argv) * Arguments: * argv[0] && argv[1]==NULL, invoke a subshell without any command * argv[0] && argv[1], invoke a subshell to execute a command * argv[0]==NULL, don't invoke a subshell * argv[0]==NULL && argv[1]==NULL, no command at all, return(1) * argv[0]==NULL && argv[1], execute inner commands without subshell * argv[1]=="exit" || "quit", quit sdb; * argv[1]=="?", show help messages; * argv[1]=="@", send messages in argv[2]; * argv[1]=="open", open port; * argv[1]=="close", close port; * argv[2], the rest arguments altogether * return value: 1, continue; * 0, break; */static int is_valid (char **argv){ makeargv (argv); if (argv[0] == NULL) { //* no subshel */ if (argv[1] == NULL) { //* NULL, no arguments, just return */ return (1); } else if (!strcmp ("?", argv[1]) || !strcmp ("help", argv[1])) { usage (); } else if (!strcmp ("exit", argv[1]) || !strcmp ("quit", argv[1])) { //* exit this program. */ kill (pid_recv, SIGTERM); return (0); } else if (!strcmp ("@", argv[1])) { INT32 retval = WriteComPort (argv[2], strlen (argv[2])); if (strlen (argv[2]) != retval) { fprintf (stderr, "cannot send data correctly\n"); } } else if (!strcmp ("close", argv[1])) { CloseComPort (); } else if (!strcmp ("open", argv[1])) { INT32 retval = 0; retval = OpenComPort (pArgs->pPortInfo); if (retval) { fprintf (stderr, "Make sure /dev/ttyS%d " "not in use or you have enough privilege.\n\n", pArgs->pPortInfo->port); } } else { //* invalid commands */ fprintf (stderr, "Invalid command: %s\n" "type \"?\" to show commands\n", argv[1]); } } //* argv[0] isn't a NULL pointer, which means to invoke a subshell */ else { shell (argv); } return (1);}/* * Function: shell(char **argv) * Arguments: * argv[0]: pointer shell name * argv[1]: "-c", with a command * NULL, without any commands */static void shell (char **argv){ switch (fork ()) { case -1: perror ("Fork failed\r\n"); break; case 0: { /* * Fire up the shell in the child. */ if (DEBUG) { char **save_argv = argv; while (*save_argv) { printf ("%s\n", *save_argv++); } } execvp (argv[0], argv); perror ("execvp"); _exit (1); } default: (void) wait ((int *) 0); //* Wait for the shell to complete */ break; }}/* * Function: makeargv (char **argv) * Arguments: argv[0], NULL: don't invoke a subshell * argv[0]==NULL && argv[1]==NULL, no command, just white space * argv[0]!=NULL && argv[1]==NULL, just invoke a subshell, * without commands. * argv[0]!=NULL && argv[1]=="-c", invoke a subshell with a command */static void makeargv (char **argv){ char *cp; char *shellp = getenv ("SHELL"); int newword = 1; if (NULL == shellp) shellp = "/bin/sh"; cp = cmd_line; strcpy (save_cmd_line, cp); //* save for shell command */ while (*cp && isspace (*cp)) { cp++; }; //* escape all white spaces */ if ('!' == *cp) { //* Special case shell escape */ cp++; *argv++ = shellp; while (*cp && isspace (*cp)) { cp++; } if (*cp) { //* with extra arguments */ *argv++ = "-c"; if (DEBUG) { printf ("%s\n", cp); } *argv++ = cp; *argv++ = NULL; return; } else { //* without extra arguments, only "!" */ *argv++ = NULL; return; } } else if ('@' == *cp) { //* send message, extra arguments to be handled specially */ cp++; *argv++ = NULL; *argv++ = "@"; *argv++ = cp; *argv++ = NULL; return; } else { //* neither invoke a subshell nor send message */ *argv++ = NULL; } while (*cp) { if (isspace (*cp)) { *cp = '\0'; newword = !newword; } else if (newword) { newword = !newword; *argv++ = cp; } cp++; } *argv++ = NULL;}/* * Function: static void usage(void); * Arguments: void; * Description: show usage message; */static void usage (void){ fprintf (stdout, "Commands are:\n\n" "exit \t\texit sdb\n" "quit \t\texit sdb\n" "open \t\topen a serail port\n" "close \t\tclose an open serial port\n" "@ \t\tsend messages\n" "! \t\tinvoke a subshell\n" " \t\texample: ! /bin/sh /bin/ls\n" "help \t\tthis help message\n" "? \t\tthis help message\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -