Example #1
0
/*===========================================================================*
 *				do_sigprocmask                               *
 *===========================================================================*/
int do_sigprocmask()
{
/* Note that the library interface passes the actual mask in sigmask_set,
 * not a pointer to the mask, in order to save a copy.  Similarly,
 * the old mask is placed in the return message which the library
 * interface copies (if requested) to the user specified address.
 *
 * The library interface must set SIG_INQUIRE if the 'act' argument
 * is NULL.
 *
 * KILL and STOP can't be masked.
 */

  int i;

  mp->mp_reply.reply_mask = (long) mp->mp_sigmask;

  switch (m_in.sig_how) {
      case SIG_BLOCK:
	sigdelset((sigset_t *)&m_in.sig_set, SIGKILL);
	sigdelset((sigset_t *)&m_in.sig_set, SIGSTOP);
	for (i = 1; i < _NSIG; i++) {
		if (sigismember((sigset_t *)&m_in.sig_set, i))
			sigaddset(&mp->mp_sigmask, i);
	}
	break;

      case SIG_UNBLOCK:
	for (i = 1; i < _NSIG; i++) {
		if (sigismember((sigset_t *)&m_in.sig_set, i))
			sigdelset(&mp->mp_sigmask, i);
	}
	check_pending(mp);
	break;

      case SIG_SETMASK:
	sigdelset((sigset_t *) &m_in.sig_set, SIGKILL);
	sigdelset((sigset_t *) &m_in.sig_set, SIGSTOP);
	mp->mp_sigmask = (sigset_t) m_in.sig_set;
	check_pending(mp);
	break;

      case SIG_INQUIRE:
	break;

      default:
	return(EINVAL);
	break;
  }
  return OK;
}
Example #2
0
/*===========================================================================*
 *				do_sigsuspend                                *
 *===========================================================================*/
PUBLIC int do_sigsuspend()
{
  mp->mp_sigmask2 = mp->mp_sigmask;	/* save the old mask */
  mp->mp_sigmask = (sigset_t) m_in.sig_set;
  sigdelset(&mp->mp_sigmask, SIGKILL);
  mp->mp_flags |= SIGSUSPENDED;
  check_pending(mp);
  return(SUSPEND);
}
Example #3
0
/*===========================================================================*
 *				do_sigsuspend                                *
 *===========================================================================*/
int do_sigsuspend(void)
{
  assert(!(mp->mp_flags & (PROC_STOPPED | VFS_CALL | UNPAUSED)));

  mp->mp_sigmask2 = mp->mp_sigmask;	/* save the old mask */
  mp->mp_sigmask = m_in.m_lc_pm_sigset.set;
  sigdelset(&mp->mp_sigmask, SIGKILL);
  sigdelset(&mp->mp_sigmask, SIGSTOP);
  mp->mp_flags |= SIGSUSPENDED;
  check_pending(mp);
  return(SUSPEND);
}
Example #4
0
/**
 * Handles an incoming REGSITER message from a client.
 */
void handle_register(struct pr_group_list_t *group, int hostidx,
                     const unsigned char *message, unsigned meslen,
                     uint32_t src)
{
    const struct register_h *reg;
    const unsigned char *enckey;
    struct pr_destinfo_t *dest;
    int dupmsg;

    reg = (const struct register_h *)message;
    enckey = (const unsigned char *)reg + sizeof(struct register_h);

    if (group->destcount == MAXPROXYDEST) {
        glog1(group, "Rejecting REGISTER from %08X: max destinations exceeded",
                     ntohl(src));
        send_downstream_abort(group, src, "Max destinations exceeded", 0);
        return;
    }
    if ((meslen < (reg->hlen * 4U)) || ((reg->hlen * 4U) <
            sizeof(struct register_h) + ntohs(reg->keyinfo_len))) {
        glog1(group, "Rejecting REGISTER from %08X: invalid message size",
                     ntohl(src));
        send_downstream_abort(group, src, "Invalid message size", 0);
        return;
    }

    if (hostidx == -1) {
        hostidx = add_client(src, group);
    }
    dest = &group->destinfo[hostidx];
    dupmsg = (dest->registered == 1);
    dest->registered = 1;
    dest->regtime.tv_sec = ntohl(reg->tstamp_sec);
    dest->regtime.tv_usec = ntohl(reg->tstamp_usec);

    if (dest->state != PR_CLIENT_REGISTERED) {
        if (group->keytype != KEY_NONE) {
            if (!handle_register_keys(reg, enckey, group, hostidx, src)) {
                return;
            }
        }
        if (!group->client_auth || dest->pubkey.key) {
            dest->state = PR_CLIENT_REGISTERED;
        }
    }

    glog2(group, "Received REGISTER%s from %s", dupmsg ? "+" : "", dest->name);

    if (dest->state == PR_CLIENT_REGISTERED) {
        check_pending(group, hostidx, message);
    }
}
Example #5
0
/*===========================================================================*
 *				do_sigreturn				     *
 *===========================================================================*/
PUBLIC int do_sigreturn()
{
/* A user signal handler is done.  Restore context and check for
 * pending unblocked signals.
 */

  int r;

  mp->mp_sigmask = (sigset_t) m_in.sig_set;
  sigdelset(&mp->mp_sigmask, SIGKILL);

  r = sys_sigreturn(who, (struct sigmsg *) m_in.sig_context);
  check_pending(mp);
  return(r);
}
Example #6
0
/*===========================================================================*
 *				do_sigreturn				     *
 *===========================================================================*/
int do_sigreturn(void)
{
/* A user signal handler is done.  Restore context and check for
 * pending unblocked signals.
 */
  int r;

  assert(!(mp->mp_flags & (PROC_STOPPED | VFS_CALL | UNPAUSED)));

  mp->mp_sigmask = m_in.m_lc_pm_sigset.set;
  sigdelset(&mp->mp_sigmask, SIGKILL);
  sigdelset(&mp->mp_sigmask, SIGSTOP);

  r = sys_sigreturn(who_e, (struct sigmsg *)m_in.m_lc_pm_sigset.ctx);
  check_pending(mp);
  return(r);
}
Example #7
0
/**
 * Handles an incoming FILEINFO_ACK message from a client
 */
void handle_fileinfo_ack(struct pr_group_list_t *group, int hostidx,
                         const unsigned char *message, unsigned meslen)
{
    const struct fileinfoack_h *fileinfoack;
    struct pr_destinfo_t *dest;

    fileinfoack = (const struct fileinfoack_h *)message;
    dest = &group->destinfo[hostidx];

    if ((meslen < (fileinfoack->hlen * 4U)) ||
            ((fileinfoack->hlen * 4U) < sizeof(struct fileinfoack_h))) {
        log1(group->group_id, group->group_inst, ntohs(fileinfoack->file_id),
                "Rejecting FILEINFO_ACK from %s: invalid message size",
                dest->name);
        return;
    }

    log2(group->group_id, group->group_inst, ntohs(fileinfoack->file_id),
            "Received FILEINFO_ACK from %s", dest->name);
    check_pending(group, hostidx, message);
}
Example #8
0
/*===========================================================================*
 *				do_trace  				     *
 *===========================================================================*/
PUBLIC int do_trace()
{
  register struct mproc *child;
  struct ptrace_range pr;
  int i, r, seg, req;

  req = m_in.request;

  /* The T_OK call is made by the child fork of the debugger before it execs
   * the process to be traced. The T_ATTACH call is made by the debugger itself
   * to attach to an existing process.
   */
  switch (req) {
  case T_OK:		/* enable tracing by parent for this proc */
	if (mp->mp_tracer != NO_TRACER) return(EBUSY);

	mp->mp_tracer = mp->mp_parent;
	mp->mp_reply.reply_trace = 0;
	return(OK);

  case T_ATTACH:	/* attach to an existing process */
	if ((child = find_proc(m_in.pid)) == NULL) return(ESRCH);
	if (child->mp_flags & EXITING) return(ESRCH);

	/* For non-root processes, user and group ID must match. */
	if (mp->mp_effuid != SUPER_USER &&
		(mp->mp_effuid != child->mp_effuid ||
		 mp->mp_effgid != child->mp_effgid ||
		 child->mp_effuid != child->mp_realuid ||
		 child->mp_effgid != child->mp_realgid)) return(EPERM);

	/* Only root may trace system servers. */
	if (mp->mp_effuid != SUPER_USER && (child->mp_flags & PRIV_PROC))
		return(EPERM);

	/* System servers may not trace anyone. They can use sys_trace(). */
	if (mp->mp_flags & PRIV_PROC) return(EPERM);

	/* Can't trace self, PM or VM. */
	if (child == mp || child->mp_endpoint == PM_PROC_NR ||
		child->mp_endpoint == VM_PROC_NR) return(EPERM);

	/* Can't trace a process that is already being traced. */
	if (child->mp_tracer != NO_TRACER) return(EBUSY);

	child->mp_tracer = who_p;
	child->mp_trace_flags = TO_NOEXEC;

	sig_proc(child, SIGSTOP, TRUE /*trace*/, FALSE /* ksig */);

	mp->mp_reply.reply_trace = 0;
	return(OK);

  case T_STOP:		/* stop the process */
	/* This call is not exposed to user programs, because its effect can be
	 * achieved better by sending the traced process a signal with kill(2).
	 */
	return(EINVAL);

  case T_READB_INS:	/* special hack for reading text segments */
	if (mp->mp_effuid != SUPER_USER) return(EPERM);
	if ((child = find_proc(m_in.pid)) == NULL) return(ESRCH);
	if (child->mp_flags & EXITING) return(ESRCH);

	r = sys_trace(req, child->mp_endpoint, m_in.PMTRACE_ADDR, &m_in.data);
	if (r != OK) return(r);

	mp->mp_reply.reply_trace = m_in.data;
	return(OK);

  case T_WRITEB_INS:	/* special hack for patching text segments */
	if (mp->mp_effuid != SUPER_USER) return(EPERM);
	if ((child = find_proc(m_in.pid)) == NULL) return(ESRCH);
	if (child->mp_flags & EXITING) return(ESRCH);

#if 0
	/* Should check for shared text */

	/* Make sure the text segment is not used as a source for shared
	 * text.
	 */
	child->mp_ino = 0;
	child->mp_dev = 0;
	child->mp_ctime = 0;
#endif

	r = sys_trace(req, child->mp_endpoint, m_in.PMTRACE_ADDR, &m_in.data);
	if (r != OK) return(r);

	mp->mp_reply.reply_trace = m_in.data;
	return(OK);
  }

  /* All the other calls are made by the tracing process to control execution
   * of the child. For all these calls, the child must be stopped.
   */
  if ((child = find_proc(m_in.pid)) == NULL) return(ESRCH);
  if (child->mp_flags & EXITING) return(ESRCH);
  if (child->mp_tracer != who_p) return(ESRCH);
  if (!(child->mp_flags & STOPPED)) return(EBUSY);

  switch (req) {
  case T_EXIT:		/* exit */
	child->mp_flags |= TRACE_EXIT;

	/* Defer the exit if the traced process has an VFS call pending. */
	if (child->mp_flags & VFS_CALL)
		child->mp_exitstatus = (int) m_in.data;	/* save for later */
	else
		exit_proc(child, (int) m_in.data, FALSE /*dump_core*/);

	/* Do not reply to the caller until VFS has processed the exit
	 * request.
	 */
	return(SUSPEND);

  case T_SETOPT:	/* set trace options */
	child->mp_trace_flags = m_in.data;

	mp->mp_reply.reply_trace = 0;
	return(OK);

  case T_GETRANGE:
  case T_SETRANGE:	/* get/set range of values */
	r = sys_datacopy(who_e, (vir_bytes) m_in.PMTRACE_ADDR,
			SELF, (vir_bytes) &pr, (phys_bytes) sizeof(pr));
	if (r != OK) return(r);

	if (pr.pr_space != TS_INS && pr.pr_space != TS_DATA) return(EINVAL);
	if (pr.pr_size == 0 || pr.pr_size > LONG_MAX) return(EINVAL);

	seg = (pr.pr_space == TS_INS) ? T : D;
	if (req == T_GETRANGE)
		r = sys_vircopy(child->mp_endpoint, seg, (vir_bytes) pr.pr_addr,
			who_e, D, (vir_bytes) pr.pr_ptr,
			(phys_bytes) pr.pr_size);
	else
		r = sys_vircopy(who_e, D, (vir_bytes) pr.pr_ptr,
			child->mp_endpoint, seg, (vir_bytes) pr.pr_addr,
			(phys_bytes) pr.pr_size);

	if (r != OK) return(r);

	mp->mp_reply.reply_trace = 0;
	return(OK);

  case T_DETACH:	/* detach from traced process */
	if (m_in.data < 0 || m_in.data >= _NSIG) return(EINVAL);

	child->mp_tracer = NO_TRACER;

	/* Let all tracer-pending signals through the filter. */
	for (i = 1; i < _NSIG; i++) {
		if (sigismember(&child->mp_sigtrace, i)) {
			(void) sigdelset(&child->mp_sigtrace, i);
			check_sig(child->mp_pid, i, FALSE /* ksig */);
		}
	}

	if (m_in.data > 0) {		/* issue signal */
		sig_proc(child, (int) m_in.data, TRUE /*trace*/, 
			FALSE /* ksig */);
	}

	/* Resume the child as if nothing ever happened. */ 
	child->mp_flags &= ~STOPPED;
	child->mp_trace_flags = 0;

	check_pending(child);

	break;

  case T_RESUME: 
  case T_STEP:
  case T_SYSCALL:	/* resume execution */
	if (m_in.data < 0 || m_in.data >= _NSIG) return(EINVAL);

	if (m_in.data > 0) {		/* issue signal */
		sig_proc(child, (int) m_in.data, FALSE /*trace*/,
			FALSE /* ksig */);
	}

	/* If there are any other signals waiting to be delivered,
	 * feign a successful resumption.
	 */
	for (i = 1; i < _NSIG; i++) {
		if (sigismember(&child->mp_sigtrace, i)) {
			mp->mp_reply.reply_trace = 0;
			return(OK);
		}
	}

	child->mp_flags &= ~STOPPED;

	check_pending(child);

	break;
  }
  r = sys_trace(req, child->mp_endpoint, m_in.PMTRACE_ADDR, &m_in.data);
  if (r != OK) return(r);

  mp->mp_reply.reply_trace = m_in.data;
  return(OK);
}
Example #9
0
File: seq_if.c Project: ukaea/epics
/*
 * Put a variable's value to a PV, with timeout.
 */
epicsShareFunc pvStat seq_pvPutTmo(SS_ID ss, CH_ID chId, enum compType compType, double tmo)
{
	PROG	*sp = ss->prog;
	CHAN	*ch = sp->chan + chId;
	pvStat	status;
	unsigned count;
	char	*var = valPtr(ch,ss);	/* ptr to value */
	PVREQ	*req;
	DBCHAN	*dbch = ch->dbch;
	PVMETA	*meta = metaPtr(ch,ss);

	DEBUG("pvPut: pv name=%s, var=%p\n", dbch ? dbch->dbName : "<anonymous>", var);

	/* First handle anonymous PV (safe mode only) */
	if (optTest(sp, OPT_SAFE) && !dbch)
	{
		anonymous_put(ss, ch);
		return pvStatOK;
	}
	if (!dbch)
	{
		errlogSevPrintf(errlogMajor,
			"pvPut(%s): user error (not assigned to a PV)\n",
			ch->varName
		);
		return pvStatERROR;
	}

	/* Check for channel connected */
	status = check_connected(dbch, meta);
	if (status != pvStatOK) return status;

	/* Determine whether to perform synchronous, asynchronous, or
	   plain put ((+a) option was never honored for put, so DEFAULT
	   means fire-and-forget) */
	status = check_pending(pvEventPut, ss, ss->putReq + chId, ch->varName,
		dbch, meta, compType, tmo);
	if (status != pvStatOK)
		return status;

	/* Determine number of elements to put (don't try to put more
	   than db count) */
	count = dbch->dbCount;

	/* Perform the PV put operation (either non-blocking or with a
	   callback routine specified) */
	if (compType == DEFAULT)
	{
		status = pvVarPutNoBlock(
				&dbch->pvid,		/* PV id */
				ch->type->putType,	/* data type */
				count,			/* element count */
				(pvValue *)var);	/* data value */
		if (status != pvStatOK)
		{
			pv_call_failure(dbch, meta, status);
			errlogSevPrintf(errlogFatal, "pvPut(var %s, pv %s): pvVarPutNoBlock() failure: %s\n",
				ch->varName, dbch->dbName, pvVarGetMess(dbch->pvid));
			return status;
		}
	}
	else
	{
		/* Allocate and initialize a pv request */
		req = (PVREQ *)freeListMalloc(sp->pvReqPool);
		req->ss = ss;
		req->ch = ch;

		assert(ss->putReq[chId] == NULL);
		ss->putReq[chId] = req;

		status = pvVarPutCallback(
				&dbch->pvid,		/* PV id */
				ch->type->putType,	/* data type */
				count,			/* element count */
				(pvValue *)var,		/* data value */
				req);			/* user arg */
		if (status != pvStatOK)
		{
			pv_call_failure(dbch, meta, status);
			errlogSevPrintf(errlogFatal, "pvPut(var %s, pv %s): pvVarPutCallback() failure: %s\n",
				ch->varName, dbch->dbName, pvVarGetMess(dbch->pvid));
			ss->putReq[chId] = NULL;	/* cancel the request */
			freeListFree(sp->pvReqPool, req);
			check_connected(dbch, meta);
			return status;
		}

		if (compType == SYNC)			/* wait for completion */
		{
			pvSysFlush(sp->pvSys);
			status = wait_complete(pvEventPut, ss, ss->putReq + chId, dbch, meta, tmo);
			if (status != pvStatOK)
				return status;
		}
	}
	return pvStatOK;
}
Example #10
0
File: seq_if.c Project: ukaea/epics
/*
 * Get value from a channel, with timeout.
 */
epicsShareFunc pvStat seq_pvGetTmo(SS_ID ss, CH_ID chId, enum compType compType, double tmo)
{
	PROG		*sp = ss->prog;
	CHAN		*ch = sp->chan + chId;
	pvStat		status;
	PVREQ		*req;
	DBCHAN		*dbch = ch->dbch;
	PVMETA		*meta = metaPtr(ch,ss);

	/* Anonymous PV and safe mode, just copy from shared buffer.
	   Note that completion is always immediate, so no distinction
	   between SYNC and ASYNC needed. See also pvGetComplete. */
	if (optTest(sp, OPT_SAFE) && !dbch)
	{
		/* Copy regardless of whether dirty flag is set or not */
		ss_read_buffer(ss, ch, FALSE);
		return pvStatOK;
	}
	/* No named PV and traditional mode => user error */
	if (!dbch)
	{
		errlogSevPrintf(errlogMajor,
			"pvGet(%s): user error (not assigned to a PV)\n",
			ch->varName
		);
		return pvStatERROR;
	}

	if (compType == DEFAULT)
	{
		compType = optTest(sp, OPT_ASYNC) ? ASYNC : SYNC;
	}

	status = check_pending(pvEventGet, ss, ss->getReq + chId, ch->varName,
		dbch, meta, compType, tmo);
	if (status != pvStatOK)
		return status;

	/* Allocate and initialize a pv request */
	req = (PVREQ *)freeListMalloc(sp->pvReqPool);
	req->ss = ss;
	req->ch = ch;

	assert(ss->getReq[chId] == NULL);
	ss->getReq[chId] = req;

	/* Perform the PV get operation with a callback routine specified.
	   Requesting more than db channel has available is ok. */
	status = pvVarGetCallback(
			&dbch->pvid,		/* PV id */
			ch->type->getType,	/* request type */
			ch->count,		/* element count */
			req);			/* user arg */
	if (status != pvStatOK)
	{
		pv_call_failure(dbch, meta, status);
		errlogSevPrintf(errlogFatal,
			"pvGet(var %s, pv %s): pvVarGetCallback() failure: %s\n",
			ch->varName, dbch->dbName, pvVarGetMess(dbch->pvid));
		ss->getReq[chId] = NULL;	/* cancel the request */
		freeListFree(sp->pvReqPool, req);
		check_connected(dbch, meta);
		return status;
	}

	/* Synchronous: wait for completion */
	if (compType == SYNC)
	{
		pvSysFlush(sp->pvSys);
		status = wait_complete(pvEventGet, ss, ss->getReq + chId, dbch, meta, tmo);
		if (status != pvStatOK)
			return status;
		if (optTest(sp, OPT_SAFE))
			/* Copy regardless of whether dirty flag is set or not */
			ss_read_buffer(ss, ch, FALSE);
	}

	return pvStatOK;
}
Example #11
0
/*===========================================================================*
 *				process_ksig				     *
 *===========================================================================*/
int process_ksig(endpoint_t proc_nr_e, int signo)
{
  register struct mproc *rmp;
  int proc_nr;
  pid_t proc_id, id;

  if(pm_isokendpt(proc_nr_e, &proc_nr) != OK || proc_nr < 0) {
	printf("PM: process_ksig: %d?? not ok\n", proc_nr_e);
	return EDEADEPT; /* process is gone. */
  }
  rmp = &mproc[proc_nr];
  if ((rmp->mp_flags & (IN_USE | EXITING)) != IN_USE) {
#if 0
	printf("PM: process_ksig: %d?? exiting / not in use\n", proc_nr_e);
#endif
	return EDEADEPT; /* process is gone. */
  }
  proc_id = rmp->mp_pid;
  mp = &mproc[0];			/* pretend signals are from PM */
  mp->mp_procgrp = rmp->mp_procgrp;	/* get process group right */

  /* For SIGVTALRM and SIGPROF, see if we need to restart a
   * virtual timer. For SIGINT, SIGWINCH and SIGQUIT, use proc_id 0
   * to indicate a broadcast to the recipient's process group.  For
   * SIGKILL, use proc_id -1 to indicate a systemwide broadcast.
   */
  switch (signo) {
      case SIGINT:
      case SIGQUIT:
      case SIGWINCH:
  	id = 0; break;	/* broadcast to process group */
      case SIGVTALRM:
      case SIGPROF:
      	check_vtimer(proc_nr, signo);
      	/* fall-through */
      default:
  	id = proc_id;
  	break;
  }
  check_sig(id, signo, TRUE /* ksig */);

  /* If SIGSNDELAY is set, an earlier sys_stop() failed because the process was
   * still sending, and the kernel hereby tells us that the process is now done
   * with that. We can now try to resume what we planned to do in the first
   * place: set up a signal handler. However, the process's message may have
   * been a call to PM, in which case the process may have changed any of its
   * signal settings. The process may also have forked, exited etcetera.
   */
  if (signo == SIGSNDELAY && (rmp->mp_flags & DELAY_CALL)) {
	rmp->mp_flags &= ~DELAY_CALL;

	/*
	 * If the VFS_CALL flag is still set we have a process which is stopped
	 * and we only need to wait for a reply from VFS. We are going to check
	 * the pending signal then
	 */
	if (rmp->mp_flags & VFS_CALL)
		return OK;
	if (rmp->mp_flags & PM_SIG_PENDING)
		panic("process_ksig: bad process state");

	/* Process as many normal signals as possible. */
	check_pending(rmp);

	if (rmp->mp_flags & DELAY_CALL)
		panic("process_ksig: multiple delay calls?");
  }
  
  /* See if the process is still alive */
  if ((mproc[proc_nr].mp_flags & (IN_USE | EXITING)) == IN_USE)  {
      return OK; /* signal has been delivered */
  }
  else {
      return EDEADEPT; /* process is gone */
  }
}
Example #12
0
int main(int argc, char *argv[]) {
	int i, t = 0;
	uint32 done = 0;
	char ch, benchmark = 0, noinput = 0;
	hd_engine *engine;
	circle_object obj[6];

	for (i = 1; i < argc; i++) {
		if (*argv[i] == '-') {
			if (strcmp("benchmark", argv[i]+1) == 0)
				benchmark = 1;
			if (strcmp("noinput", argv[i]+1) == 0)
				noinput = 1;
		}
	}

	noinput = noinput && benchmark;

#ifndef IPOD
	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
		fprintf(stderr,"Unable to init SDL: %s\n",SDL_GetError());
		exit(1);
	}
	atexit(SDL_Quit);

	screen = SDL_SetVideoMode(WIDTH, HEIGHT,16,SDL_SWSURFACE);
	if (screen == NULL) {
		fprintf(stderr,"Unable to init SDL video: %s\n",SDL_GetError());
		exit(1);
	}
	engine = HD_Initialize (WIDTH, HEIGHT, 16, screen->pixels, update);
#define IMGPREFIX ""
#else

	HD_LCD_Init();
	HD_LCD_GetInfo (0, &WIDTH, &HEIGHT, 0);
	screen = xmalloc (WIDTH * HEIGHT * 2);
	engine = HD_Initialize (WIDTH, HEIGHT, 16, screen, update);
#define IMGPREFIX ""
#endif

	obj[4].object    = HD_PNG_Create (IMGPREFIX "bg.png");
	obj[4].object->x = 0;
	obj[4].object->y = 0;
	obj[4].object->w = WIDTH;
	obj[4].object->h = HEIGHT;

	obj[0].object    = HD_PNG_Create (IMGPREFIX "photos.png");
	obj[0].object->x = 0;
	obj[0].object->y = 0;
	obj[0].object->w = 75 * WIDTH / 220;
	obj[0].object->h = 150 * WIDTH / 220;

	obj[1].object    = HD_PNG_Create (IMGPREFIX "music.png");
	obj[1].object->x = 0;
	obj[1].object->y = 0;
	obj[1].object->w = 75 * WIDTH / 220;
	obj[1].object->h = 150 * WIDTH / 220;

	obj[2].object    = HD_PNG_Create (IMGPREFIX "dvd.png");
	obj[2].object->x = 0;
	obj[2].object->y = 0;
	obj[2].object->w = 75 * WIDTH / 220;
	obj[2].object->h = 150 * WIDTH / 220;

	obj[3].object    = HD_PNG_Create (IMGPREFIX "movies.png");
	obj[3].object->x = 0;
	obj[3].object->y = 0;
	obj[3].object->w = 75 * WIDTH / 220;
	obj[3].object->h = 150 * WIDTH / 220;

	obj[5].object    = HD_Canvas_Create (100, 100);
	obj[5].object->x = 100;
	obj[5].object->y = 100;

	HD_Register(engine,obj[4].object);
	HD_Register(engine,obj[0].object);
	HD_Register(engine,obj[1].object);
	HD_Register(engine,obj[2].object);
	HD_Register(engine,obj[3].object);
	if (obj[5].object) HD_Register(engine,obj[5].object);

	obj[0].position = 0;
	obj[1].position = 1024;
	obj[2].position = 2048;
	obj[3].position = 3072;

	object_topwid = ((50 * WIDTH / 220) << 16) / obj[0].object->w;
	object_bottomwid = ((70 * WIDTH / 220) << 16) / obj[0].object->w;

	if (benchmark) {
		HD_AnimateCircle(obj[0].object, 80 * WIDTH / 220, 50 * HEIGHT / 176, 50 * HEIGHT / 176,
				 object_topwid, object_bottomwid, obj[0].position, 4096, -100);
		HD_AnimateCircle(obj[1].object, 80 * WIDTH / 220, 50 * HEIGHT / 176, 50 * HEIGHT / 176,
				 object_topwid, object_bottomwid, obj[1].position, 4096, -100);
		HD_AnimateCircle(obj[2].object, 80 * WIDTH / 220, 50 * HEIGHT / 176, 50 * HEIGHT / 176,
				 object_topwid, object_bottomwid, obj[2].position, 4096, -100);
		HD_AnimateCircle(obj[3].object, 80 * WIDTH / 220, 50 * HEIGHT / 176, 50 * HEIGHT / 176,
				 object_topwid, object_bottomwid, obj[3].position, 4096, -100);
	}
	else {
		circle_rotate(&obj[0], 1);
		circle_rotate(&obj[1], 1);
		circle_rotate(&obj[2], 1);
		circle_rotate(&obj[3], 1);
	}

#ifdef IPOD
	uint32 srtc = *(volatile uint32 *)0x60005010;

	set_keypress();
	fd_set rd;
	struct timeval tv;
	int n;
#endif

	while(!done) {
		if (!benchmark && (ch = check_pending()) &&
				!obj[0].object->animating) {
			circle_rotate(&obj[0], ch);
			circle_rotate(&obj[1], ch);
			circle_rotate(&obj[2], ch);
			circle_rotate(&obj[3], ch);
		}
#ifndef IPOD
		SDL_Event event;

		while(SDL_PollEvent(&event)) {
			switch(event.type) {
			case SDL_KEYDOWN:
				switch(event.key.keysym.sym) {
				case SDLK_SPACE:
				case SDLK_BACKSPACE:
				case SDLK_DOWN:
				case SDLK_UP:
					break;
				case SDLK_RIGHT:
					if (benchmark) break;
					if (obj[0].object->animating) {
						add_pending(1);
						break;
					}
					circle_rotate(&obj[0], 1);
					circle_rotate(&obj[1], 1);
					circle_rotate(&obj[2], 1);
					circle_rotate(&obj[3], 1);
					break;
				case SDLK_LEFT:
					if (benchmark) break;
					if (obj[0].object->animating) {
						add_pending(-1);
						break;
					}
					circle_rotate(&obj[0], -1);
					circle_rotate(&obj[1], -1);
					circle_rotate(&obj[2], -1);
					circle_rotate(&obj[3], -1);
					break;
				case SDLK_ESCAPE:
					done = 1;
					break;
				default:
					break;
				}
				break;
			case SDL_QUIT:
				return(0);
				break;
			default:
				break;
			}
		}

		SDL_Delay (30);
#else
#define SCROLL_MOD_NUM	24 // 100/25 - 1
#define SCROLL_MOD(n) \
  ({ \
    static int sofar = 0; \
    int use = 0; \
    if (++sofar >= n) { \
      sofar -= n; \
      use = 1; \
    } \
    (use == 1); \
  })
		if (!noinput) {
			FD_ZERO(&rd);
			FD_SET(0, &rd);
			
			tv.tv_sec = 0;
			tv.tv_usec = 100;
			
			n = select(0+1, &rd, NULL, NULL, &tv);
			if (FD_ISSET(0, &rd) && (n > 0)) {
				read(0, &ch, 1);
				switch(ch) {
				case 'm':
					done = 1;
					break;
				case 'r':
					if (SCROLL_MOD(SCROLL_MOD_NUM)) {
					if (benchmark) break;
					if (obj[0].object->animating) {
						add_pending(1);
						break;
					}
					circle_rotate(&obj[0], 1);
					circle_rotate(&obj[1], 1);
					circle_rotate(&obj[2], 1);
					circle_rotate(&obj[3], 1);
					}
					break;
				case 'l':
					if (SCROLL_MOD(SCROLL_MOD_NUM)) {
					if (benchmark) break;
					if (obj[0].object->animating) {
						add_pending(-1);
						break;
					}
					circle_rotate(&obj[0], -1);
					circle_rotate(&obj[1], -1);
					circle_rotate(&obj[2], -1);
					circle_rotate(&obj[3], -1);
					}
					break;
				case 'w':
				case 'f':
				case 'd':
				default:
					break;
				}
			}
		}
#endif
		t++;
		if (benchmark && t > 200)
			done = 1;

		HD_Animate (engine);

#ifndef IPOD
		if( SDL_MUSTLOCK(screen) )
			SDL_LockSurface(screen);
#endif

		HD_Render(engine);

#ifndef IPOD
		if( SDL_MUSTLOCK(screen) )
			SDL_UnlockSurface(screen);
#endif
	}
#ifdef IPOD
	HD_LCD_Quit();
	uint32 ertc = *(volatile uint32 *)0x60005010;
	printf ("%d frames in %d microseconds = %d.%02d frames/sec\n",
		t, ertc - srtc, 1000000 * t / (ertc - srtc),
		(1000000 * t / ((ertc - srtc) / 100)) % 100);
	sleep (5);
	reset_keypress();
#endif
	HD_Deinitialize(engine);
	return(0);
}
Example #13
0
/*===========================================================================*
 *				process_ksig				     *
 *===========================================================================*/
int process_ksig(endpoint_t proc_nr_e, int signo)
{
  register struct mproc *rmp;
  int proc_nr;
  pid_t proc_id, id;

  if(pm_isokendpt(proc_nr_e, &proc_nr) != OK) {
	printf("PM: process_ksig: %d?? not ok\n", proc_nr_e);
	return EDEADEPT; /* process is gone. */
  }
  rmp = &mproc[proc_nr];
  if ((rmp->mp_flags & (IN_USE | EXITING)) != IN_USE) {
#if 0
	printf("PM: process_ksig: %d?? exiting / not in use\n", proc_nr_e);
#endif
	return EDEADEPT; /* process is gone. */
  }
  proc_id = rmp->mp_pid;
  mp = &mproc[0];			/* pretend signals are from PM */
  mp->mp_procgrp = rmp->mp_procgrp;	/* get process group right */

  /* For SIGVTALRM and SIGPROF, see if we need to restart a
   * virtual timer. For SIGINT, SIGINFO, SIGWINCH and SIGQUIT, use proc_id 0
   * to indicate a broadcast to the recipient's process group.  For
   * SIGKILL, use proc_id -1 to indicate a systemwide broadcast.
   */
  switch (signo) {
      case SIGINT:
      case SIGQUIT:
      case SIGWINCH:
      case SIGINFO:
  	id = 0; break;	/* broadcast to process group */
      case SIGVTALRM:
      case SIGPROF:
      	check_vtimer(proc_nr, signo);
      	/* fall-through */
      default:
  	id = proc_id;
  	break;
  }
  check_sig(id, signo, TRUE /* ksig */);

  /* If SIGSNDELAY is set, an earlier sys_stop() failed because the process was
   * still sending, and the kernel hereby tells us that the process is now done
   * with that. We can now try to resume what we planned to do in the first
   * place: set up a signal handler. However, the process's message may have
   * been a call to PM, in which case the process may have changed any of its
   * signal settings. The process may also have forked, exited etcetera.
   */
  if (signo == SIGSNDELAY && (rmp->mp_flags & DELAY_CALL)) {
	/* When getting SIGSNDELAY, the process is stopped at least until the
	 * receipt of the SIGSNDELAY signal is acknowledged to the kernel. The
	 * process is not stopped on PROC_STOP in the kernel. However, now that
	 * there is no longer a delay call, stop_proc() is guaranteed to
	 * succeed immediately.
	 */
	rmp->mp_flags &= ~DELAY_CALL;

	assert(!(rmp->mp_flags & PROC_STOPPED));

	/* If the delay call was to PM, it may have resulted in a VFS call. In
	 * that case, we must wait with further signal processing until VFS has
	 * replied. Stop the process.
	 */
	if (rmp->mp_flags & VFS_CALL) {
		stop_proc(rmp, FALSE /*may_delay*/);

		return OK;
	}

	/* Process as many normal signals as possible. */
	check_pending(rmp);

	assert(!(rmp->mp_flags & DELAY_CALL));
  }
  
  /* See if the process is still alive */
  if ((mproc[proc_nr].mp_flags & (IN_USE | EXITING)) == IN_USE)  {
      return OK; /* signal has been delivered */
  }
  else {
      return EDEADEPT; /* process is gone */
  }
}
Example #14
0
/**
 * Handles an incoming CLIENT_KEY message from a client.
 */
void handle_clientkey(struct pr_group_list_t *group, int hostidx,
                      const unsigned char *message, unsigned meslen,
                      uint32_t src)
{
    const struct client_key_h *clientkey;
    const unsigned char *keyblob, *verify;
    struct pr_destinfo_t *dest;
    int dupmsg;

    clientkey = (const struct client_key_h *)message;
    keyblob = (const unsigned char *)clientkey + sizeof(struct client_key_h);
    verify = keyblob + ntohs(clientkey->bloblen);

    if (group->destcount == MAXPROXYDEST) {
        glog1(group, "Rejecting CLIENT_KEY from %08X: "
                     "max destinations exceeded", ntohl(src));
        send_downstream_abort(group, src, "Max destinations exceeded", 0);
        return;
    }
    if ((meslen < (clientkey->hlen * 4U)) ||
            ((clientkey->hlen * 4U) < sizeof(struct client_key_h) +
                ntohs(clientkey->bloblen) + ntohs(clientkey->siglen))) {
        glog1(group, "Rejecting CLIENT_KEY from %08X: invalid message size",
                     ntohl(src));
        send_downstream_abort(group, src, "Invalid message size", 0);
        return;
    }
    if ((((group->keyextype == KEYEX_RSA) ||
                    (group->keyextype == KEYEX_ECDH_RSA)) &&
                (keyblob[0] != KEYBLOB_RSA)) ||
            ((group->keyextype == KEYEX_ECDH_ECDSA) &&
             (keyblob[0] != KEYBLOB_EC))) {
        glog1(group, "Rejecting CLIENT_KEY from %08X: invalid keyblob type",
                     ntohl(src));
        send_downstream_abort(group, src, "Invalid keyblob type", 0);
        return;
    }


    if (hostidx == -1) {
        hostidx = add_client(src, group);
    }
    dest = &group->destinfo[hostidx];
    dupmsg = (dest->pubkey.key != 0);

    if (!dest->verified) {
        if (keyblob[0] == KEYBLOB_RSA) {
            if (!import_RSA_key(&dest->pubkey.rsa, keyblob,
                                ntohs(clientkey->bloblen))) {
                glog1(group, "Failed to load client public key");
                send_downstream_abort(group, src,
                                      "Failed to load client public key", 0);
                return;
            }
            dest->pubkeylen = RSA_keylen(dest->pubkey.rsa);
        } else {
            if (!import_EC_key(&dest->pubkey.ec, keyblob,
                               ntohs(clientkey->bloblen), 0)) {
                glog1(group, "Failed to load client public key");
                send_downstream_abort(group, src,
                                      "Failed to load client public key", 0);
                return;
            }
            dest->pubkeylen = ECDSA_siglen(dest->pubkey.ec);
        }
        if (!verify_fingerprint(client_fp, client_fp_count, keyblob,
                                ntohs(clientkey->bloblen), group, src)) {
            glog1(group, "Failed to verify client key fingerprint");
            send_downstream_abort(group, src, 
                                  "Failed to verify client key fingerprint", 0);
            return;
        }
        dest->verified = 1;
    }

    memcpy(dest->verifydata, verify, ntohs(clientkey->siglen));
    dest->verifylen = ntohs(clientkey->siglen);
    if (dest->registered) {
        if (!verify_client_key(group, hostidx)) {
            return;
        }
        dest->state = PR_CLIENT_REGISTERED;
    }

    glog2(group,"Received CLIENT_KEY%s from %s", dupmsg ? "+" : "", dest->name);

    if (dest->state == PR_CLIENT_REGISTERED) {
        // Pass in a dummy REGISTER message to check_pending, since
        // CLIENT_KEY is basically an extension of REGISTER.
        struct register_h reg;
        reg.func = REGISTER;
        check_pending(group, hostidx, (unsigned char *)&reg);
    }
}