⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sem.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	nv->nv_name = dev->d_name;	nv->nv_int = makedev(dev->d_major, unit * 8 + part);	return (0);}static intlresolve(nvp, name, what, dflt, part)	register struct nvlist **nvp;	const char *name, *what;	struct nvlist *dflt;	int part;{	int err;	while ((err = resolve(nvp, name, what, dflt, part)) == 0 &&	    (*nvp)->nv_next != NULL)		nvp = &(*nvp)->nv_next;	return (err);}/* * Add a completed configuration to the list. */voidaddconf(cf0)	register struct config *cf0;{	register struct config *cf;	register struct nvlist *nv;	const char *name;	name = cf0->cf_name;	cf = emalloc(sizeof *cf);	if (ht_insert(cfhashtab, name, cf)) {		error("configuration `%s' already defined", name);		free(cf);		goto bad;	}	*cf = *cf0;	/*	 * Look for "swap generic".	 */	for (nv = cf->cf_swap; nv != NULL; nv = nv->nv_next)		if (nv->nv_str == s_generic)			break;	if (nv != NULL) {		/*		 * Make sure no root or dump device specified, and no		 * other swap devices.  Note single | here (check all).		 */		nv = cf->cf_swap;		if (exclude(cf->cf_root, name, "root device") |		    exclude(nv->nv_next, name, "additional swap devices") |		    exclude(cf->cf_dump, name, "dump device"))			goto bad;	} else {		nv = cf->cf_root;		if (nv == NULL) {			error("%s: no root device specified", name);			goto bad;		}		if (resolve(&cf->cf_root, name, "root", nv, 'a') |		    lresolve(&cf->cf_swap, name, "swap", nv, 'b') |		    resolve(&cf->cf_dump, name, "dumps", nv, 'b'))			goto bad;	}	*nextcf = cf;	nextcf = &cf->cf_next;	return;bad:	nvfreel(cf0->cf_root);	nvfreel(cf0->cf_swap);	nvfreel(cf0->cf_dump);}voidsetconf(npp, what, v)	register struct nvlist **npp;	const char *what;	struct nvlist *v;{	if (*npp != NULL) {		error("duplicate %s specification", what);		nvfreel(v);	} else		*npp = v;}static struct devi *newdevi(name, unit, d)	const char *name;	int unit;	struct devbase *d;{	register struct devi *i;	i = emalloc(sizeof *i);	i->i_name = name;	i->i_unit = unit;	i->i_base = d;	i->i_next = NULL;	i->i_bsame = NULL;	i->i_alias = NULL;	i->i_at = NULL;	i->i_atattr = NULL;	i->i_atdev = NULL;	i->i_locs = NULL;	i->i_cfflags = 0;	i->i_lineno = currentline();	if (unit >= d->d_umax)		d->d_umax = unit + 1;	return (i);}/* * Add the named device as attaching to the named attribute (or perhaps * another device instead) plus unit number. */voidadddev(name, at, loclist, flags)	const char *name, *at;	struct nvlist *loclist;	int flags;{	register struct devi *i;	/* the new instance */	register struct attr *attr;	/* attribute that allows attach */	register struct devbase *ib;	/* i->i_base */	register struct devbase *ab;	/* not NULL => at another dev */	register struct nvlist *nv;	const char *cp;	int atunit;	char atbuf[NAMESIZE];	ab = NULL;	if (at == NULL) {		/* "at root" */		if ((i = getdevi(name)) == NULL)			goto bad;		/*		 * Must warn about i_unit > 0 later, after taking care of		 * the STAR cases (we could do non-star's here but why		 * bother?).  Make sure this device can be at root.		 */		ib = i->i_base;		if (!onlist(ib->d_atlist, NULL)) {			error("%s's cannot attach to the root", ib->d_name);			goto bad;		}		attr = &errattr;	/* a convenient "empty" attr */	} else {		if (split(at, strlen(at), atbuf, sizeof atbuf, &atunit)) {			error("invalid attachment name `%s'", at);			/* (void)getdevi(name); -- ??? */			goto bad;		}		if ((i = getdevi(name)) == NULL)			goto bad;		ib = i->i_base;		cp = intern(atbuf);		if ((attr = ht_lookup(attrtab, cp)) == NULL) {			/*			 * Have to work a bit harder to see whether we have			 * something like "tg0 at esp0" (where esp is merely			 * not an attribute) or "tg0 at nonesuch0" (where			 * nonesuch is not even a device).			 */			if ((ab = ht_lookup(devbasetab, cp)) == NULL) {				error("%s at %s: `%s' unknown",				    name, at, atbuf);				goto bad;			}			/*			 * See if the named parent carries an attribute			 * that allows it to supervise device ib.			 */			for (nv = ab->d_attrs; nv != NULL; nv = nv->nv_next) {				attr = nv->nv_ptr;				if (onlist(attr->a_devs, ib))					goto ok;			}			attr = &errattr;/* now onlist below will fail */		}		if (!onlist(attr->a_devs, ib)) {			error("%s's cannot attach to %s's", ib->d_name, atbuf);			goto bad;		}	}ok:	if ((i->i_locs = fixloc(name, attr, loclist)) == NULL)		goto bad;	if (i->i_unit == STAR && ib->d_vectors != NULL) {		error("%s's cannot be *'d as they have preset vectors",		    ib->d_name);		goto bad;	}	i->i_at = at;	i->i_atattr = attr;	i->i_atdev = ab;	i->i_atunit = atunit;	i->i_cfflags = flags;	selectbase(ib);	/* all done, fall into ... */bad:	nvfreel(loclist);	return;}voidaddpseudo(name, number)	const char *name;	int number;{	register struct devbase *d;	register struct devi *i;	d = ht_lookup(devbasetab, name);	if (d == NULL) {		error("undefined pseudo-device %s", name);		return;	}	if (!d->d_ispseudo) {		error("%s is a real device, not a pseudo-device", name);		return;	}	if (ht_lookup(devitab, name) != NULL) {		error("`%s' already defined", name);		return;	}	i = newdevi(name, number - 1, d);	/* foo 16 => "foo0..foo15" */	if (ht_insert(devitab, name, i))		panic("addpseudo(%s)", name);	selectbase(d);	*nextpseudo = i;	nextpseudo = &i->i_next;	npseudo++;}/* * Define a new instance of a specific device. */static struct devi *getdevi(name)	const char *name;{	register struct devi *i, *firsti;	register struct devbase *d;	int unit;	char base[NAMESIZE];	if (split(name, strlen(name), base, sizeof base, &unit)) {		error("invalid device name `%s'", name);		return (NULL);	}	d = ht_lookup(devbasetab, intern(base));	if (d == NULL) {		error("%s: unknown device `%s'", name, base);		return (NULL);	}	if (d->d_ispseudo) {		error("%s: %s is a pseudo-device", name, base);		return (NULL);	}	firsti = ht_lookup(devitab, name);	i = newdevi(name, unit, d);	if (firsti == NULL) {		if (ht_insert(devitab, name, i))			panic("getdevi(%s)", name);		*d->d_ipp = i;		d->d_ipp = &i->i_bsame;	} else {		while (firsti->i_alias)			firsti = firsti->i_alias;		firsti->i_alias = i;	}	*nextdevi = i;	nextdevi = &i->i_next;	ndevi++;	return (i);}static const char *concat(name, c)	const char *name;	int c;{	register int len;	char buf[NAMESIZE];	len = strlen(name);	if (len + 2 > sizeof(buf)) {		error("device name `%s%c' too long", name, c);		len = sizeof(buf) - 2;	}	bcopy(name, buf, len);	buf[len] = c;	buf[len + 1] = 0;	return (intern(buf));}const char *starref(name)	const char *name;{	return (concat(name, '*'));}const char *wildref(name)	const char *name;{	return (concat(name, '?'));}/* * Split a name like "foo0" into base name (foo) and unit number (0). * Return 0 on success.  To make this useful for names like "foo0a", * the length of the "foo0" part is one of the arguments. */static intsplit(name, nlen, base, bsize, aunit)	register const char *name;	size_t nlen;	char *base;	size_t bsize;	int *aunit;{	register const char *cp;	register int c, l;	l = nlen;	if (l < 2 || l >= bsize || isdigit(*name))		return (1);	c = (u_char)name[--l];	if (!isdigit(c)) {		if (c == '*')			*aunit = STAR;		else if (c == '?')			*aunit = WILD;		else			return (1);	} else {		cp = &name[l];		while (isdigit(cp[-1]))			l--, cp--;		*aunit = atoi(cp);	}	bcopy(name, base, l);	base[l] = 0;	return (0);}/* * We have an instance of the base foo, so select it and all its * attributes for "optional foo". */static voidselectbase(d)	register struct devbase *d;{	register struct attr *a;	register struct nvlist *nv;	(void)ht_insert(selecttab, d->d_name, (char *)d->d_name);	for (nv = d->d_attrs; nv != NULL; nv = nv->nv_next) {		a = nv->nv_ptr;		(void)ht_insert(selecttab, a->a_name, (char *)a->a_name);	}}/* * Is the given pointer on the given list of pointers? */static intonlist(nv, ptr)	register struct nvlist *nv;	register void *ptr;{	for (; nv != NULL; nv = nv->nv_next)		if (nv->nv_ptr == ptr)			return (1);	return (0);}static char *extend(p, name)	register char *p;	const char *name;{	register int l;	l = strlen(name);	bcopy(name, p, l);	p += l;	*p++ = ',';	*p++ = ' ';	return (p);}/* * Check that we got all required locators, and default any that are * given as "?" and have defaults.  Return 0 on success. */static const char **fixloc(name, attr, got)	const char *name;	register struct attr *attr;	register struct nvlist *got;{	register struct nvlist *m, *n;	register int ord;	register const char **lp;	int nmissing, nextra, nnodefault;	char *mp, *ep, *ndp;	char missing[1000], extra[1000], nodefault[1000];	static const char *nullvec[1];	/*	 * Look for all required locators, and number the given ones	 * according to the required order.  While we are numbering,	 * set default values for defaulted locators.	 */	if (attr->a_loclen == 0)	/* e.g., "at root" */		lp = nullvec;	else		lp = emalloc((attr->a_loclen + 1) * sizeof(const char *));	for (n = got; n != NULL; n = n->nv_next)		n->nv_int = -1;	nmissing = 0;	mp = missing;	/* yes, this is O(mn), but m and n should be small */	for (ord = 0, m = attr->a_locs; m != NULL; m = m->nv_next, ord++) {		for (n = got; n != NULL; n = n->nv_next) {			if (n->nv_name == m->nv_name) {				n->nv_int = ord;				break;			}		}		if (n == NULL && m->nv_int == 0) {			nmissing++;			mp = extend(mp, m->nv_name);		}		lp[ord] = m->nv_str;	}	if (ord != attr->a_loclen)		panic("fixloc");	lp[ord] = NULL;	nextra = 0;	ep = extra;	nnodefault = 0;	ndp = nodefault;	for (n = got; n != NULL; n = n->nv_next) {		if (n->nv_int >= 0) {			if (n->nv_str != NULL)				lp[n->nv_int] = n->nv_str;			else if (lp[n->nv_int] == NULL) {				nnodefault++;				ndp = extend(ndp, n->nv_name);			}		} else {			nextra++;			ep = extend(ep, n->nv_name);		}	}	if (nextra) {		ep[-2] = 0;	/* kill ", " */		error("%s: extraneous locator%s: %s",		    name, nextra > 1 ? "s" : "", extra);	}	if (nmissing) {		mp[-2] = 0;		error("%s: must specify %s", name, missing);	}	if (nnodefault) {		ndp[-2] = 0;		error("%s: cannot wildcard %s", name, nodefault);	}	if (nmissing || nnodefault) {		free(lp);		lp = NULL;	}	return (lp);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -