Beispiel #1
0
void asset_reload_all() {

  debug("Reloading All Assets...");

  list* asset_names = list_new();

  for(int i = 0; i < asset_dict->size; i++) {
    struct bucket* b = asset_dict->buckets[i];
    while(b != NULL) {
      char* new_name = malloc(strlen(b->key)+1);
      strcpy(new_name, b->key);
      list_push_back(asset_names, new_name);
      b = b->next;
    }
  }

  for(int i = 0; i < asset_names->num_items; i++) {
    file_unload(P(list_get(asset_names, i)));
  }

  for(int i = 0; i < asset_names->num_items; i++) {
    /*
    ** Assets can reload their child assets before we do
    ** So it is important we check before loading again
    */
    if (!file_isloaded(P(list_get(asset_names, i)))) {
      file_load(P(list_get(asset_names, i)));
    }
  }

  list_delete_with(asset_names, free);

  asset_cache_flush();
}
Beispiel #2
0
void folder_unload(fpath folder) {

  folder = asset_map_filename(folder);

  debug("Unloading Folder: '%s'", folder.ptr);
  DIR* dir = opendir(folder.ptr);

  if (dir == NULL) {
    error("Could not open directory '%s' to unload.\n", folder.ptr);
  }

  struct dirent* ent;
  while ((ent = readdir(dir)) != NULL) {

    if ((strcmp(ent->d_name,".") != 0) &&
        (strcmp(ent->d_name,"..") != 0)) {

      fpath filename = folder;
      strcat(filename.ptr, ent->d_name);

      if(dict_contains(asset_dict, filename.ptr) ) {
        file_unload(filename);
      }

    }
  }
  closedir(dir);
}
Beispiel #3
0
void asset_reload_type_id(type_id type) {

  debug("Reloading Assets of type '%s'...", type_id_name(type));

  fpath ext;

  /* Find the file extension for given type */
  for(int i=0; i < num_asset_handlers; i++) {
    asset_handler handler = asset_handlers[i];
    if (handler.type == type) {
      strcpy(ext.ptr, handler.extension);
      break;
    }
  }

  list* asset_names = list_new();

  for(int i = 0; i < asset_dict->size; i++) {
    struct bucket* b = asset_dict->buckets[i];
    while(b != NULL) {
      fpath bucket_ext;
      SDL_PathFileExtension(bucket_ext.ptr, b->key);

      if (strcmp(bucket_ext.ptr, ext.ptr) == 0) {
        char* new_name = malloc(strlen(b->key)+1);
        strcpy(new_name, b->key);
        list_push_back(asset_names, new_name);
      }

      b = b->next;
    }
  }

  for(int i = 0; i < asset_names->num_items; i++) {
    file_unload(P(list_get(asset_names, i)));
  }

  for(int i = 0; i < asset_names->num_items; i++) {
    /*
    ** Assets can reload their child assets before we do
    ** So it is important we check before loading again
    */
    if (!file_isloaded(P(list_get(asset_names, i)))) {
      file_load(P(list_get(asset_names, i)));
    }
  }

  list_delete_with(asset_names, free);

  asset_cache_flush();
}
Beispiel #4
0
int kexecve(const char *filename, char *const argv[],
                  char *const envp[])
{
    // If first line is #! exec interpreter and feed
    // it the command line options and the file.
    // Otherwise, load the entire file into RAM,
    // and call image_load.
    // On error, return -1 and set errno.
    // On success, no return (0).
    // The latter implies we have to setup the process context
    // and free prior RAM.
    char        *image      = NULL;
    unsigned int image_size = 0;
    unsigned int i          = 0;
    unsigned int j          = 0;
    unsigned int start      = 0;
    unsigned int end        = 0;
    unsigned int len        = 0;
    int argc                = 0;
    char interpreter[MAX_PATH]  = {0};
    char args[MAX_PATH]         = {0};
    char *arg               = NULL;
    char **argv2            = NULL;
    static int nr_recursion = 0;
    int delete_argv2        = 0;
    start_t elf_entry       = NULL;
    unsigned char *exec     = NULL;
    unsigned int exec_size  = 0;

    asm_disable_interrupt();

    if(!file_load(filename, &image, &image_size)) {
        printk("execve:: error loading file\n");
        asm_enable_interrupt();
        return -1;
    }

    // TODO - We should store argv2 in the process and
    //        and mark if it should be free'd on exit.

    // Handle interpreter invocation.
    if(image[0] == '#' && image[1] == '!') {
#ifdef _TEST_EXEC
        printk("execve:: image = [%s]\n", image);
#endif
        for(i = 2; i < image_size; ++i) {
            if(!isspace(image[i])) {
                start = i;
                break;
            }
        }
        for(i = start + 1; i < image_size; ++i) {
            if(isspace(image[i])) {
                end = i;
                break;
            }
        }
        for(i = start,j=0; i < end; ++i,++j) {
            if(j >= MAX_PATH) {
                printk("execve:: interpreter name too long\n");
                asm_enable_interrupt();
                return -1;
            }
            interpreter[j] = image[i];
        }
        for(i = end,j=0; i < image_size; ++i,++j) {
            if(image[i]=='\n') {
                break;
            }
            args[j]=image[i];
        }
        arg = strtok(args," \t");
        i   = 0;
        while(arg) {
            if(!argv2) {
                argv2 = (char **)malloc(sizeof(char *) * MAX_PATH + 1);
            }
            if(i >= MAX_PATH) {
                free((void *)argv2);
                printk("execve:: error processing interpreter args\n");
                asm_enable_interrupt();
                return -1;
            }
            len = strlen(arg);
            argv2[i] = (char *)malloc(len + 1);
            strcpy(argv2[i],arg);
            argv2[i][len]='\0';
            ++i;
            arg = strtok(NULL," \t");
        }
        /* Now get the rest of the args. */
        j = 0;
        while(i < MAX_PATH && argv[j]) {
            len = strnlen(argv[j],1024);
            argv2[i] = (char *)malloc(len + 1);
            strncpy(argv2[i],argv[j],1024);
            argv2[i][len] = '\0';
            ++i;
            ++j;
        }

        if(argv[j] != NULL) {
            free((void *)argv2);
            printk("execve:: error argv[j] != NULL\n");
            asm_enable_interrupt();
            return -1;
        }

        /* Now copy the script filename. */
        if(i >= MAX_PATH) {
            free((void *)argv2);
            printk("execve:: error i >= MAX_PATH\n");
            asm_enable_interrupt();
            return -1;
        }
#if 0
        /* argv[0] should be the filename */
        len = strlen(filename);
        argv2[i] = (char *)malloc(len + 1);
        strcpy(argv2[i],filename);
        argv2[i][len]='\0';
        ++i;
        if(i >= MAX_PATH) {
            free((void *)argv2);
            printk("execve:: error i >= MAX_PATH[2]\n");
            return -1;
        }
#endif
        argv2[i]='\0';
        // Free the original file loaded.
        if(!file_unload(&image)) {
            free((void *)argv2);
            printk("execve:: error unloading file [%s]\n",filename);
            asm_enable_interrupt();
            return -1;
        }

#ifdef _TEST_EXEC
        printk("interpreter [%s]\n",interpreter);
        for(i = 0; argv2[i]; ++i) {
            printk("argv2[%d]=[%s]\n",i,argv2[i]);
        }
        for(i = 0; envp[i]; ++i) {
            printk("envp[%d]=[%s]\n",i,envp[i]);
        }
        return 0;
#else
        // Call ourselves with the proper paramters.
        if(nr_recursion > EXEC_MAX_RECURSION) {
            printk("execve:: error nr_recursion > EXEC_MAX_RECURSION\n");
            asm_enable_interrupt();
            return -1;
        }
        nr_recursion++;
        asm_enable_interrupt();
        return kexecve(interpreter, argv2, envp);
#endif
    }

    // If we are in a recursive call, then we
    // allocated argv2 and it must be free'd.
    if(nr_recursion) {
        delete_argv2 = 1;
    } else {
        delete_argv2 = 0;
        argv2 = (char **)argv;
    }
    for(i = 0; argv2[i]; ++i) {
        argc++;
    }
    nr_recursion--;
    // At this point, the ELF image is in RAM.
    // Parse it out and jump to it.
    LINE();
    elf_entry = image_load(image, image_size, &exec, &exec_size);
    LINE();

    // TODO - Do we put envp into the process struct
    //        and make it accessible via getenv() ?
#ifdef _TEST_EXEC
    printk("elf_entry=[%x]\n",elf_entry);
    LINE();
    i = elf_entry();
    printk("returns =[%d]\n",i);
#endif
    LINE();

    if(!file_unload(&image)) {
        if(nr_recursion) {
            for(i = 0; i < argc; ++i) {
                free((void *)argv2[i]);
            }
            free((void *)argv2);
        }
#ifdef _TEST_EXEC
        munmap(elf_entry, image_size);
#endif
        printk("execve:: error unloading file [%s]\n",filename);
        return -1;
    }
#ifdef _TEST_EXEC
        munmap(exec,exec_size);
#else // Kernel
    //
    // - Set up the entry point and args
    // into the process structure...
    // Mark flag for first time execution
    // as we need to call into the entry point
    // when we schedule the process.
    // - Free the old process image...
    //
    // We have:-
    //
    // exec         - memory image to free 
    // exec_size    - size of image
    // elf_entry    - pointer to the start method
    // argc         - argument count
    // argv2        - arguments
    // envp         - environment
    // delete_argv2 - flag to indicate if argv2 should be free'd
    //
    // Free up prior memory.
    // Should also happen in exit.c.
    if(current_process->p_exec) {
        mem_unset_read_only(current_process->p_exec,
                            current_process->p_exec_size);
        free((void *)current_process->p_exec);
    }
    if(current_process->p_delete_argv) {
        for(i = 0; i < current_process->p_argc; ++i) {
            free((void *)current_process->p_argv[i]);
        }
        free((void *)current_process->p_argv);
    }
    // Close all open files.
    for(i = 0; i < MAX_FILES; ++i) {
        for(j = 0; j < MAX_FILES; ++j) {
            if(current_process->file_desc[i] == 
               &(current_process->file_tab[j])) {
                kclose(i);
            }
        }
    }
    // Close all open directories.
    for(i = 0; i < MAX_DIR; ++i) {
        if(current_process->dir_tab[i].__allocation == DEV_BLOCK_SIZE) {
            kclosedir(&(current_process->dir_tab[i])); 
        }
    }
    // Setup our new image.
    current_process->p_exec         = exec;
    current_process->p_exec_size    = exec_size;
    current_process->p_elf_entry    = elf_entry;
    current_process->p_argc         = argc;
    current_process->p_argv         = argv2;
    current_process->p_envp         = envp;
    current_process->p_delete_argv  = delete_argv2;
    current_process->p_first_exec   = 1;
    asm_enable_interrupt();
    schedule();
#endif
    return 0;

}/* kexecve */
Beispiel #5
0
void file_reload(fpath filename) {
  file_unload(filename);
  file_load(filename);
  asset_cache_flush();
}