int shm_resinit(dispatch_t *dpp) { int ret; /* shmget() doesn't talk about umask but shm_open() does. */ umask(0); iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &shm_connect, _RESMGR_IO_NFUNCS, &shm_io); shm_io.msg = shm_msg; iofunc_attr_init(&shm_ioattr, 0666, 0, 0); shm_resid = resmgr_attach(dpp, 0, PATH_SHMMGR, _FTYPE_ANY, 0, &shm_connect, &shm_io, &shm_ioattr); if (shm_resid == -1) { return -1; } if ((ret = pthread_create(NULL, NULL, shmres_handle, dpp)) != EOK) { errno = ret; resmgr_detach(dpp, shm_resid, _RESMGR_DETACH_ALL); return -1; } return 0; }
/* Most of the time w/ these function the user wants the dpp to be autocreated, so the default is to destroy it when we detach. */ int name_detach(name_attach_t *attach, unsigned flags) { int ret = EOK; if (attach) { ret = resmgr_detach(attach->dpp, attach->mntid, 0); if (!(flags & NAME_FLAG_DETACH_SAVEDPP)) { (void)dispatch_destroy(attach->dpp); } free(attach); } return ret; }
static int _spi_register_interface(void *data) { spi_dev_t *dev = data; SPIDEV *drvhdl; resmgr_attr_t rattr; char devname[PATH_MAX + 1]; struct passwd* pw; uid_t uid = 0; gid_t gid = 0; if ((drvhdl = dev->funcs->init(dev, dev->opts)) == NULL) { free(dev->opts); dev->opts = NULL; return (!EOK); } dev->drvhdl = drvhdl; /* set up i/o handler functions */ memset(&rattr, 0, sizeof(rattr)); rattr.nparts_max = SPI_RESMGR_NPARTS_MIN; rattr.msg_max_size = SPI_RESMGR_MSGSIZE_MIN; iofunc_attr_init(&drvhdl->attr, S_IFCHR | devperm, NULL, NULL); drvhdl->attr.mount = &_spi_mount; /* register device name */ snprintf(devname, PATH_MAX, "/dev/spi%d", dev->devnum); if (-1 == (dev->id = resmgr_attach(dev->dpp, &rattr, devname, _FTYPE_ANY, 0, &_spi_connect_funcs, &_spi_io_funcs, (void *)drvhdl))) { perror("resmgr_attach() failed"); goto failed1; } resmgr_devino(dev->id, &drvhdl->attr.mount->dev, &drvhdl->attr.inode); if (UserParm != NULL) { if(*UserParm >= '0' && *UserParm <= '9') { uid = strtol(UserParm, &UserParm, 0); if(*UserParm++ == ':') { gid = strtol(UserParm, NULL, 0); } } else if (( pw = getpwnam( UserParm ) ) != NULL ) { uid = pw->pw_uid; gid = pw->pw_gid; } if(setgid(gid) == -1 || setuid(uid) == -1 ) { perror("setgid() / setuid() failed"); } } if ((dev->ctp = dispatch_context_alloc(dev->dpp)) != NULL) return (EOK); perror("dispatch_context_alloc() failed"); resmgr_detach(dev->dpp, dev->id, _RESMGR_DETACH_ALL); failed1: dev->funcs->fini(drvhdl); return (!EOK); }
name_attach_t *name_attach(dispatch_t *dpp, const char *path, unsigned flags) { name_attach_t *attach; int auto_create, mntid, chid; char *newname; //Reserve leading /'s for future use if (!path || !*path || *path == '/') { errno = EINVAL; return NULL; } //Don't allow ../ or .. attaches to escape if ((newname = (char *)strstr(path, "..")) && (newname[2] == '/' || newname[2] == '\0')) { errno = EINVAL; return NULL; } newname = NULL; mntid = chid = -1; auto_create = (dpp) ? 0 : 1; if (!dpp && !(dpp = dispatch_create())) { errno = EINVAL; return NULL; } if (flags & NAME_FLAG_ATTACH_GLOBAL) { if (!(newname = alloca(strlen(__name_prefix_global) + strlen(path) + 1))) { errno = ENOMEM; goto failure; } strcpy(newname, __name_prefix_global); } else { if (!(newname = alloca(strlen(__name_prefix_local) + strlen(path) + 1))) { errno = ENOMEM; goto failure; } strcpy(newname, __name_prefix_local); } strcat(newname, path); //TODO: Make the last thing really an attribute matching us? //TODO: Allow the user to specify a function they want to be called /* We have to regist with global service manager, this is done by: * 1) do an empty resmgr_attach() to setup things (in case dpp->chid isn't there) * 2) send an _IO_CONNECT_OPEN, _IO_CONNECT_EXTRA_RESMGR_LINK, to the * manager. (What we really want is _IO_CONENCT_LINK plus * _IO_CONNECT_EXTRA_RESMGR_LINK, but PathMgr won't pass it down to GNS * 3) if 2) faild, there is no local GNS exist, then ONLY IF the attach * if for _NAME_FLAG_ATTACH_LOCAL, we will send a _IO_CONNECT_LINK, * _IO_CONNECT_EXTRA_RESMGR_LINK, as if pathmgr_link() did, this will * regist it with pathmgr. And everything still works in local nodes. */ { unsigned nflag; struct link *linkl; struct _io_resmgr_link_extra extra; /* make sure no real attach will happen */ nflag = flags & ~_RESMGR_FLAG_FTYPEONLY; if (resmgr_attach(dpp, NULL, NULL, 0, nflag, NULL, NULL, NULL) == -1) { goto failure; } if (!(linkl = _resmgr_link_alloc())) { goto failure; } linkl->connect_funcs = 0; linkl->io_funcs = 0; linkl->handle = 0; extra.nd = ND_LOCAL_NODE; extra.pid = getpid(); extra.chid = dpp->chid; extra.handle = mntid = linkl->id; extra.file_type = _FTYPE_NAME; extra.flags = flags & _RESMGR_FLAG_MASK; linkl->link_id = _connect(PATHMGR_COID, newname, 0, 0, SH_DENYNO, _IO_CONNECT_OPEN, 0, 0, _FTYPE_NAME, _IO_CONNECT_EXTRA_RESMGR_LINK, sizeof extra, &extra, 0, 0, 0); if (linkl->link_id == -1 && !(flags & NAME_FLAG_ATTACH_GLOBAL) && (errno == ENOTSUP || errno == ENOENT || errno == ENOSYS)) { linkl->link_id = _connect(PATHMGR_COID, newname, 0, 0, SH_DENYNO, _IO_CONNECT_LINK, 0, 0, _FTYPE_NAME, _IO_CONNECT_EXTRA_RESMGR_LINK, sizeof extra, &extra, 0, 0, 0); } if (linkl->link_id == -1) { _resmgr_link_free(linkl->id, _RESMGR_DETACH_ALL); mntid = -1; goto failure; } linkl->flags &= ~_RESMGR_LINK_HALFOPEN; } chid = _DPP(dpp)->chid; if (!(attach = malloc(sizeof(*attach)))) { errno = ENOMEM; goto failure; } attach->dpp = dpp; attach->chid = chid; attach->mntid = mntid; return attach; failure: if (mntid > 0) { (void)resmgr_detach(dpp, mntid, 0); } if (auto_create && dpp) { (void)dispatch_destroy(dpp); } return NULL; }