Example #1
0
File: sem.c Project: Hooman3/minix
static void send_message_to_process(endpoint_t who, int ret, int ignore)
{
	message m;

	m.m_type = ret;
	ipc_sendnb(who, &m);
}
Example #2
0
/*===========================================================================*
 *				reply					     *
 *===========================================================================*/
static void reply(message *m_out, endpoint_t whom, int result)
{
/* Send a reply to a user process.  If the send fails, just ignore it. */
  int r;

  m_out->m_type = result;
  r = ipc_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();
  }
}
Example #3
0
/*===========================================================================*
 *				send_reply				     *
 *===========================================================================*/
static void send_reply(endpoint_t endpt, message *m_ptr, int ipc_status)
{
/* Send a reply message to a request. */
  int r;

  /* 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 = ipc_sendnb(endpt, m_ptr);
  else
	r = asynsend3(endpt, m_ptr, AMF_NOREPLY);

  if (r != OK)
	printf("blockdriver: unable to send reply to %d: %d\n", endpt, r);
}
Example #4
0
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.m_lc_readclock_rtcdev.flags);
			if (reply_status != OK) {
				break;
			}

			/* write results back to calling process */
			reply_status =
			    store_t(caller, m.m_lc_readclock_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, m.m_lc_readclock_rtcdev.tm,
				    &t);
				if (reply_status != OK) {
					break;
				}

				reply_status =
				    rtc.set_time(&t, m.m_lc_readclock_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.m_readclock_lc_rtcdev.status = reply_status;

		log_debug(&log, "Sending Reply");

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

	rtc.exit();
	return 0;
}
Example #5
0
File: sem.c Project: Hooman3/minix
/*===========================================================================*
 *				do_semop		     		     *
 *===========================================================================*/
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->m_lc_ipc_semop.id;
	nsops = m->m_lc_ipc_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->m_lc_ipc_semop.ops,
			SELF, (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 >= 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;

		ipc_sendnb(who_e, m);
	}

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

	return 0;
}
Example #6
0
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.m_lc_readclock_rtcdev.flags);
			if (reply_status != OK) {
				break;
			}

			/* write results back to calling process */
			reply_status =
			    store_t(caller, m.m_lc_readclock_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,
					    m.m_lc_readclock_rtcdev.grant, &t);
				if (reply_status != OK) {
					break;
				}

				reply_status =
				    rtc_set_time(&t,
					    m.m_lc_readclock_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.m_readclock_lc_rtcdev.status = reply_status;

		log_debug(&log, "Sending Reply");

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

	rtc_exit();

	return 0;
}