コード例 #1
0
ファイル: sem.c プロジェクト: DragonQuan/minix3
PRIVATE void send_message_to_process(endpoint_t who, int ret, int ignore)
{
	message m;

	m.m_type = ret;
	sendnb(who, &m);
}
コード例 #2
0
ファイル: driver.c プロジェクト: AjeyBohare/minix
/*===========================================================================*
 *				blockdriver_reply			     *
 *===========================================================================*/
void blockdriver_reply(message *m_ptr, int ipc_status, int reply)
{
/* Reply to a block request sent to the driver. */
  endpoint_t caller_e;
  long id;
  int r;

  if (reply == EDONTREPLY)
	return;

  caller_e = m_ptr->m_source;
  id = m_ptr->BDEV_ID;

  memset(m_ptr, 0, sizeof(*m_ptr));

  m_ptr->m_type = BDEV_REPLY;
  m_ptr->BDEV_STATUS = reply;
  m_ptr->BDEV_ID = id;

  /* If we would block sending the message, send it asynchronously. The NOREPLY
   * flag is set because the caller may also issue a SENDREC (mixing sync and
   * async comm), and the asynchronous reply could otherwise end up satisfying
   * the SENDREC's receive part, after which our next SENDNB call would fail.
   */
  if (IPC_STATUS_CALL(ipc_status) == SENDREC)
	r = sendnb(caller_e, m_ptr);
  else
	r = asynsend3(caller_e, m_ptr, AMF_NOREPLY);

  if (r != OK)
	printf("blockdriver_reply: unable to send reply to %d: %d\n",
		caller_e, r);
}
コード例 #3
0
ファイル: philo.c プロジェクト: shervinshaikh/minix
// up not synchronous
void sem_up(endpoint_t e)
{
	message m;
	int r;

	m.m_type = SEM_UP;
	r = sendnb(e, &m);
	if (r)
		printf("semaphore up error\n");
}
コード例 #4
0
ファイル: main.c プロジェクト: Sciumo/minix
/*===========================================================================*
 *				reply					     *
 *===========================================================================*/
void reply(endpoint_t whom, int result)
{
/* Send a reply to a user process.  If the send fails, just ignore it. */
  int r;

  m_out.reply_type = result;
  r = sendnb(whom, &m_out);
  if (r != OK) {
	printf("VFS: %d couldn't send reply %d to %d: %d\n", mthread_self(),
		result, whom, r);
	util_stacktrace();
  }
}
コード例 #5
0
ファイル: chardriver.c プロジェクト: grd/minix
/*===========================================================================*
 *				sync_reply				     *
 *===========================================================================*/
static void sync_reply(message *m_ptr, int ipc_status, int reply)
{
/* Reply to a message sent to the driver. */
  endpoint_t caller_e, user_e;
  int r;

  caller_e = m_ptr->m_source;
  user_e = m_ptr->USER_ENDPT;

  m_ptr->m_type = TASK_REPLY;
  m_ptr->REP_ENDPT = user_e;
  m_ptr->REP_STATUS = reply;

  /* If we would block sending the message, send it asynchronously. */
  if (IPC_STATUS_CALL(ipc_status) == SENDREC)
	r = sendnb(caller_e, m_ptr);
  else
	r = asynsend(caller_e, m_ptr);

  if (r != OK)
	printf("driver_reply: unable to send reply to %d: %d\n", caller_e, r);
}
コード例 #6
0
ファイル: tps65950.c プロジェクト: anuragpeshne/minix
int
main(int argc, char *argv[])
{
	int r, i;
	struct tm t;
	endpoint_t user, caller;
	message m;
	int ipc_status, reply_status;

	env_setargs(argc, argv);

	r = i2cdriver_env_parse(&bus, &addresses[0], valid_addrs);
	if (r < 0) {
		log_warn(&log, "Expecting -args 'bus=X address=0xYY'\n");
		log_warn(&log, "Example -args 'bus=1 address=0x48'\n");
		return EXIT_FAILURE;
	} else if (r > 0) {
		log_warn(&log,
		    "Invalid slave address for device, expecting 0x48\n");
		return EXIT_FAILURE;
	}

	sef_local_startup();

	while (TRUE) {

		/* Receive Message */
		r = sef_receive_status(ANY, &m, &ipc_status);
		if (r != OK) {
			log_warn(&log, "sef_receive_status() failed\n");
			continue;
		}

		if (is_ipc_notify(ipc_status)) {

			if (m.m_source == DS_PROC_NR) {
				for (i = 0; i < NADDRESSES; i++) {
					/* changed state, update endpoint */
					i2cdriver_handle_bus_update
					    (&bus_endpoint, bus, addresses[i]);
				}
			}

			/* Do not reply to notifications. */
			continue;
		}

		caller = m.m_source;

		log_debug(&log, "Got message 0x%x from 0x%x\n", m.m_type,
		    caller);

		switch (m.m_type) {
		case RTCDEV_GET_TIME_G:
			/* Any user can read the time */
			reply_status = rtc_get_time(&t, m.RTCDEV_FLAGS);
			if (reply_status != OK) {
				break;
			}

			/* write results back to calling process */
			reply_status =
			    store_t(caller, (cp_grant_id_t) m.RTCDEV_GRANT,
			    &t);
			break;

		case RTCDEV_SET_TIME_G:
			/* Only super user is allowed to set the time */
			if (getnuid(caller) == SUPER_USER) {
				/* read time from calling process */
				reply_status =
				    fetch_t(caller,
				    (cp_grant_id_t) m.RTCDEV_GRANT, &t);
				if (reply_status != OK) {
					break;
				}

				reply_status =
				    rtc_set_time(&t, m.RTCDEV_FLAGS);
			} else {
				reply_status = EPERM;
			}
			break;

		case RTCDEV_PWR_OFF:
			reply_status = ENOSYS;
			break;

		default:
			/* Unrecognized call */
			reply_status = EINVAL;
			break;
		}

		/* Send Reply */
		m.m_type = RTCDEV_REPLY;
		m.RTCDEV_STATUS = reply_status;

		log_debug(&log, "Sending Reply");

		r = sendnb(caller, &m);
		if (r != OK) {
			log_warn(&log, "sendnb() failed\n");
			continue;
		}
	}

	rtc_exit();

	return 0;
}
コード例 #7
0
ファイル: main.c プロジェクト: 7shi/minix-tools
PUBLIC int main(int argc, char *argv[])
{
	message m;

	/* SEF local startup. */
	env_setargs(argc, argv);
	sef_local_startup();

	while (TRUE) {
		int r;
		int i;

		if ((r = sef_receive(ANY, &m)) != OK)
			printf("sef_receive failed %d.\n", r);
		who_e = m.m_source;
		call_type = m.m_type;

		if(verbose)
			printf("IPC: get %d from %d\n", call_type, who_e);

		if (call_type & NOTIFY_MESSAGE) {
			switch (who_e) {
			case PM_PROC_NR:
				/* PM sends a notify() on shutdown,
				 * checkout if there are still IPC keys,
				 * give warning messages.
				 */
				if (!is_sem_nil() || !is_shm_nil())
					printf("IPC: exit with un-clean states.\n");
				break;
			case VM_PROC_NR:
				/* currently, only semaphore needs such information. */
				sem_process_vm_notify();
				break;
			default:
				printf("IPC: ignoring notify() from %d\n",
					who_e);
				break;
			}
			continue;
		}

		/* dispatch messages */
		for (i = 0; i < SIZE(ipc_calls); i++) {
			if (ipc_calls[i].type == call_type) {
				int result;

				result = ipc_calls[i].func(&m);

				if (ipc_calls[i].reply)
					break;

				m.m_type = result;

				if(verbose && result != OK)
					printf("IPC: error for %d: %d\n",
						call_type, result);

				if ((r = sendnb(who_e, &m)) != OK)
					printf("IPC send error %d.\n", r);
				break;
			}
		}

		if (i == SIZE(ipc_calls)) {
			/* warn and then ignore */
			printf("IPC unknown call type: %d from %d.\n",
				call_type, who_e);
		}
		update_refcount_and_destroy();
	}

	/* no way to get here */
	return -1;
}
コード例 #8
0
ファイル: sem.c プロジェクト: DragonQuan/minix3
/*===========================================================================*
 *				do_semop		     		     *
 *===========================================================================*/
PUBLIC int do_semop(message *m)
{
	int id, i, j, r;
	struct sembuf *sops;
	unsigned int nsops;
	struct sem_struct *sem;
	int no_reply = 0;

	id = m->SEMOP_ID;
	nsops = (unsigned int) m->SEMOP_SIZE;

	r = EINVAL;
	if (!(sem = sem_find_id(id)))
		goto out;

	if (nsops <= 0)
		goto out;

	r = E2BIG;
	if (nsops > SEMOPM)
		goto out;

	/* check for read permission */
	r = EACCES;
	if (!check_perm(&sem->semid_ds.sem_perm, who_e, 0444))
		goto out;

	/* get the array from user application */
	r = ENOMEM;
	sops = malloc(sizeof(struct sembuf) * nsops);
	if (!sops)
		goto out_free;
	r = sys_datacopy(who_e, (vir_bytes) m->SEMOP_OPS,
			SELF_E, (vir_bytes) sops,
			sizeof(struct sembuf) * nsops);
	if (r != OK) {
		r = EINVAL;
		goto out_free;
	}

#ifdef DEBUG_SEM
	for (i = 0; i < nsops; i++)
		printf("SEMOP: num:%d  op:%d  flg:%d\n",
			sops[i].sem_num, sops[i].sem_op, sops[i].sem_flg);
#endif
	/* check for value range */
	r = EFBIG;
	for (i = 0; i < nsops; i++)
		if (sops[i].sem_num < 0 ||
				sops[i].sem_num >= sem->semid_ds.sem_nsems)
			goto out_free;

	/* check for duplicate number */
	r = EINVAL;
	for (i = 0; i < nsops; i++)
		for (j = i + 1; j < nsops; j++)
			if (sops[i].sem_num == sops[j].sem_num)
				goto out_free;

	/* check for EAGAIN error */
	r = EAGAIN;
	for (i = 0; i < nsops; i++) {
		int op_n, val;

		op_n = sops[i].sem_op;
		val = sem->sems[sops[i].sem_num].semval;

		if ((sops[i].sem_flg & IPC_NOWAIT) &&
				((!op_n && val) ||
				 (op_n < 0 &&
				  -op_n > val)))
			goto out_free;

	}
	/* there will be no errors left, so we can go ahead */
	for (i = 0; i < nsops; i++) {
		struct semaphore *s;
		int op_n;

		s = &sem->sems[sops[i].sem_num];
		op_n = sops[i].sem_op;

		s->sempid = getnpid(who_e);

		if (op_n > 0) {
			/* check for alter permission */
			r = EACCES;
			if (!check_perm(&sem->semid_ds.sem_perm, who_e, 0222))
				goto out_free;
			s->semval += sops[i].sem_op;
		} else if (!op_n) {
			if (s->semval) {
				/* put the process asleep */
				s->semzcnt++;
				s->zlist = realloc(s->zlist, sizeof(struct waiting) * s->semzcnt);
				if (!s->zlist) {
					printf("IPC: zero waiting list lost...\n");
					break;
				}
				s->zlist[s->semzcnt-1].who = who_e;
				s->zlist[s->semzcnt-1].val = op_n;

#ifdef DEBUG_SEM
				printf("SEMOP: Put into sleep... %d\n", who_e);
#endif
				no_reply++;
			}
		} else {
			/* check for alter permission */
			r = EACCES;
			if (!check_perm(&sem->semid_ds.sem_perm, who_e, 0222))
				goto out_free;
			if (s->semval >= -op_n)
				s->semval += op_n;
			else {
				/* put the process asleep */
				s->semncnt++;
				s->nlist = realloc(s->nlist, sizeof(struct waiting) * s->semncnt);
				if (!s->nlist) {
					printf("IPC: increase waiting list lost...\n");
					break;
				}
				s->nlist[s->semncnt-1].who = who_e;
				s->nlist[s->semncnt-1].val = -op_n;

				no_reply++;
			}
		}
	}

	r = OK;
out_free:
	free(sops);
out:
	/* if we reach here by errors
	 * or with no errors but we should reply back.
	 */
	if (r != OK || !no_reply) {
		m->m_type = r;

		sendnb(who_e, m);
	}

	/* awaken process if possible */
	update_semaphores();

	return 0;
}
コード例 #9
0
ファイル: tps65217.c プロジェクト: junzhe/minix_pandaboard_es
int
main(int argc, char *argv[])
{
	int r;
	endpoint_t user, caller;
	message m;
	int ipc_status;

	env_setargs(argc, argv);

	r = i2cdriver_env_parse(&bus, &address, valid_addrs);
	if (r < 0) {
		log_warn(&log, "Expecting -args 'bus=X address=0xYY'\n");
		log_warn(&log, "Example -args 'bus=1 address=0x24'\n");
		return EXIT_FAILURE;
	} else if (r > 0) {
		log_warn(&log,
		    "Invalid slave address for device, expecting 0x24\n");
		return EXIT_FAILURE;
	}

	sef_local_startup();

	while (TRUE) {

		/* Receive Message */
		r = sef_receive_status(ANY, &m, &ipc_status);
		if (r != OK) {
			log_warn(&log, "sef_receive_status() failed\n");
			continue;
		}

		log_trace(&log, "Got a message 0x%x from 0x%x\n", m.m_type,
		    m.m_source);

		if (is_ipc_notify(ipc_status)) {

			switch (m.m_source) {

			case DS_PROC_NR:
				/* bus driver changed state, update endpoint */
				i2cdriver_handle_bus_update(&bus_endpoint, bus,
				    address);
				break;
			case HARDWARE:
				intr_handler();
				break;
			default:
				break;
			}

			/* Do not reply to notifications. */
			continue;
		}

		caller = m.m_source;
		user = m.USER_ENDPT;

		/*
		 * Handle Message
		 *
		 * So far this driver only deals with notifications
		 * so it always replies to non-notifications with EINVAL.
		 */

		/* Send Reply */
		m.m_type = TASK_REPLY;
		m.REP_ENDPT = user;
		m.REP_STATUS = EINVAL;

		r = sendnb(caller, &m);
		if (r != OK) {
			log_warn(&log, "sendnb() failed\n");
			continue;
		}
	}

	return 0;
}
コード例 #10
0
ファイル: main.c プロジェクト: DragonQuan/minix3
PUBLIC int main(int argc, char *argv[])
{
	message m;

	/* SEF local startup. */
	env_setargs(argc, argv);
	sef_local_startup();

	while (TRUE) {
		int r;
		int i;

		if ((r = sef_receive(ANY, &m)) != OK)
			printf("sef_receive failed %d.\n", r);
		who_e = m.m_source;
		call_type = m.m_type;

		if(verbose)
			printf("IPC: get %d from %d\n", call_type, who_e);

		if (call_type & NOTIFY_MESSAGE) {
			switch (who_e) {
			case VM_PROC_NR:
				/* currently, only semaphore needs such information. */
				sem_process_vm_notify();
				break;
			default:
				printf("IPC: ignoring notify() from %d\n",
					who_e);
				break;
			}
			continue;
		}

		/* dispatch messages */
		for (i = 0; i < SIZE(ipc_calls); i++) {
			/* If any process does an IPC call,
			 * we have to know about it exiting.
			 * Tell VM to watch it for us.
			 */
			if(vm_watch_exit(m.m_source) != OK) {
				printf("IPC: watch failed on %d\n", m.m_source);
			}

			if (ipc_calls[i].type == call_type) {
				int result;

				result = ipc_calls[i].func(&m);

				if (ipc_calls[i].reply)
					break;

				m.m_type = result;

				if(verbose && result != OK)
					printf("IPC: error for %d: %d\n",
						call_type, result);

				if ((r = sendnb(who_e, &m)) != OK)
					printf("IPC send error %d.\n", r);
				break;
			}
		}

		if (i == SIZE(ipc_calls)) {
			/* warn and then ignore */
			printf("IPC unknown call type: %d from %d.\n",
				call_type, who_e);
		}
		update_refcount_and_destroy();
	}

	/* no way to get here */
	return -1;
}
コード例 #11
0
ファイル: readclock.c プロジェクト: anuragpeshne/minix
int
main(int argc, char **argv)
{
	int r;
	endpoint_t caller;
	struct tm t;
	message m;
	int ipc_status, reply_status;

	env_setargs(argc, argv);
	sef_local_startup();

	while (TRUE) {

		/* Receive Message */
		r = sef_receive_status(ANY, &m, &ipc_status);
		if (r != OK) {
			log_warn(&log, "sef_receive_status() failed\n");
			continue;
		}

		if (is_ipc_notify(ipc_status)) {

			/* Do not reply to notifications. */
			continue;
		}

		caller = m.m_source;

		log_debug(&log, "Got message 0x%x from 0x%x\n", m.m_type,
		    caller);

		switch (m.m_type) {
		case RTCDEV_GET_TIME:
			/* Any user can read the time */
			reply_status = rtc.get_time(&t, m.RTCDEV_FLAGS);
			if (reply_status != OK) {
				break;
			}

			/* write results back to calling process */
			reply_status =
			    store_t(caller, (vir_bytes) m.RTCDEV_TM, &t);
			break;

		case RTCDEV_SET_TIME:
			/* Only super user is allowed to set the time */
			if (getnuid(caller) == SUPER_USER) {
				/* read time from calling process */
				reply_status =
				    fetch_t(caller, (vir_bytes) m.RTCDEV_TM,
				    &t);
				if (reply_status != OK) {
					break;
				}

				reply_status =
				    rtc.set_time(&t, m.RTCDEV_FLAGS);
			} else {
				reply_status = EPERM;
			}
			break;

		case RTCDEV_PWR_OFF:
			/* Only PM is allowed to set the power off time */
			if (caller == PM_PROC_NR) {
				reply_status = rtc.pwr_off();
			} else {
				reply_status = EPERM;
			}
			break;

		default:
			/* Unrecognized call */
			reply_status = EINVAL;
			break;
		}

		/* Send Reply */
		m.m_type = RTCDEV_REPLY;
		m.RTCDEV_STATUS = reply_status;

		log_debug(&log, "Sending Reply");

		r = sendnb(caller, &m);
		if (r != OK) {
			log_warn(&log, "sendnb() failed\n");
			continue;
		}
	}

	rtc.exit();
	return 0;
}
コード例 #12
0
ファイル: main.c プロジェクト: QiuLihua83/minix2009
/*===========================================================================*
 *				main					     *
 *===========================================================================*/
PUBLIC int main()
{
/* Main routine of the process manager. */
  int result, s, proc_nr;
  struct mproc *rmp;
  sigset_t sigset;

  pm_init();			/* initialize process manager tables */

  /* This is PM's main loop-  get work and do it, forever and forever. */
  while (TRUE) {
	get_work();		/* wait for an PM system call */

	/* Check for system notifications first. Special cases. */
	switch(call_nr)
	{
	case SYN_ALARM:
		pm_expire_timers(m_in.NOTIFY_TIMESTAMP);
		result = SUSPEND;		/* don't reply */
		break;
	case SYS_SIG:				/* signals pending */
		sigset = m_in.NOTIFY_ARG;
		if (sigismember(&sigset, SIGKSIG))  {
			(void) ksig_pending();
		} 
		result = SUSPEND;		/* don't reply */
		break;
	case PM_GET_WORK:
		if (who_e == FS_PROC_NR)
		{
			send_work();
			result= SUSPEND;		/* don't reply */
		}
		else
			result= ENOSYS;
		break;
	case PM_EXIT_REPLY:
	case PM_REBOOT_REPLY:
	case PM_EXEC_REPLY:
	case PM_CORE_REPLY:
	case PM_EXIT_REPLY_TR:
		if (who_e == FS_PROC_NR)
		{
			handle_fs_reply(&m_in);
			result= SUSPEND;		/* don't reply */
		}
		else
			result= ENOSYS;
		break;
	case ALLOCMEM:
		result= do_allocmem();
		break;
	case FORK_NB:
		result= do_fork_nb();
		break;
	case EXEC_NEWMEM:
		result= exec_newmem();
		break;
	case EXEC_RESTART:
		result= do_execrestart();
		break;
	case PROCSTAT:
		result= do_procstat();
		break;
	case GETPROCNR:
		result= do_getprocnr();
		break;
	case GETPUID:
		result= do_getpuid();
		break;
	case DIAG_REPL :
		diag_repl();
		result= SUSPEND;
		break;
	default:
		/* Else, if the system call number is valid, perform the
		 * call.
		 */
		if ((unsigned) call_nr >= NCALLS) {
			result = ENOSYS;
		} else {
#if ENABLE_SYSCALL_STATS
			calls_stats[call_nr]++;
#endif

			result = (*call_vec[call_nr])();

		}
		break;
	}

	/* Send the results back to the user to indicate completion. */
	if (result != SUSPEND) setreply(who_p, result);

	/* Send out all pending reply messages, including the answer to
	 * the call just made above.
	 */
	for (proc_nr=0, rmp=mproc; proc_nr < NR_PROCS; proc_nr++, rmp++) {
		/* In the meantime, the process may have been killed by a
		 * signal (e.g. if a lethal pending signal was unblocked)
		 * without the PM realizing it. If the slot is no longer in
		 * use or just a zombie, don't try to reply.
		 */
		if ((rmp->mp_flags & (REPLY | IN_USE | ZOMBIE)) ==
		   (REPLY | IN_USE)) {
			s=sendnb(rmp->mp_endpoint, &rmp->mp_reply);
			if (s != OK) {
				printf("PM can't reply to %d (%s): %d\n",
					rmp->mp_endpoint, rmp->mp_name, s);
			}
			rmp->mp_flags &= ~REPLY;
		}
	}
  }
  return(OK);
}