Changeset e2ea8d7e in mainline
- Timestamp:
- 2008-08-27T05:36:12Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1b4b7b6
- Parents:
- b510d52
- Location:
- uspace/app/bdsh
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/cmds/builtins/README
rb510d52 re2ea8d7e 5 5 Examples of what should be a built-in and not a module would be: 6 6 7 cd (the cwd needs to be updated) 8 prompt (the prompt needs to be updated) 9 enable (the euid needs to be updated) 7 cd (cliuser_t->cwd needs to be updated) 8 9 In the future, more user preferences will be set via built-in commands, 10 such as the formatting of the prompt string (HelenOS doesn't yet have 11 an environment, much less PS*, even if it did we'd likely do it a little 12 differently). 10 13 11 14 .... etc. 12 15 13 Anything that does _not_ need to write to this structure should be included 14 as a module, not a built in. 16 Anything that does _not_ need to use this structure should be included 17 as a module, not a built in. If you want to include a new command, there 18 is a 99% chance that you want it to be a module. 15 19 16 For now, a skeleton directory of stuff that will exist lives here. 20 21 -
uspace/app/bdsh/cmds/modules/README
rb510d52 re2ea8d7e 1 Modules are commands or full programs (anything can be made into a module that can return2 int type) should go here. Note, modules do not update the structures containing user info 3 such as the working directory, euid, etc.1 Modules are commands or full programs (anything can be made into a module 2 that can return int type) should go here. Note, modules do not (can not) 3 update or read cliuser_t. 4 4 5 Stuff that needs to write to the user structures contained in scli.h should be made as 6 built-in commands, not modules. 5 Stuff that needs to write to the user structures contained in scli.h should 6 be made as built-in commands, not modules, but there are very few times when 7 you would want to do that. 8 9 See the README file in the bdsh root directory for a quick overview of how to 10 write a new command, or convert an existig stand-alone program into a module 11 for BDSH. 7 12 8 13 14 15 -
uspace/app/bdsh/cmds/modules/help/help.c
rb510d52 re2ea8d7e 41 41 static char *cmdname = "help"; 42 42 extern const char *progname; 43 extern unsigned int cli_interactive;44 43 45 44 #define HELP_IS_MODULE 1 … … 127 126 } 128 127 129 printf("%sAvailable commands are:\n", cli_interactive ? "\n " : ""); 130 if (cli_interactive) 131 printf( 132 " ------------------------------------------------------------\n"); 128 printf("\n Available commands are:\n"); 129 printf(" ------------------------------------------------------------\n"); 133 130 134 131 /* First, show a list of built in commands that are available in this mode */ … … 156 153 } 157 154 158 /* Provide a little more information and inform them of history / line 159 * editing features if they are present */ 160 if (cli_interactive) 161 printf("\n Try %s %s for more information on how `%s' works.\n\n", 162 cmdname, cmdname, cmdname); 155 printf("\n Try %s %s for more information on how `%s' works.\n\n", 156 cmdname, cmdname, cmdname); 163 157 164 158 return CMD_SUCCESS; -
uspace/app/bdsh/cmds/modules/quit/quit.c
rb510d52 re2ea8d7e 36 36 37 37 static char *cmdname = "quit"; 38 unsigned int cli_quit = 0;39 38 40 extern volatile int cli_lasterror;39 extern volatile unsigned int cli_quit; 41 40 extern const char *progname; 42 41 -
uspace/app/bdsh/errors.c
rb510d52 re2ea8d7e 39 39 #include "errstr.h" 40 40 41 volatile int cli_errno = CL_EOK; 42 extern volatile unsigned int cli_quit; 43 41 44 /* Error printing, translation and handling functions */ 42 45 43 volatile int cli_lasterr = 0;44 extern volatile unsigned int cli_verbocity;45 46 46 47 /* Look up errno in cl_errors and return the corresponding string. 47 48 * Return NULL if not found */ 48 char *err2str(int errno)49 static char *err2str(int err) 49 50 { 50 51 51 if (NULL != cl_errors[err no])52 return cl_errors[err no];52 if (NULL != cl_errors[err]) 53 return cl_errors[err]; 53 54 54 55 return (char *)NULL; … … 59 60 * cli_quit int that tells the main program loop to exit immediately */ 60 61 61 void cli_error(int err no, const char *fmt, ...)62 void cli_error(int err, const char *fmt, ...) 62 63 { 63 64 va_list vargs; … … 66 67 va_end(vargs); 67 68 68 if (NULL != err2str(err no))69 printf(" (%s)\n", err2str(err no));69 if (NULL != err2str(err)) 70 printf(" (%s)\n", err2str(err)); 70 71 else 71 printf(" (Unknown Error %d)\n", err no);72 printf(" (Unknown Error %d)\n", err); 72 73 73 if (errno < 0) 74 exit(EXIT_FAILURE); 74 /* If fatal, raise cli_quit so that we try to exit 75 * gracefully. This will break the main loop and 76 * invoke the destructor */ 77 if (err == CL_EFATAL) 78 cli_quit = 1; 75 79 76 } 80 return; 77 81 78 /* Just a smart printf(), print the string only if cli_verbocity is high */79 void cli_verbose(const char *fmt, ...)80 {81 if (cli_verbocity) {82 va_list vargs;83 84 printf("[*] ");85 va_start(vargs, fmt);86 vprintf(fmt, vargs);87 va_end(vargs);88 printf("\n");89 }90 return;91 82 } 92 83 … … 94 85 95 86 87 -
uspace/app/bdsh/errors.h
rb510d52 re2ea8d7e 3 3 4 4 /* Various error levels */ 5 #define CL_EFATAL 5 #define CL_EFATAL -1 6 6 #define CL_EOK 0 7 7 #define CL_EFAIL 1 … … 13 13 #define CL_EEXEC 7 14 14 #define CL_EEXISTS 8 15 #define CL_ETOOBIG 9 15 16 16 extern char *err2str(int); 17 /* Just like 'errno' */ 18 extern volatile int cli_errno; 19 17 20 extern void cli_error(int, const char *, ...); 18 extern void cli_verbose(const char *, ...); 21 19 22 #endif -
uspace/app/bdsh/errstr.h
rb510d52 re2ea8d7e 14 14 "Bad command or file name", 15 15 "Entry already exists", 16 "Object too large", 16 17 NULL 17 18 }; 18 19 20 static char *err2str(int); 21 19 22 #endif 20 23 -
uspace/app/bdsh/exec.c
rb510d52 re2ea8d7e 66 66 char *find_command(char *cmd) 67 67 { 68 char *path_ orig, *path_tok;68 char *path_tok; 69 69 char *path[PATH_MAX]; 70 70 int n = 0, i = 0; … … 77 77 return (char *) cmd; 78 78 } 79 path_orig = PATH; 80 path_tok = cli_strdup( path_orig);79 80 path_tok = cli_strdup(PATH); 81 81 82 82 /* Extract the PATH env to a path[] array */ -
uspace/app/bdsh/input.c
rb510d52 re2ea8d7e 47 47 void cli_restricted(char *cmd) 48 48 { 49 cli_verbose("%s is not available in %s mode\n", cmd,49 printf("%s is not available in %s mode\n", cmd, 50 50 cli_interactive ? "interactive" : "non-interactive"); 51 51 -
uspace/app/bdsh/scli.c
rb510d52 re2ea8d7e 43 43 static cliuser_t usr; 44 44 45 /* Modified by the 'quit' module, which is compiled before this */ 46 extern unsigned int cli_quit; 47 48 /* Globals that are modified during start-up that modules/builtins should 49 * be aware of. */ 45 /* Globals that are modified during start-up that modules/builtins 46 * should be aware of. */ 47 volatile unsigned int cli_quit = 0; 50 48 volatile unsigned int cli_interactive = 1; 51 49 volatile unsigned int cli_verbocity = 1; … … 55 53 const char *progname = PACKAGE_NAME; 56 54 55 /* These are not exposed, even to builtins */ 56 static int cli_init(cliuser_t *usr); 57 static void cli_finit(cliuser_t *usr); 58 57 59 /* (re)allocates memory to store the current working directory, gets 58 * and updates the current working directory, formats the prompt string */ 60 * and updates the current working directory, formats the prompt 61 * string */ 59 62 unsigned int cli_set_prompt(cliuser_t *usr) 60 63 { … … 78 81 snprintf(usr->cwd, PATH_MAX, "(unknown)"); 79 82 80 snprintf(usr->prompt,81 PATH_MAX,82 "%s # ",83 usr->cwd);83 if (1 < cli_psprintf(&usr->prompt, "%s # ", usr->cwd)) { 84 cli_error(cli_errno, "Failed to set prompt"); 85 return 1; 86 } 84 87 85 88 return 0; 86 89 } 87 90 88 int cli_init(cliuser_t *usr) 91 /* Constructor */ 92 static int cli_init(cliuser_t *usr) 89 93 { 90 94 usr->line = (char *) NULL; … … 99 103 100 104 /* Destructor */ 101 void cli_finit(cliuser_t *usr)105 static void cli_finit(cliuser_t *usr) 102 106 { 103 107 if (NULL != usr->line) -
uspace/app/bdsh/scli.h
rb510d52 re2ea8d7e 15 15 16 16 extern unsigned int cli_set_prompt(cliuser_t *usr); 17 extern int cli_init(cliuser_t *usr);18 extern void cli_finit(cliuser_t *usr);19 17 20 18 #endif -
uspace/app/bdsh/util.c
rb510d52 re2ea8d7e 53 53 #include "util.h" 54 54 55 extern volatile int cli_errno; 56 55 57 /* some platforms do not have strdup, implement it here. 56 58 * Returns a pointer to an allocated string or NULL on failure */ … … 60 62 void *ret = malloc(len); 61 63 62 if (ret == NULL) 64 if (ret == NULL) { 65 cli_errno = CL_ENOMEM; 63 66 return (char *) NULL; 64 67 } 68 69 cli_errno = CL_EOK; 65 70 return (char *) memcpy(ret, s1, len); 66 71 } … … 80 85 *s1 = realloc(*s1, len); 81 86 82 if (*s1 == NULL) 83 return -1; 87 if (*s1 == NULL) { 88 cli_errno = CL_ENOMEM; 89 return -1; 90 } 84 91 85 92 memset(*s1, 0, sizeof(*s1)); 86 93 memcpy(*s1, s2, len); 94 cli_errno = CL_EOK; 87 95 return (int) len; 88 96 } 89 97 90 /* An asprintf() for concantenating paths. Allocates the system PATH_MAX value, 91 * expands the formatted string and re-sizes the block s1 points to accordingly. 92 * 93 * Returns the length of the new s1 on success, -1 on failure. On failure, an 94 * attempt is made to return s1 unmodified for sanity, in this case 0 is returned. 95 * to indicate that s1 was not modified. 96 * 97 * FIXME: ugly hack to get around asprintf(), if you use this, CHECK ITS VALUE! */ 98 /* An asprintf() for formatting paths, similar to asprintf() but ensures 99 * the returned allocated string is <= PATH_MAX. On failure, an attempt 100 * is made to return the original string (if not null) unmodified. 101 * 102 * Returns: Length of the new string on success, 0 if the string was handed 103 * back unmodified, -1 on failure. On failure, cli_errno is set. 104 * 105 * We do not use POSIX_PATH_MAX, as it is typically much smaller than the 106 * PATH_MAX defined by the kernel. 107 * 108 * Use this like: 109 * if (1 > cli_psprintf(&char, "%s/%s", foo, bar)) { 110 * cli_error(cli_errno, "Failed to format path"); 111 * stop_what_your_doing_as_your_out_of_memory(); 112 * } 113 */ 114 98 115 int cli_psprintf(char **s1, const char *fmt, ...) 99 116 { 100 117 va_list ap; 101 118 size_t needed, base = PATH_MAX + 1; 119 int skipped = 0; 120 char *orig = NULL; 102 121 char *tmp = (char *) malloc(base); 103 122 104 if (NULL == tmp) 105 return -1; 106 107 char *orig = *s1; 108 123 /* Don't even touch s1, not enough memory */ 124 if (NULL == tmp) { 125 cli_errno = CL_ENOMEM; 126 return -1; 127 } 128 129 /* If re-allocating s1, save a copy in case we fail */ 130 if (NULL != *s1) 131 orig = cli_strdup(*s1); 132 133 /* Print the string to tmp so we can determine the size that 134 * we actually need */ 109 135 memset(tmp, 0, sizeof(tmp)); 110 136 va_start(ap, fmt); 111 vsnprintf(tmp, base, fmt, ap); 137 /* vsnprintf will return the # of bytes not written */ 138 skipped = vsnprintf(tmp, base, fmt, ap); 112 139 va_end(ap); 140 141 /* realloc/alloc s1 to be just the size that we need */ 113 142 needed = strlen(tmp) + 1; 114 143 *s1 = realloc(*s1, needed); 144 115 145 if (NULL == *s1) { 146 /* No string lived here previously, or we failed to 147 * make a copy of it, either way there's nothing we 148 * can do. */ 149 if (NULL == *orig) { 150 cli_errno = CL_ENOMEM; 151 return -1; 152 } 153 /* We can't even allocate enough size to restore the 154 * saved copy, just give up */ 116 155 *s1 = realloc(*s1, strlen(orig) + 1); 117 156 if (NULL == *s1) { 118 157 free(tmp); 158 free(orig); 159 cli_errno = CL_ENOMEM; 119 160 return -1; 120 161 } 162 /* Give the string back as we found it */ 121 163 memset(*s1, 0, sizeof(*s1)); 122 164 memcpy(*s1, orig, strlen(orig) + 1); 123 165 free(tmp); 166 free(orig); 167 cli_errno = CL_ENOMEM; 124 168 return 0; 125 169 } 170 171 /* Ok, great, we have enough room */ 126 172 memset(*s1, 0, sizeof(*s1)); 127 173 memcpy(*s1, tmp, needed); 128 174 free(tmp); 129 175 176 /* Free tmp only if s1 was reallocated instead of allocated */ 177 if (NULL != orig) 178 free(orig); 179 180 if (skipped) { 181 /* s1 was bigger than PATH_MAX when expanded, however part 182 * of the string was printed. Tell the caller not to use it */ 183 cli_errno = CL_ETOOBIG; 184 return -1; 185 } 186 187 /* Success! */ 188 cli_errno = CL_EOK; 130 189 return (int) needed; 131 190 } … … 137 196 int c, sc; 138 197 139 if (s == NULL && (s = *last) == NULL) 198 if (s == NULL && (s = *last) == NULL) { 199 cli_errno = CL_EFAIL; 140 200 return (NULL); 201 } 141 202 142 203 cont:
Note:
See TracChangeset
for help on using the changeset viewer.