Пример #1
0
static void set_page_tables(void)
{
    /* map every memory region to itself */
    map_section(0, 0, 0x1000, CACHE_NONE);

    /* map RAM and enable caching for it */
    map_section(DRAM_ORIG, CACHED_DRAM_ADDR, MEMORYSIZE, CACHE_ALL);
    map_section(DRAM_ORIG, BUFFERED_DRAM_ADDR, MEMORYSIZE, BUFFERED);
}
Пример #2
0
void soc_map(uint32_t l1_address)
{
	//Map Integrator
	map_section(l1_address, 0xf1000000, 0x10000000, FALSE);
	// map Timer
	map_section(l1_address, 0xf1300000, 0x13000000, FALSE);
	//map Pic
	map_section(l1_address, 0xf1400000, 0x14000000, FALSE);
	//Map UART
	map_section(l1_address, 0xf1600000, 0x16000000, FALSE);

}
Пример #3
0
void mem_initialize(void)
{
	u32 cr;
	u32 cookie = irq_kill();

	gecko_printf("MEM: cleaning up\n");

	_ic_inval();
	_dc_inval();
	_tlb_inval();

	gecko_printf("MEM: unprotecting memory\n");

	mem_protect(0,NULL,NULL);

	gecko_printf("MEM: mapping sections\n");

	memset32(__page_table, 0, 16384);

	map_section(0x000, 0x000, 0x018, WRITEBACK_CACHE | DOMAIN(0) | AP_RWUSER);
	map_section(0x100, 0x100, 0x040, WRITEBACK_CACHE | DOMAIN(0) | AP_RWUSER);
	map_section(0x0d0, 0x0d0, 0x001, NONBUFFERABLE | DOMAIN(0) | AP_RWUSER);
	map_section(0x0d8, 0x0d8, 0x001, NONBUFFERABLE | DOMAIN(0) | AP_RWUSER);
	map_section(0xfff, 0xfff, 0x001, WRITEBACK_CACHE | DOMAIN(0) | AP_RWUSER);

	set_dacr(0xFFFFFFFF); //manager access for all domains, ignore AP
	set_ttbr((u32)__page_table); //configure translation table

	_drain_write_buffer();

	cr = get_cr();

#ifndef NO_CACHES
	gecko_printf("MEM: enabling caches\n");

	cr |= CR_DCACHE | CR_ICACHE;
	set_cr(cr);

	gecko_printf("MEM: enabling MMU\n");

	cr |= CR_MMU;
	set_cr(cr);
#endif

	gecko_printf("MEM: init done\n");

	irq_restore(cookie);
}
Пример #4
0
/** Create a mapping in an MMU context.
 * @param ctx		Context to map in.
 * @param virt		Virtual address to map.
 * @param phys		Physical address to map to.
 * @param size		Size of the mapping to create.
 * @return		Whether created successfully. */
bool mmu_map(mmu_context_t *ctx, target_ptr_t virt, phys_ptr_t phys, target_size_t size) {
	uint32_t i;

	if(virt % PAGE_SIZE || phys % PAGE_SIZE || size % PAGE_SIZE)
		return false;

	/* Map using sections where possible. To do this, align up to a 1MB
	 * boundary using small pages, map anything possible with sections,
	 * then do the rest using small pages. If virtual and physical addresses
	 * are at different offsets from a section boundary, we cannot map
	 * using sections. */
	if((virt % LARGE_PAGE_SIZE) == (phys % LARGE_PAGE_SIZE)) {
		while(virt % LARGE_PAGE_SIZE && size) {
			map_small(ctx, virt, phys);
			virt += PAGE_SIZE;
			phys += PAGE_SIZE;
			size -= PAGE_SIZE;
		}
		while(size / LARGE_PAGE_SIZE) {
			map_section(ctx, virt, phys);
			virt += LARGE_PAGE_SIZE;
			phys += LARGE_PAGE_SIZE;
			size -= LARGE_PAGE_SIZE;
		}
	}

	/* Map whatever remains. */
	for(i = 0; i < size; i += PAGE_SIZE)
		map_small(ctx, virt + i, phys + i);

	return true;
}
Пример #5
0
void	load_section(Elf64_Ehdr *header, char *file, char *section_name, t_section *section_ptr)
{
  Elf64_Half nb_entry;
  
  Elf64_Shdr	*section;
  char	*name;
  
  nb_entry = header->e_shnum;
  for (int i = 0; i < nb_entry; i++)
    {
      section = get_section(header, file, i);
      name = get_string(section->sh_name, header, file);
      if (!strcmp(name, section_name))
	{
	  section_ptr->data = map_section(file, section);
	  section_ptr->size = section->sh_size;
	  break;
	}
    }
}
Пример #6
0
/* everything is based on this exec, we have an extra argument
   (execonly) to differentiate between the exec and fork_exec
   families.  the difference is that the latter forks and then execs
   the process thereby returning in the parent
   */
static int
fork_execve0(const char *path, char *const argv_ori[], char * const envptr[], 
	     int execonly) {
  int envid;
  int fd;

  u_int k = 0;
  struct Uenv cu;
  int argc;
  char **argv_tmp,*argv_p,**argv;
  u32 lmagic;
  char *cmagic = (char*)&lmagic;
  u32 entry_point = 0;
  int running_emulator = 0;
  char *emu_path = NULL;
  char **argv_ori_tmp = (char**)argv_ori;
  char **argv_ori_tmp2;
#define FE_PATH (running_emulator ? emu_path : path)
#ifdef PROCESS_TABLE
  int NewPid = 0;
#endif
  char *extra_argv_space = NULL;
#if 0
  {
    extern void pr_fds();
    fprintf(stderr,"FDS BEFORE EXEC PID: %d execonly: %d\n",getpid(),execonly);
    pr_fds;
  }
#endif
//  printf("fork_execve0: path: %s\n",path);
#if 0
  for(argc = 0; argv_ori[argc] ; argc++) 
    kprintf("%d) %s\n",argc,argv_ori[argc]);
#endif

  proprintf("allocate env, and open file\n");
  ISTART(misc,execve);
  ISTART(misc,step1);
  /* fprintf(stderr,"fe_nfs2 %s\n",FE_PATH); */
  if (! (envid = sys_env_alloc (0))) {
    fprintf(stderr,"could not sys_env_alloc\n");
    goto err;
  }

open_binary:
  /* verify executable permission */
  if (access(FE_PATH, X_OK) == -1) {
    /* access will set errno */
    goto fork_execve0_end_error;
  }
  /* open the executable */
  fd = open (FE_PATH, O_RDONLY, 0644);
  if (fd < 0) {
    /* open will set errno */
    /*fprintf(stderr,"1could not open path %s, errno: %d\n",FE_PATH,errno);*/
    goto fork_execve0_end_error;
  }
  STOPP(misc,step1);
  proprintf("read file and open interpreter if necessary\n");
  ISTART(misc,step2);

  /* read in the magic number */
  if (read(fd, cmagic, 2) < 2) {
    errno = ENOEXEC;
    goto fork_execve0_end_error_closefd;
  }

  /* check for interpreter */
  if (cmagic[0] == '#' && cmagic[1] == '!') {
    int intersize;
    char inter[MAXINTERP+1], *interp;

    if ((intersize = read(fd,inter,MAXINTERP)) == -1) {
      errno = ENOEXEC;
      goto fork_execve0_end_error_closefd;
    }
    inter[intersize] = '\n';
    interp = inter;
    
    /* skip spaces */
    while ((*interp == ' ' || *interp == '\t') && 
	   *interp != '\n')
      interp++;
    
    {
      char **v = (char **)argv_ori_tmp;
      while(*v++);
      extra_argv_space = (char *)malloc((char *)v - (char *)argv_ori_tmp + 
					MAXINTERP*(sizeof(char*)));
      if (!extra_argv_space) {
	fprintf(stderr,"execve could not allocate extra argv space for "
		"interpreted file\n");
	goto fork_execve0_end_error_closefd;
      }
    }
    argv = (char **)extra_argv_space;
    *argv++ = interp;

    while (*interp != ' ' && *interp != '\t' && 
	   *interp != (char)0 && *interp != '\n')
      interp++;
    
    if (*interp != 0 && *interp != '\n') {
      /* more arguments, we only copy one more */
      *interp++ = 0;
      /* skip spaces */
      while ((*interp == ' ' || *interp == '\t') && 
	     *interp != '\n')
	interp++;

      *argv++ = interp;
      while (*interp != ' ' && *interp != '\t' && 
	     *interp != (char)0 && *interp != '\n')
	interp++;
      *interp = (char)0;
    } else {
      *interp = (char)0;
    }
    *argv++ = (char *)FE_PATH;
    argv_ori_tmp2 = argv_ori_tmp;
    argv_ori_tmp2++;
    while(*argv_ori_tmp2 != (char *) 0) {*argv++ = *argv_ori_tmp2++;}
    /* copy the 0 */
    *argv++ = *argv_ori_tmp2++;
    argv = (char **)extra_argv_space;
  
    close(fd);
    /* verify executable permission */
    if (access(argv[0], X_OK) == -1) {
      /* access will set errno */
      goto fork_execve0_end_error;
    }
    fd = open (argv[0], O_RDONLY, 0644);
    if (fd < 0) {
      /* open will set errno */
      /*fprintf(stderr,"2could not open path %s, errno: %d\n",argv[0],errno);*/
      goto fork_execve0_end_error;
    }
    /* read in the magic number (and nesting of interpreters not allowed) */
    if (read(fd, cmagic, 2) < 2 || (cmagic[0] == '#' && cmagic[1] == '!')) {
      errno = ENOEXEC;
      goto fork_execve0_end_error_closefd;
    }
  } else {
    argv = (char **)argv_ori_tmp;
  }

  STOPP(misc,step2);
  proprintf("read more magic and executable headers, check for emulation\n");
  ISTART(misc,step3);

  if (read(fd, &cmagic[2], 2) < 2) {
    errno = ENOEXEC;
    goto fork_execve0_end_error_closefd;
  }

  /* see whether we need to run an emulator */
  if (lmagic != 0700303000 && (lmagic & 0x0000ffff) != 0514) {
    if (running_emulator) {
      fprintf(stderr,"Emulator binary is in unrecognized executable "
	      "format.\n");
      goto fork_execve0_end_error_closefd;
    }
    else
      fprintf(stderr,"Unrecognized executable format; attempting to run " 
	      "emulator.\n");
    close(fd);
    {
      char **v = (char **)argv_ori_tmp;
      while(*v++);
      extra_argv_space = (char *)malloc((char *)v - (char *)argv_ori_tmp +
					2 * sizeof(char*));
      if (!extra_argv_space) {
	fprintf(stderr,"execve could not allocate extra argv space for "
		"copying args for emulator\n");
	goto fork_execve0_end_error_closefd;
      }
    }
    argv = (char **)extra_argv_space;
    running_emulator = 1;
    *argv++ = emu_path = getenv("EMULATOR");
    if (!FE_PATH) {
      fprintf(stderr,"EMULATOR environment variable not set to emulator path; "
	      "cannot run emulator.\n");
      goto fork_execve0_end_error;
    }
    *argv++ = (char *)path;
    argv_ori_tmp2 = argv_ori_tmp;
    argv_ori_tmp2++;
    while(*argv_ori_tmp2 != (char *) 0) {*argv++ = *argv_ori_tmp2++;}
    /* copy the 0 */
    *argv++ = *argv_ori_tmp2++;
    argv = (char **)extra_argv_space;
    argv_ori_tmp = argv;
    goto open_binary;
  }  

  /* check for original ExOS (OpenBSD) format - remove eventually */
  if (lmagic == 0700303000)
    {
      struct exec hdr;
      u_int byte_count, page_count;
      Pte *ptes;
      int i;

#if 0
      fprintf(stderr,"File uses old executable format.\n");
#endif
      /* allocate physical pages and read data into it. */

      /* read a.out headers */
      if (lseek(fd,0,SEEK_SET) == -1 ||
	  read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
	fprintf(stderr,"Invalid executable format.\n");
	errno = ENOEXEC;
	goto fork_execve0_end_error_closefd;
      }
      entry_point = hdr.a_entry;

      /* alloc this much memory */
      byte_count = hdr.a_text + hdr.a_data + hdr.a_bss;
      page_count = PGNO(PGROUNDUP(byte_count));

      /* allocate it in both child and parent areas */
      if ((ptes = malloc(sizeof(Pte) * page_count)) == 0) {
	errno = ENOEXEC;
	goto fork_execve0_end_error_closefd;
      }
      for (i=0; i < page_count; i++)
	ptes[i] = PG_U|PG_W|PG_P;
      STOPP(misc,step3);
      proprintf("allocate childs vm in both parent and child, read text+data "
		"(sz %ld)\n", hdr.a_text + hdr.a_data);
      ISTART(misc,read0);
      if (sys_self_insert_pte_range(k, ptes, page_count, TEMP_REGION) < 0 ||
	  sys_insert_pte_range(k, &vpt[PGNO(TEMP_REGION)], page_count, 
			       UTEXT, k, envid) < 0 ||
	  read(fd, (void*)TEMP_REGION, hdr.a_text + hdr.a_data) != 
	  hdr.a_text + hdr.a_data) {
	fprintf (stderr,"Binary file invalid or corrupt.\n");
	for (i=0; i < page_count; i++)
	  ptes[i] = 0;
	sys_self_insert_pte_range(k, ptes, page_count, TEMP_REGION);
	sys_insert_pte_range(k, ptes, page_count, UTEXT, k, envid);
	free(ptes);
	errno = ENOEXEC;
	goto fork_execve0_end_error_closefd;
      }

      STOPP(misc,read0);
      /* zero the bss */
      proprintf("bzero bss  (sz %ld)\n",hdr.a_bss);
      ISTART(misc,read1);
      bzero((void*)(TEMP_REGION + hdr.a_text + hdr.a_data), hdr.a_bss);

      STOP(misc,read1);
      PRNAME(misc,read1);
      proprintf("unmap TEMP_REGION (sz %d pages)\n", page_count);
      ISTART(misc,step4);
      /* unmap the used TEMP_REGION */
      for (i=0; i < page_count; i++)
	ptes[i] = 0;
      sys_self_insert_pte_range(k, ptes, page_count, TEMP_REGION);
      free(ptes);
    }
  else if ((lmagic & 0x0000ffff) == 0514) /* check for ExOS COFF format */
    {
      FILHDR hdr;
      AOUTHDR opthdr;
      SCNHDR shdr;
      int s;

      /* allocate physical pages and read data into it. */
      /* read file headers */
      if (lseek(fd,0,SEEK_SET) == -1 ||
	  read(fd, &hdr, FILHSZ) != FILHSZ ||
	  hdr.f_opthdr != sizeof(opthdr) ||
	  !(hdr.f_flags & F_EXEC) ||
	  read(fd, &opthdr, hdr.f_opthdr) != hdr.f_opthdr) {
	fprintf(stderr,"Invalid executable format.\n");
	errno = ENOEXEC;
	goto fork_execve0_end_error_closefd;
      }
      entry_point = opthdr.entry;

      /* ensure ZMAGIC */
      if (opthdr.magic != ZMAGIC) {
	fprintf(stderr,"Exec cannot read non-ZMAGIC COFF executables.\n");
	errno = ENOEXEC;
	goto fork_execve0_end_error_closefd;
      }

      STOPP(misc,step3);
      proprintf("read in and map/zero COFF sections then unmap\n");
      ISTART(misc,read0);
      for (s=0; s < hdr.f_nscns; s++)
	if (read(fd, &shdr, SCNHSZ) != SCNHSZ ||
	    map_section(k, fd, &shdr, envid) == -1) {
	  fprintf(stderr,"Invalid executable format.\n");
	  errno = ENOEXEC;
	  goto fork_execve0_end_error_closefd;
	}
      STOPP(misc,read0);
      proprintf("nothing\n");
      ISTART(misc,read1);
      STOP(misc,read1);
      PRNAME(misc,read1);
      proprintf("nothing\n");
      ISTART(misc,step4);
    } else {
      fprintf(stderr, "Unknown file format.\n");
      errno = ENOEXEC;
      goto fork_execve0_end_error_closefd;
    }

  STOPP(misc,step4);

  close (fd);

  proprintf("Allocate stack for child\n");
  ISTART(misc,step5);

  /* allocate stack space for child */
  if (sys_insert_pte (k, PG_U|PG_W|PG_P, USTACKTOP-NBPG, k, envid) < 0) {
    fprintf(stderr,"sys_insert_pte failed\n");
    errno = ENOEXEC;
    goto fork_execve0_end_error;
  }

  STOPP(misc,step5);
  proprintf("ExecuteOnExecHandlers\n");
  ISTART(misc,step6);
  if (ExecuteOnExecHandlers(k,envid,execonly) == -1) {
    fprintf(stderr,"cleanup code not done yet\n");
    assert(-1);
  }
  STOPP(misc,step6);
  proprintf("Process table stuff\n");
  ISTART(misc,step7);
#ifdef PROCESS_TABLE
  if (execonly) {
    /* because true exec */
    NewPid = getpid();
    /* XXX -- this locking is ... up. I should really come up with a better
       convention as to what expects to be called with things locked and
       what doesn't */
    dlockputs(__PROCD_LD,"fork_execve0 get lock ");
    EXOS_LOCK(PROCINFO_LOCK);
    dlockputs(__PROCD_LD,"... got lock\n");
    EnterCritical (); 

    ProcChangeEnv(NewPid,envid);

    EXOS_UNLOCK(PROCINFO_LOCK);
    dlockputs(__PROCD_LD,"fork_execve0 release lock\n");
    ExitCritical (); 
  } else {
    /* because we are forking */
    NewPid = AllocateFreePid (envid);
  }
#endif  

#ifdef PROCESS_TABLE
  cu = u;
  if (!execonly) {
    AddProcEntry (&cu, (char *)FE_PATH, (char **)argv, NewPid, UAREA.pid);
    if ((cu.parent_slot = GetChildSlot (NewPid)) < 0) {
      errno = ENOEXEC;
      goto fork_execve0_end_error;
    }
  } else {
    /* TO TOM: what do we do this for?  */
    strncpy (UAREA.name, argv[0], U_NAMEMAX-1);
    UAREA.name[U_NAMEMAX-1] = '\0';
  }
  /* XXX -- on an exec we'll forget to unref our children's pids */
  /* TO TOM: shouldnt this clearchildinfo be at the top */
  ClearChildInfo (&cu);
  strncpy (cu.name, FE_PATH, U_NAMEMAX-1);
  cu.name[U_NAMEMAX-1] = '\0';
  cu.u_chld_state_chng = 0;
#endif /* PROCESS_TABLE */
  cu.u_in_critical = 0;
  cu.u_status = U_RUN;
  cu.u_entprologue = entry_point;
  cu.u_next_timeout = 0;
  cu.u_in_pfault = 0;
  cu.u_revoked_pages = 0;
  cu.u_donate = -1;

  STOPP(misc,step7);
  proprintf("Argv and Environment copying\n");
  ISTART(misc,step8);


//  printf("ENTERING ARGV COPY\n");
  /* ----------------------------------------------------------------------------- */
  /* allocate argv space for child */
  {
    char *buf = (char *)ARGV_START_LOCAL;
    char **bufv = (char **)ARGV_START_LOCAL;
    int len,i;

    argc = 0;
    while (argv[argc] != 0) {
      //printf("argv[%d] = %p\n",argc,argv[argc]);
      argc++;}
    
//    printf("argv: %p, argc: %d\n",argv,argc);

    /* allocate pages */
    {
      Pte *ptes;

      if ((ptes = malloc(sizeof(Pte) * NRARGVPG)) == 0) {
	return -1;
      }
      for (i=0; i < NRARGVPG; i++)
	ptes[i] = PG_U|PG_W|PG_P;
      
      if (sys_self_insert_pte_range(k, ptes, NRARGVPG, ARGV_START_LOCAL) < 0 ||
	  sys_insert_pte_range(k, &vpt[PGNO(ARGV_START_LOCAL)], NRARGVPG, 
			       ARGV_START, k, envid) < 0) {
	fprintf(stderr,"sys_insert_pte failed\n");
	for (i=0; i < NRARGVPG; i++)
	  ptes[i] = 0;
	sys_self_insert_pte_range(k, ptes, NRARGVPG, ARGV_START_LOCAL);
	sys_insert_pte_range(k, ptes, NRARGVPG, ARGV_START, k, envid);
	free(ptes);
	errno = ENOEXEC;
	goto fork_execve0_end_error_closefd;
      }
      free(ptes);
    }

    /* copy the args */
    buf += (argc + 1) * sizeof(char *);
    for (i = 0; i < argc; i++) {
//      fprintf(stderr,"argv[%d] ",i);
      len = strlen(argv[i]) + 1;
//      fprintf(stderr,"length %d\n",len);
      
      if ((int)(buf + len) > ARGV_START_LOCAL + NRARGVPG*NBPG) {
	kprintf("Argv too large truncating\n");
	break;
      }

      bufv[i] = buf - (ARGV_START_LOCAL - ARGV_START);
//      fprintf(stderr,"copied argument %d: %p %s (len %d) to %p bufv: %p\n",i,argv[i],argv[i],len,buf,bufv);
      memcpy(buf, argv[i],len);
      buf += len;
    }
    bufv[argc] = (char *)0;

    
  }
//  printf("DONE ARGV COPY\n");

  /* ----------------------------------------------------------------------------- */

#if 0
  /* COPY ARGUMENTS */
  argc = 0;
  iptr = (int *)ARGV_START_LOCAL;
  argv_p = (char *)(ARGV_START_LOCAL + NBPG);
  while(*argv != (char *)0) {
    strcpy(argv_p,*argv);
    iptr[argc] = strlen(*argv) + 1;
    argv_p += strlen(*argv) + 1;
    /*     fprintf(stderr,"%d len %d \"%s\"  ",argc,cu.u_argv_lengths[argc],*argv); */
    argc++;
    argv++;
  }
  iptr[argc] = -1;
  /*   fprintf(stderr,"ARGC %d\n",argc); */
#endif
#if 0
  argc = 0;
  argv_p = (char *)&cu.u_argv_space;
  while(*argv != (char *)0) {
    strcpy(argv_p,*argv);
    cu.u_argv_lengths[argc] = strlen(*argv) + 1;
    argv_p += strlen(*argv) + 1;
    /*     fprintf(stderr,"%d len %d \"%s\"  ",argc,cu.u_argv_lengths[argc],*argv); */
    argc++;
    argv++;
    if (argc == (UNIX_NR_ARGV - 1)) {
      fprintf(stderr,"argc (%d) is greater than maximum allowed (%d), truncating.\n",
	     argc,UNIX_NR_ARGV - 1);
      break;
    }
    if ((int)argv_p > (int)&cu.u_argv_space[0] + UNIX_ARGV_SIZE) {
      fprintf(stderr,"too much data in argv (%d) max is %d\n",
	     (int)argv_p - (int)&cu.u_argv_space[0],UNIX_ARGV_SIZE);
      break;
    }
  }
  cu.u_argv_lengths[argc] = -1;
#endif

  /* COPY ENVIRONMENT */
  argc = 0;
  (char * const *)argv_tmp = envptr;
  argv_p = (char *)&cu.u_env_space;
  if (argv_tmp)
  while(*argv_tmp != (char *)0) {
    strcpy(argv_p,*argv_tmp);
    cu.u_env_lengths[argc] = strlen(*argv_tmp) + 1;
    argv_p += strlen(*argv_tmp) + 1;
    /* fprintf(stderr,"%d len %d \"%s\"  ",argc,cu.u_env_lengths[argc],*argv_tmp); */
    argc++;
    argv_tmp++;
    if (argc == (UNIX_NR_ENV - 1)) {
      fprintf(stderr,"envc (%d) is greater than maximum allowed (%d), truncating.\n",
	     argc,UNIX_NR_ENV - 1);
      break;
    }
    if ((int)argv_p > (int)&cu.u_env_space[0] + UNIX_ENV_SIZE) {
      fprintf(stderr,"too much data in envp (%d) max is %d (%s)\n",
	     (int)argv_p - (int)&cu.u_env_space[0],UNIX_ENV_SIZE, __FILE__);
      break;
    }
  }
  cu.u_env_lengths[argc] = -1;
  /* fprintf(stderr,"ENVC %d\n",argc); */

  if (sys_wru (0, envid, &cu) < 0) {
    fprintf (stderr,"sys_wru failed\n");
    errno = ENOEXEC;
    goto fork_execve0_end_error;
  }
  STOPP(misc,step8);

  STOP(misc,execve);
  PRNAME(misc,execve);
  {
    extern void pr_fd_stat(void);
    pr_fd_stat();
  }

  /*fprintf(stderr,"allocating quantum\n");*/
  if (sys_quantum_alloc (k, -1, 0, envid) < 0) {
    fprintf (stderr,"could not alloc quantum\n");
    errno = ENOEXEC;
    goto fork_execve0_end_error;
  }

  if (execonly) {
    ProcessFreeQuanta(__envid);
    sys_env_free (0, __envid);
  }

  return (NewPid);

fork_execve0_end_error_closefd:
  close(fd);
fork_execve0_end_error:
  ProcessFreeQuanta(__envid);
  sys_env_free (k, envid);
err:
  if (extra_argv_space != NULL) free(extra_argv_space);
  return -1;
}
Пример #7
0
/*
 * For a specified manual directory, read, store and sort section subdirs.
 * For each section specified, find and search matching subdirs.
 */
static void
mandir(char **secv, char *path, char *name, int lspec)
{
	DIR	*dp;
	char	**dirv;
	char	**dv, **pdv;
	int	len, dslen;

	if ((dp = opendir(path)) == NULL)
		return;

	if (lspec)
		DPRINTF("-- Searching mandir: %s\n", path);

	sortdir(dp, &dirv);

	/* Search in the order specified by MANSECTS */
	for (; *secv; secv++) {
		len = strlen(*secv);
		for (dv = dirv; *dv; dv++) {
			dslen = strlen(*dv + 3);
			if (dslen > len)
				len = dslen;
			if (**secv == '\\') {
				if (strcmp(*secv + 1, *dv + 3) != 0)
					continue;
			} else if (strncasecmp(*secv, *dv + 3, len) != 0) {
				if (!all &&
				    (newsection = map_section(*secv, path))
				    == NULL) {
					continue;
				}
				if (newsection == NULL)
					newsection = "";
				if (strncmp(newsection, *dv + 3, len) != 0) {
					continue;
				}
			}

			if (searchdir(path, *dv, name) == 0)
				continue;

			if (!all) {
				pdv = dirv;
				while (*pdv) {
					free(*pdv);
					pdv++;
				}
				(void) closedir(dp);
				free(dirv);
				return;
			}

			if (all && **dv == 'm' && *(dv + 1) &&
			    strcmp(*(dv + 1) + 3, *dv + 3) == 0)
					dv++;
		}
	}
	pdv = dirv;
	while (*pdv != NULL) {
		free(*pdv);
		pdv++;
	}
	free(dirv);
	(void) closedir(dp);
}