#include #include #include #include #include #include #include #include #include "builtins.h" #include "shell.h" #include "bashgetopt.h" /* A builtin `xxx' is normally implemented with an `xxx_builtin' function. If you're converting a command that uses the normal Unix argc/argv calling convention, use argv = make_builtin_argv (list, &argc) and call the original `main' something like `xxx_main'. Look at cat.c for an example. Builtins should use internal_getopt to parse options. It is the same as getopt(3), but it takes a WORD_LIST *. Look at print.c for an example of its use. If the builtin takes no options, call no_options(list) before doing anything else. If it returns a non-zero value, your builtin should immediately return EX_USAGE. Look at logname.c for an example. A builtin command returns EXECUTION_SUCCESS for success and EXECUTION_FAILURE to indicate failure. */ console_builtin (list) WORD_LIST *list; { char *path = list->word->word; int fd = open (path, O_RDWR); unsigned int console; if (fd != -1) { dup2 (fd, 0); dup2 (fd, 1); dup2 (fd, 2); if (fd > 2) close (fd); if (sscanf (path, "/dev/tty%u%*c", &console) == 1) { if (console > 0 && console < 64) { ioctl (0, VT_ACTIVATE, console); ioctl (0, VT_WAITACTIVE, console); } } return EXECUTION_SUCCESS; } else return EXECUTION_FAILURE; } /* An array of strings forming the `long' documentation for a builtin xxx, which is printed by `help xxx'. It must end with a NULL. */ char *console_doc[] = { "connects the current process to 'path'", "no controlling terminal will be allocated", "if the path is of the form /dev/ttyN, switches to that console", (char *)NULL }; /* The standard structure describing a builtin command. bash keeps an array of these structures. The flags must include BUILTIN_ENABLED so the builtin can be used. */ struct builtin console_struct = { "console", /* builtin name */ console_builtin, /* function implementing the builtin */ BUILTIN_ENABLED, /* initial flags for builtin */ console_doc, /* array of long documentation strings. */ "console path", /* usage synopsis; becomes short_doc */ 0 /* reserved for internal use */ }; setsid_builtin (list) WORD_LIST *list; { int fd = open ("/dev/tty", O_RDWR); if (fd != -1) { ioctl (fd, TIOCNOTTY); close (fd); } return setsid () >= 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE; } char *setsid_doc[] = { "calls setsid", (char *)NULL }; struct builtin setsid_struct = { "setsid", setsid_builtin, BUILTIN_ENABLED, setsid_doc, "setsid", 0 }; winsize_builtin (list) WORD_LIST *list; { struct winsize ws; if (ioctl (0, TIOCGWINSZ, &ws) != -1) { printf ("rows=%d; cols=%d\n", ws.ws_row, ws.ws_col); return EXECUTION_SUCCESS; } else { printf ("rows=80; cols=25\n"); return EXECUTION_FAILURE; } } char *winsize_doc[] = { "returns the window size as 'rows=; cols='", (char *)NULL }; struct builtin winsize_struct = { "winsize", winsize_builtin, BUILTIN_ENABLED, winsize_doc, "winsize", 0 }; renamefunc_builtin (list) WORD_LIST *list; { if (list && list->next) { BUCKET_CONTENTS *elt = (BUCKET_CONTENTS *)hash_remove (list->word->word, shell_functions, 0); if (elt) { SHELL_VAR *cmd = (SHELL_VAR *)elt->data; free (elt->key); free (elt); free (cmd->name); cmd->name = savestring (list->next->word->word); elt = hash_insert (cmd->name, shell_functions, 0); elt->data = (char *)cmd; return EXECUTION_SUCCESS; } else return EXECUTION_FAILURE; } else return EX_USAGE; } char *renamefunc_doc[] = { "rename a function from oldname to newname. the new function mustn't exist", (char *)NULL }; struct builtin renamefunc_struct = { "renamefunc", renamefunc_builtin, BUILTIN_ENABLED, renamefunc_doc, "renamefunc oldname newname", 0 }; usleep_builtin (list) WORD_LIST *list; { usleep (atof (list->word->word) * 1e6); return EXECUTION_SUCCESS; } char *usleep_doc[] = { "sleep a (possibly fractional) number of seconds", (char *)NULL }; struct builtin usleep_struct = { "usleep", usleep_builtin, BUILTIN_ENABLED, usleep_doc, "usleep time-in-fractional-seconds", 0 }; str2hex_builtin (list) WORD_LIST *list; { char *p; for (p = list->word->word; *p; p++) printf ("%02x", *p); puts ("\n"); return EXECUTION_SUCCESS; } char *str2hex_doc[] = { "convert the first argument to a hex string", (char *)NULL }; struct builtin str2hex_struct = { "str2hex", str2hex_builtin, BUILTIN_ENABLED, str2hex_doc, "str2hex string", 0 }; #if 0 havefunc_builtin (list) WORD_LIST *list; { if(list && find_hash_item(list->word->word, shell_functions)) return EXECUTION_SUCCESS; return EXECUTION_FAILURE; } char *havefunc_doc[] = { "checks if argument is a shell function", (char *)NULL }; struct builtin havefunc_struct = { "havefunc", havefunc_builtin, BUILTIN_ENABLED, havefunc_doc, "havefunc name", 0 }; #endif