int cmd_execbg (Shell *shell, void *args) { if (array_is_empty (args)) { fprintf (stderr, "The command execbg expects at least one argument.\n"); return -1; } return execute (array_get (args, 0), args, EXEC_BG, NULL); }
int cmd_sdc (Shell *s, void *args) { if (array_is_empty (args)) { fprintf (stderr, "The command sdc expects at least one argument.\n"); return -1; } shell_set_default_command (s, array_get (args, 0)); return 0; }
int cmd_exec (Shell *shell, void *args) { if (array_is_empty (args)) { fprintf (stderr, "The command exec expects at least one argument.\n"); return -1; } execute (array_get (args, 0), args, EXEC_REPLACE, NULL); error (0, errno, "Error"); return -1; }
int cmd_help (Shell *shell, void *args) { if (array_is_empty (args)) { printf ("Available commands:\n"); const Array *a = shell_get_commands (shell); for (size_t i = 0, n = array_get_size (a); i < n; ++i) { const command_t *command = array_get (a, i); printf (" %s\n", command->name); } return 0; } int return_value = 0; for (size_t i = 0, n = array_get_size (args); i < n; ++i) { const char *name = array_get (args, i); const command_t *p = shell_get_command (shell, name); if (!p) // Command not found. { fprintf (stderr, "No command \"%s\" found.\n", name); --return_value; } else { printf ("- %s: %s", name, name); if (p->args_list) { printf (" %s", p->args_list); } printf ("\n "); if (p->help) { printf ("%s", p->help); } else { printf ("%s", "No help available for this command."); } printf ("\n"); } } return return_value; }
int cmd_history (Shell *shell, void *args) { if (array_is_empty (args)) { fprintf (stderr, "The command history expects at least one argument.\n"); return -1; } const char *opt = array_get (args, 0); if (0 == strcmp ("-c", opt)) { clear_history (); return 0; } return -1; }
int cmd_execfg (Shell *shell, void *args) { if (array_is_empty (args)) { fprintf (stderr, "The command execfg expects at least one argument.\n"); return -1; } int status; if (-1 == execute (array_get (args, 0), args, EXEC_FG, &status)) { fprintf (stderr, "fork () failed.\n"); return -1; } return status; }
int cmd_version (Shell *shell, void *args) { if (!array_is_empty (args)) { const char *arg = array_get (args, 0); if (0 == strcmp ("-v", arg)) { printf ("%s\n", get_prog_version ()); return 0; } else if (0 == strcmp ("-n", arg)) { printf ("%s\n", get_prog_version_name ()); return 0; } } print_version (); return 0; }
int ArrayMain(void) { int sum[] = { 1,2,3,4,5,6,7,8,9 }; struct Array tmp; int *ret; int *ret2; int *ret3; int *ret4; array_init(&tmp, 128); /* add an element and get it */ array_insert_rear(&tmp, sum); ret = array_get_head(&tmp); printf("%d(should be 1)\n", *ret); /* array is 2 1 3 */ array_insert_head(&tmp, sum + 1); array_insert_rear(&tmp, sum + 2); ret2 = array_get_rear(&tmp); printf("%d (should be 3)\n", *ret2); /* array is 4 1 3 */ array_set_by_index(&tmp, sum + 3, 0); ret3 = array_get_head(&tmp); printf("%d(should be 4)\n", *ret3); /* array is 1 3 */ array_remove_head(&tmp); printf("%d(should be 2)\n", array_get_length(&tmp)); while (!array_is_empty(&tmp)) { ret4 = array_get_head(&tmp); printf("%d ", *ret4); array_remove_head(&tmp); } printf("(should be 1 3)\n"); return 0; }
int cmd_setenv (Shell *shell, void *args) { if (array_is_empty (args)) { char **p = environ; while (*p) { printf ("%s\n", *p); ++p; } } else { for (size_t i = 0, n = array_get_size (args); i < n; ++i) { putenv (strdup (array_get (args, i))); } } return 0; }
int cmd_cd (Shell *shell, void *args) { char *new_pwd; if (!array_is_empty (args)) { if (0 == strcmp ("-", array_get (args, 0))) { if ( (new_pwd = getenv ("OLDPWD")) ) { new_pwd = strdup (new_pwd); } else { fprintf (stderr, "Failed to get previous directory.\n"); return -1; } } else { new_pwd = strdup (array_get (args, 0)); } } else if (!get_home_dir ()) { fprintf (stderr, "Failed to get home directory.\n"); return -1; } else { new_pwd = strdup (get_home_dir ()); } char *old_pwd = get_cwd (); if (0 != chdir (new_pwd)) { fprintf (stderr, "Failed to change directory to \"%s\".\n", new_pwd); return -1; } // Because new_cwd does not contain an absolute path. free (new_pwd); if (old_pwd) { setenv ("OLDPWD", old_pwd, 1); free (old_pwd); } else { unsetenv ("OLDPWD"); } if ( (new_pwd = get_cwd ()) ) { setenv ("PWD", new_pwd, 1); free (new_pwd); } else { unsetenv ("PWD"); } return 0; }
enum dsc_image_parse_result dsc_image_parse(struct tbd_create_info *const info_in, struct dyld_shared_cache_info *const dsc_info, struct dyld_cache_image_info *const image, const uint64_t macho_options, const uint64_t tbd_options, __unused const uint64_t options) { /* * The mappings store the data-structures that make up a mach-o file for all * dyld_shared_cache images. * * To find out image's data, we have to recurse the mappings, to find the * one containing our file. */ uint64_t max_image_size = 0; const uint64_t file_offset = get_image_file_offset_from_address(dsc_info, image->address, &max_image_size); if (file_offset == 0) { return E_DSC_IMAGE_PARSE_NO_CORRESPONDING_MAPPING; } if (max_image_size < sizeof(struct mach_header)) { return E_DSC_IMAGE_PARSE_SIZE_TOO_SMALL; } const uint8_t *const map = dsc_info->map; const struct mach_header *const header = (const struct mach_header *)(map + file_offset); const uint32_t magic = header->magic; const bool is_64 = magic == MH_MAGIC_64 || magic == MH_CIGAM_64; const bool is_big_endian = magic == MH_CIGAM || magic == MH_CIGAM_64; if (is_64) { if (max_image_size < sizeof(struct mach_header_64)) { return E_DSC_IMAGE_PARSE_SIZE_TOO_SMALL; } } else { const bool is_fat = magic == FAT_MAGIC || magic == FAT_MAGIC_64 || magic == FAT_CIGAM || magic == FAT_CIGAM_64; if (is_fat) { return E_DSC_IMAGE_PARSE_FAT_NOT_SUPPORTED; } if (!is_big_endian && magic != MH_MAGIC) { return E_DSC_IMAGE_PARSE_NOT_A_MACHO; } } const uint32_t flags = header->flags; if (flags & MH_TWOLEVEL) { info_in->flags_field |= TBD_FLAG_FLAT_NAMESPACE; } if (!(flags & MH_APP_EXTENSION_SAFE)) { info_in->flags_field |= TBD_FLAG_NOT_APP_EXTENSION_SAFE; } struct symtab_command symtab = {}; /* * The symbol-table and string-table offsets are absolute, not relative from * image's base, but we still need to account for shared-cache's start and * size. * * To accomplish this, we parse the symbol-table separately. * * The section's offset are also absolute (relative to the map, not to the * header). */ const uint64_t arch_bit = dsc_info->arch_bit; const uint64_t lc_options = O_MACHO_FILE_PARSE_DONT_PARSE_SYMBOL_TABLE | O_MACHO_FILE_PARSE_SECT_OFF_ABSOLUTE | macho_options; struct mf_parse_load_commands_from_map_info info = { .map = map, .map_size = dsc_info->size, .macho = (const uint8_t *)header, .macho_size = max_image_size, .arch = dsc_info->arch, .arch_bit = arch_bit, .available_map_range = dsc_info->available_range, .is_64 = is_64, .is_big_endian = is_big_endian, .ncmds = header->ncmds, .sizeofcmds = header->sizeofcmds, .tbd_options = tbd_options, .options = lc_options }; const enum macho_file_parse_result parse_load_commands_result = macho_file_parse_load_commands_from_map(info_in, &info, &symtab); if (parse_load_commands_result != E_MACHO_FILE_PARSE_OK) { return translate_macho_file_parse_result(parse_load_commands_result); } /* * If symtab is invalid, we can simply assume that no symbol-table was * found, but that this was ok from the options as * macho_file_parse_load_commands_from_map didn't return an error-code. */ if (symtab.cmd != LC_SYMTAB) { return E_DSC_IMAGE_PARSE_OK; } /* * For parsing the symbol-tables, we provide the full dyld_shared_cache map * as the symbol-table and string-table offsets are relative to the full * map, not relative to the mach-o header. */ enum macho_file_parse_result ret = E_MACHO_FILE_PARSE_OK; if (is_64) { ret = macho_file_parse_symbols_64_from_map(info_in, map, dsc_info->available_range, arch_bit, is_big_endian, symtab.symoff, symtab.nsyms, symtab.stroff, symtab.strsize, tbd_options); } else { ret = macho_file_parse_symbols_from_map(info_in, map, dsc_info->available_range, arch_bit, is_big_endian, symtab.symoff, symtab.nsyms, symtab.stroff, symtab.strsize, tbd_options); } if (ret != E_MACHO_FILE_PARSE_OK) { return translate_macho_file_parse_result(ret); } if (!(tbd_options & O_TBD_PARSE_IGNORE_MISSING_EXPORTS)) { if (array_is_empty(&info_in->exports)) { return E_DSC_IMAGE_PARSE_NO_EXPORTS; } } info_in->archs = arch_bit; info_in->archs_count = 1; info_in->flags |= F_TBD_CREATE_INFO_EXPORTS_HAVE_FULL_ARCHS; return E_DSC_IMAGE_PARSE_OK; }