コード例 #1
0
ファイル: signal.c プロジェクト: newtonsjr/source-
/*===========================================================================*
 *			       do_sigaction				     *
 *===========================================================================*/
PUBLIC int do_sigaction()
{
  int r;
  struct sigaction svec;
  struct sigaction *svp;

  if (sig_nr == SIGKILL) return(OK);
  if (sig_nr < 1 || sig_nr > _NSIG) return (EINVAL);
  svp = &mp->mp_sigact[sig_nr];
  if ((struct sigaction *) sig_osa != (struct sigaction *) NULL) {
	r = sys_copy(MM_PROC_NR,D, (phys_bytes) svp,
		who, D, (phys_bytes) sig_osa, (phys_bytes) sizeof(svec));
	if (r != OK) return(r);
  }

  if ((struct sigaction *) sig_nsa == (struct sigaction *) NULL) return(OK);

  /* Read in the sigaction structure. */
  r = sys_copy(who, D, (phys_bytes) sig_nsa,
		MM_PROC_NR, D, (phys_bytes) &svec, (phys_bytes) sizeof(svec));
  if (r != OK) return(r);

  if (svec.sa_handler == SIG_IGN) {
	sigaddset(&mp->mp_ignore, sig_nr);
	sigdelset(&mp->mp_sigpending, sig_nr);
	sigdelset(&mp->mp_catch, sig_nr);
  } else {
	sigdelset(&mp->mp_ignore, sig_nr);
	if (svec.sa_handler == SIG_DFL)
		sigdelset(&mp->mp_catch, sig_nr);
	else
		sigaddset(&mp->mp_catch, sig_nr);
  }
  mp->mp_sigact[sig_nr].sa_handler = svec.sa_handler;
  sigdelset(&svec.sa_mask, SIGKILL);
  mp->mp_sigact[sig_nr].sa_mask = svec.sa_mask;
  mp->mp_sigact[sig_nr].sa_flags = svec.sa_flags;
  mp->mp_sigreturn = (vir_bytes) sig_ret;
  return(OK);
}
コード例 #2
0
ファイル: exec.c プロジェクト: astrotycoon/source-
/*===========================================================================*
 *				do_exec					     *
 *===========================================================================*/
PUBLIC int do_exec()
{
    /* Perform the execve(name, argv, envp) call.  The user library builds a
     * complete stack image, including pointers, args, environ, etc.  The stack
     * is copied to a buffer inside MM, and then to the new core image.
     */

    register struct mproc *rmp;
    struct mproc *sh_mp;
    int m, r, fd, ft, sn;
    static char mbuf[ARG_MAX];	/* buffer for stack and zeroes */
    static char name_buf[PATH_MAX]; /* the name of the file to exec */
    char *new_sp, *basename;
    vir_bytes src, dst, text_bytes, data_bytes, bss_bytes, stk_bytes, vsp;
    phys_bytes tot_bytes;		/* total space for program, including gap */
    long sym_bytes;
    vir_clicks sc;
    struct stat s_buf;
    vir_bytes pc;

    /* Do some validity checks. */
    rmp = mp;
    stk_bytes = (vir_bytes) stack_bytes;
    if (stk_bytes > ARG_MAX) return(ENOMEM);	/* stack too big */
    if (exec_len <= 0 || exec_len > PATH_MAX) return(EINVAL);

    /* Get the exec file name and see if the file is executable. */
    src = (vir_bytes) exec_name;
    dst = (vir_bytes) name_buf;
    r = sys_copy(who, D, (phys_bytes) src,
                 MM_PROC_NR, D, (phys_bytes) dst, (phys_bytes) exec_len);
    if (r != OK) return(r);	/* file name not in user data segment */
    tell_fs(CHDIR, who, FALSE, 0);	/* switch to the user's FS environ. */
    fd = allowed(name_buf, &s_buf, X_BIT);	/* is file executable? */
    if (fd < 0) return(fd);	/* file was not executable */

    /* Read the file header and extract the segment sizes. */
    sc = (stk_bytes + CLICK_SIZE - 1) >> CLICK_SHIFT;
    m = read_header(fd, &ft, &text_bytes, &data_bytes, &bss_bytes,
                    &tot_bytes, &sym_bytes, sc, &pc);
    if (m < 0) {
        close(fd);		/* something wrong with header */
        return(ENOEXEC);
    }

    /* Fetch the stack from the user before destroying the old core image. */
    src = (vir_bytes) stack_ptr;
    dst = (vir_bytes) mbuf;
    r = sys_copy(who, D, (phys_bytes) src,
                 MM_PROC_NR, D, (phys_bytes) dst, (phys_bytes)stk_bytes);
    if (r != OK) {
        close(fd);		/* can't fetch stack (e.g. bad virtual addr) */
        return(EACCES);
    }

    /* Can the process' text be shared with that of one already running? */
    sh_mp = find_share(rmp, s_buf.st_ino, s_buf.st_dev, s_buf.st_ctime);

    /* Allocate new memory and release old memory.  Fix map and tell kernel. */
    r = new_mem(sh_mp, text_bytes, data_bytes, bss_bytes, stk_bytes, tot_bytes);
    if (r != OK) {
        close(fd);		/* insufficient core or program too big */
        return(r);
    }

    /* Save file identification to allow it to be shared. */
    rmp->mp_ino = s_buf.st_ino;
    rmp->mp_dev = s_buf.st_dev;
    rmp->mp_ctime = s_buf.st_ctime;

    /* Patch up stack and copy it from MM to new core image. */
    vsp = (vir_bytes) rmp->mp_seg[S].mem_vir << CLICK_SHIFT;
    vsp += (vir_bytes) rmp->mp_seg[S].mem_len << CLICK_SHIFT;
    vsp -= stk_bytes;
    patch_ptr(mbuf, vsp);
    src = (vir_bytes) mbuf;
    r = sys_copy(MM_PROC_NR, D, (phys_bytes) src,
                 who, D, (phys_bytes) vsp, (phys_bytes)stk_bytes);
    if (r != OK) panic("do_exec stack copy err", NO_NUM);

    /* Read in text and data segments. */
    if (sh_mp != NULL) {
        lseek(fd, (off_t) text_bytes, SEEK_CUR);  /* shared: skip text */
    } else {
        load_seg(fd, T, text_bytes);
    }
    load_seg(fd, D, data_bytes);

#if (SHADOWING == 1)
    if (lseek(fd, (off_t)sym_bytes, SEEK_CUR) == (off_t) -1) ;	/* error */
    if (relocate(fd, (unsigned char *)mbuf) < 0) 	;		/* error */
    pc += (vir_bytes) rp->mp_seg[T].mem_vir << CLICK_SHIFT;
#endif

    close(fd);			/* don't need exec file any more */

    /* Take care of setuid/setgid bits. */
    if ((rmp->mp_flags & TRACED) == 0) { /* suppress if tracing */
        if (s_buf.st_mode & I_SET_UID_BIT) {
            rmp->mp_effuid = s_buf.st_uid;
            tell_fs(SETUID,who, (int)rmp->mp_realuid, (int)rmp->mp_effuid);
        }
        if (s_buf.st_mode & I_SET_GID_BIT) {
            rmp->mp_effgid = s_buf.st_gid;
            tell_fs(SETGID,who, (int)rmp->mp_realgid, (int)rmp->mp_effgid);
        }
    }

    /* Save offset to initial argc (for ps) */
    rmp->mp_procargs = vsp;

    /* Fix 'mproc' fields, tell kernel that exec is done,  reset caught sigs. */
    for (sn = 1; sn <= _NSIG; sn++) {
        if (sigismember(&rmp->mp_catch, sn)) {
            sigdelset(&rmp->mp_catch, sn);
            rmp->mp_sigact[sn].sa_handler = SIG_DFL;
            sigemptyset(&rmp->mp_sigact[sn].sa_mask);
        }
    }

    rmp->mp_flags &= ~SEPARATE;	/* turn off SEPARATE bit */
    rmp->mp_flags |= ft;		/* turn it on for separate I & D files */
    new_sp = (char *) vsp;

    tell_fs(EXEC, who, 0, 0);	/* allow FS to handle FD_CLOEXEC files */

    /* System will save command line for debugging, ps(1) output, etc. */
    basename = strrchr(name_buf, '/');
    if (basename == NULL) basename = name_buf;
    else basename++;
    sys_exec(who, new_sp, rmp->mp_flags & TRACED, basename, pc);
    return(OK);
}
コード例 #3
0
int semaphore_entry(void)
{
/* para evitar que la función modifique los valores del mensaje recibido, 
 * creamos variables locales de manera de evitar tener que acceder 
 * al mensaje para armar la respuesta, es más ineficiente, pero...
 */
	int return_val;

	sem_t sema;
	sem_t *semaux;
	int pshared, oflags, permission, initial, value_now, argc, phsared;
	char name[MAX_NAME];



#ifdef DEBUG
/*
int i;
char *m1;*/
printf("en el semaphore.c\n");/*
for (i = 0; i < 100; i++)
{
	if ((m1 = malloc(128)) == NULL)
	{
		printf("FALLO MALLOC en la iteracion %d\n", i);
		break;
	}
	strcpy(m1, "malloc\n");
	printf("i = %d m1 = %d m1 = %s\n", i, (int)m1, m1);
}*/
#endif
	


	sema = mensaje_semaforo;
	oflags = mensaje_oflag;
	permission = mensaje_permisos;
	initial = mensaje_valInicial;
	value_now = mensaje_valActual;
	argc = mensaje_cantArg;
	pshared = mensaje_pshared;

	sys_copy (who, D, (phys_bytes) mensaje_nombre, FS_PROC_NR, D,  (phys_bytes) name,  (phys_bytes) MAX_NAME);
	name[MAX_NAME - 1] = '\0';

	switch(mensaje_funcion)
	{
		case SEM_OPEN: if (argc == 4)
			       {
#ifdef DEBUG
printf("SEMOPEN name: %s, oflags: %d, permission: %d, initial: %d\n", name, oflags, permission, initial);
#endif 
					semaux = sem_open(name, oflags, permission,
								   initial);
			       }
			       else
			       {
#ifdef DEBUG
printf("SEMOPEN name: %s, oflags: %d\n", name, oflags);
#endif 
					semaux = sem_open(name, oflags);
			       }
			       answer(*semaux,0,0,1);
			       break;

		case SEM_CLOSE: 
				return_val = sem_close(&sema);
				answer(return_val,sema,0,2);
				break;

		case SEM_INIT:  return_val = sem_init(&sema, pshared, initial);
				answer(return_val,sema,0,2);
				break;

		case SEM_WAIT:  return_val = sem_wait(&sema);
				answer(return_val,sema,0,2);
				break;

		case SEM_POST:  return_val = sem_post(&sema);
				answer(return_val,sema,0,2);
				break;

		case SEM_ULINK: return_val = sem_unlink(name);
				answer(return_val,0,0,1);
				break;

		case SEM_GETVAL: return_val = sem_getvalue(&sema, &value_now);
				 answer(return_val,sema,value_now,3);
				 break;

		case SEM_TRYWAIT: return_val = sem_trywait(&sema);
				  answer(return_val,sema,0,2);
				  break;
 
		case SEM_DESTROY: return_val = sem_destroy(&sema);
				  answer(return_val,sema,0,2);
				  break;

		case SEM_TIMEDWAIT: return_val = no_func();
				    answer(return_val,0,0,1);
				    break;
	}
#ifdef DEBUG
printf("fin de semaphore.c\n");
#endif
	if (return_val != 0)
		return (errno);		
	return(OK);
}
コード例 #4
0
ファイル: forkexit.c プロジェクト: khorben/DeforaOS
/*===========================================================================*
 *				do_fork					     *
 *===========================================================================*/
PUBLIC int do_fork()
{
/* The process pointed to by 'mp' has forked.  Create a child process. */

  register struct mproc *rmp;	/* pointer to parent */
  register struct mproc *rmc;	/* pointer to child */
  int i, child_nr, t;
  phys_clicks prog_clicks, child_base;
  phys_bytes prog_bytes, parent_abs, child_abs;	/* Intel only */

 /* If tables might fill up during FORK, don't even start since recovery half
  * way through is such a nuisance.
  */
  rmp = mp;
  if (procs_in_use == NR_PROCS) return(EAGAIN);
  if (procs_in_use >= NR_PROCS-LAST_FEW && rmp->mp_effuid != 0)return(EAGAIN);

  /* Determine how much memory to allocate.  Only the data and stack need to
   * be copied, because the text segment is either shared or of zero length.
   */
  prog_clicks = (phys_clicks) rmp->mp_seg[S].mem_len;
  prog_clicks += (rmp->mp_seg[S].mem_vir - rmp->mp_seg[D].mem_vir);
  prog_bytes = (phys_bytes) prog_clicks << CLICK_SHIFT;
  if ( (child_base = alloc_mem(prog_clicks)) == NO_MEM) return(ENOMEM);

  /* Create a copy of the parent's core image for the child. */
  child_abs = (phys_bytes) child_base << CLICK_SHIFT;
  parent_abs = (phys_bytes) rmp->mp_seg[D].mem_phys << CLICK_SHIFT;
  i = sys_copy(ABS, 0, parent_abs, ABS, 0, child_abs, prog_bytes);
  if (i < 0) panic("do_fork can't copy", i);

  /* Find a slot in 'mproc' for the child process.  A slot must exist. */
  for (rmc = &mproc[0]; rmc < &mproc[NR_PROCS]; rmc++)
	if ( (rmc->mp_flags & IN_USE) == 0) break;

  /* Set up the child and its memory map; copy its 'mproc' slot from parent. */
  child_nr = (int)(rmc - mproc);	/* slot number of the child */
  procs_in_use++;
  *rmc = *rmp;			/* copy parent's process slot to child's */

  rmc->mp_parent = who;			/* record child's parent */
  rmc->mp_flags &= (IN_USE|SEPARATE);	/* inherit only these flags */

  /* A separate I&D child keeps the parents text segment.  The data and stack
   * segments must refer to the new copy.
   */
  if (!(rmc->mp_flags & SEPARATE)) rmc->mp_seg[T].mem_phys = child_base;
  rmc->mp_seg[D].mem_phys = child_base;
  rmc->mp_seg[S].mem_phys = rmc->mp_seg[D].mem_phys + 
			(rmp->mp_seg[S].mem_vir - rmp->mp_seg[D].mem_vir);
  rmc->mp_exitstatus = 0;
  rmc->mp_sigstatus = 0;

  /* Find a free pid for the child and put it in the table. */
  do {
	t = 0;			/* 't' = 0 means pid still free */
	next_pid = (next_pid < 30000 ? next_pid + 1 : INIT_PID + 1);
	for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
		if (rmp->mp_pid == next_pid || rmp->mp_procgrp == next_pid) {
			t = 1;
			break;
		}
	rmc->mp_pid = next_pid;	/* assign pid to child */
  } while (t);

  /* Tell kernel and file system about the (now successful) FORK. */
  sys_fork(who, child_nr, rmc->mp_pid);
  tell_fs(FORK, who, child_nr, rmc->mp_pid);

  /* Report child's memory map to kernel. */
  sys_newmap(child_nr, rmc->mp_seg);

  /* Reply to child to wake it up. */
  setreply(child_nr, 0);
  return(next_pid);		 /* child's pid */
}