enum policy supported;
};
-static struct rprocpub rprocpub[NR_SYS_PROCS];
-static struct rproc rproc[NR_SYS_PROCS];
+static struct {
+ struct rproc proc[NR_SYS_PROCS];
+ struct rprocpub pub[NR_SYS_PROCS];
+} rproc;
+
static struct policies policies[NR_SYS_PROCS];
static struct inode *service_node;
};
/* Find the related policy, based on the file name of the service. */
- ref_label = strrchr(rprocpub[slot].proc_name, '/');
+ ref_label = strrchr(rproc.pub[slot].proc_name, '/');
if (NULL == ref_label)
- ref_label = rprocpub[slot].proc_name;
+ ref_label = rproc.pub[slot].proc_name;
memset(pol[slot].formatted, 0, MAX_POL_FORMAT_SZ);
for(pos = 0; pos < (sizeof(def_pol) / sizeof(def_pol[0])); pos++) {
struct inode *node;
struct inode_stat stat;
index_t slot;
-
- /* There is not much we can do if either of these calls fails. */
- (void)getsysinfo(RS_PROC_NR, SI_PROCPUB_TAB, rprocpub,
- sizeof(rprocpub));
- (void)getsysinfo(RS_PROC_NR, SI_PROC_TAB, rproc, sizeof(rproc));
+ static int warned = FALSE;
+ int r;
+
+ /* There is not much we can do if this call fails. */
+ r = getsysinfo(RS_PROC_NR, SI_PROCALL_TAB, &rproc, sizeof(rproc));
+ if (r != OK && !warned) {
+ printf("PROCFS: unable to obtain RS tables (%d)\n", r);
+ warned = TRUE;
+ }
/*
* As with PIDs, we make two passes. Delete first, then add. This
* If the slot is no longer in use, or the label name does not
* match, the node must be deleted.
*/
- if (!(rproc[slot].r_flags & RS_IN_USE) ||
- strcmp(get_inode_name(node), rprocpub[slot].label))
+ if (!(rproc.proc[slot].r_flags & RS_IN_USE) ||
+ strcmp(get_inode_name(node), rproc.pub[slot].label))
delete_inode(node);
}
stat.gid = SUPER_USER;
for (slot = 0; slot < NR_SYS_PROCS; slot++) {
- if (!(rproc[slot].r_flags & RS_IN_USE) ||
+ if (!(rproc.proc[slot].r_flags & RS_IN_USE) ||
get_inode_by_index(service_node, slot) != NULL)
continue;
- node = add_inode(service_node, rprocpub[slot].label, slot,
+ node = add_inode(service_node, rproc.pub[slot].label, slot,
&stat, (index_t)0, (cbdata_t)slot);
if (node == NULL)
return;
slot = get_inode_index(node);
- rpub = &rprocpub[slot];
- rp = &rproc[slot];
+ rpub = &rproc.pub[slot];
+ rp = &rproc.proc[slot];
/* TODO: add a large number of other fields! */
buf_printf("filename: %s\n", rpub->proc_name);
{
vir_bytes src_addr, dst_addr;
int dst_proc;
- size_t len;
+ size_t size, len;
int s;
/* Check if the call can be allowed. */
if((s = check_call_permission(m_ptr->m_source, 0, NULL)) != OK)
return s;
+ dst_proc = m_ptr->m_source;
+ dst_addr = m_ptr->m_lsys_getsysinfo.where;
+ size = m_ptr->m_lsys_getsysinfo.size;
+
switch(m_ptr->m_lsys_getsysinfo.what) {
case SI_PROC_TAB:
src_addr = (vir_bytes) rproc;
len = sizeof(struct rproc) * NR_SYS_PROCS;
break;
+ case SI_PROCALL_TAB:
+ /* Copy out both tables, one after the other. */
+ src_addr = (vir_bytes) rproc;
+ len = sizeof(struct rproc) * NR_SYS_PROCS;
+ if (len > size)
+ return EINVAL;
+ if ((s = sys_datacopy(SELF, src_addr, dst_proc, dst_addr, len)) != OK)
+ return s;
+ dst_addr += len;
+ size -= len;
+ /* FALLTHROUGH */
case SI_PROCPUB_TAB:
src_addr = (vir_bytes) rprocpub;
len = sizeof(struct rprocpub) * NR_SYS_PROCS;
return(EINVAL);
}
- if (len != m_ptr->m_lsys_getsysinfo.size)
+ if (len != size)
return(EINVAL);
- dst_proc = m_ptr->m_source;
- dst_addr = m_ptr->m_lsys_getsysinfo.where;
return sys_datacopy(SELF, src_addr, dst_proc, dst_addr, len);
}