static int cgt_init(clockid_t clk, struct timespec *ts)
{
	void *p = __vdsosym(VDSO_CGT_VER, VDSO_CGT_SYM);
	int (*f)(clockid_t, struct timespec *) =
		(int (*)(clockid_t, struct timespec *))p;
	a_cas_p(&vdso_func, (void *)cgt_init, p);
	return f ? f(clk, ts) : -ENOSYS;
}
Exemple #2
0
char *bindtextdomain(const char *domainname, const char *dirname)
{
	static int lock[2];
	struct binding *p, *q;

	if (!domainname) return 0;
	if (!dirname) return gettextdir(domainname, &(size_t){0});

	size_t domlen = strlen(domainname);
	size_t dirlen = strlen(dirname);
	if (domlen > NAME_MAX || dirlen >= PATH_MAX) {
		errno = EINVAL;
		return 0;
	}

	LOCK(lock);

	for (p=bindings; p; p=p->next) {
		if (!strcmp(p->domainname, domainname) &&
		    !strcmp(p->dirname, dirname)) {
			break;
		}
	}

	if (!p) {
		p = malloc(sizeof *p + domlen + dirlen + 2);
		if (!p) {
			UNLOCK(lock);
			return 0;
		}
		p->next = bindings;
		p->dirlen = dirlen;
		p->domainname = p->buf;
		p->dirname = p->buf + domlen + 1;
		memcpy(p->domainname, domainname, domlen+1);
		memcpy(p->dirname, dirname, dirlen+1);
		a_cas_p(&bindings, bindings, p);
	}

	a_store(&p->active, 1);

	for (q=bindings; q; q=q->next) {
		if (!strcmp(p->domainname, domainname) && q != p)
			a_store(&q->active, 0);
	}

	UNLOCK(lock);
	
	return (char *)p->dirname;
}
Exemple #3
0
int pthread_key_create(pthread_key_t *k, void (*dtor)(void *))
{
	unsigned i = (uintptr_t)&k / 16 % PTHREAD_KEYS_MAX;
	unsigned j = i;

	__pthread_self_init();
	if (!dtor) dtor = nodtor;
	do {
		if (!a_cas_p(keys+j, 0, dtor)) {
			*k = j;
			return 0;
		}
	} while ((j=(j+1)%PTHREAD_KEYS_MAX) != i);
	return EAGAIN;
}
Exemple #4
0
int pthread_key_create(pthread_key_t *k, void (*dtor)(void *))
{
	unsigned i = (uintptr_t)&k / 16 % PTHREAD_KEYS_MAX;
	unsigned j = i;

#ifndef __EMSCRIPTEN__ // XXX Emscripten does not need specific initialization for threads, the runtime has initialized everything prior to running.
	__pthread_self_init();
#endif
	if (!dtor) dtor = nodtor;
	do {
		if (!a_cas_p(keys+j, 0, (void *)dtor)) {
			*k = j;
			return 0;
		}
	} while ((j=(j+1)%PTHREAD_KEYS_MAX) != i);
	return EAGAIN;
}
int __pthread_key_create(pthread_key_t *k, void (*dtor)(void *))
{
	unsigned i = (uintptr_t)&k / 16 % PTHREAD_KEYS_MAX;
	unsigned j = i;
	pthread_t self = __pthread_self();

	/* This can only happen in the main thread before
	 * pthread_create has been called. */
	if (!self->tsd) self->tsd = __pthread_tsd_main;

	if (!dtor) dtor = nodtor;
	do {
		if (!a_cas_p(keys+j, 0, (void *)dtor)) {
			*k = j;
			return 0;
		}
	} while ((j=(j+1)%PTHREAD_KEYS_MAX) != i);
	return EAGAIN;
}
static void handler(int sig)
{
	struct chain ch;
	int old_errno = errno;

	sem_init(&ch.target_sem, 0, 0);
	sem_init(&ch.caller_sem, 0, 0);

	ch.tid = __syscall(SYS_gettid);

	do ch.next = head;
	while (a_cas_p(&head, ch.next, &ch) != ch.next);

	if (a_cas(&target_tid, ch.tid, 0) == (ch.tid | 0x80000000))
		__syscall(SYS_futex, &target_tid, FUTEX_UNLOCK_PI|FUTEX_PRIVATE);

	sem_wait(&ch.target_sem);
	callback(context);
	sem_post(&ch.caller_sem);
	sem_wait(&ch.target_sem);

	errno = old_errno;
}
Exemple #7
0
char *dcngettext(const char *domainname, const char *msgid1, const char *msgid2, unsigned long int n, int category)
{
	static struct msgcat *volatile cats;
	struct msgcat *p;
	struct __locale_struct *loc = CURRENT_LOCALE;
	struct __locale_map *lm;
	const char *dirname, *locname, *catname;
	size_t dirlen, loclen, catlen, domlen;

	if (!domainname) domainname = __gettextdomain();

	domlen = strlen(domainname);
	if (domlen > NAME_MAX) goto notrans;

	dirname = gettextdir(domainname, &dirlen);
	if (!dirname) goto notrans;

	switch (category) {
	case LC_MESSAGES:
		locname = loc->messages_name;
		if (!*locname) goto notrans;
		break;
	case LC_TIME:
	case LC_MONETARY:
	case LC_COLLATE:
		lm = loc->cat[category-2];
		if (!lm) goto notrans;
		locname = lm->name;
		break;
	default:
notrans:
		return (char *) ((n == 1) ? msgid1 : msgid2);
	}

	catname = catnames[category-2];
	catlen = catlens[category-2];
	loclen = strlen(locname);

	size_t namelen = dirlen+1 + loclen+1 + catlen+1 + domlen+3;
	char name[namelen+1], *s = name;

	memcpy(s, dirname, dirlen);
	s[dirlen] = '/';
	s += dirlen + 1;
	memcpy(s, locname, loclen);
	s[loclen] = '/';
	s += loclen + 1;
	memcpy(s, catname, catlen);
	s[catlen] = '/';
	s += catlen + 1;
	memcpy(s, domainname, domlen);
	s[domlen] = '.';
	s[domlen+1] = 'm';
	s[domlen+2] = 'o';
	s[domlen+3] = 0;

	for (p=cats; p; p=p->next)
		if (!strcmp(p->name, name))
			break;

	if (!p) {
		void *old_cats;
		size_t map_size;
		const void *map = __map_file(name, &map_size);
		if (!map) goto notrans;
		p = malloc(sizeof *p + namelen + 1);
		if (!p) {
			__munmap((void *)map, map_size);
			goto notrans;
		}
		p->map = map;
		p->map_size = map_size;
		memcpy(p->name, name, namelen+1);
		do {
			old_cats = cats;
			p->next = old_cats;
		} while (a_cas_p(&cats, old_cats, p) != old_cats);
	}

	const char *trans = __mo_lookup(p->map, p->map_size, msgid1);
	if (!trans) goto notrans;

	/* Non-plural-processing gettext forms pass a null pointer as
	 * msgid2 to request that dcngettext suppress plural processing. */
	if (!msgid2) return (char *)trans;

	if (!p->plural_rule) {
		const char *rule = "n!=1;";
		unsigned long np = 2;
		const char *r = __mo_lookup(p->map, p->map_size, "");
		char *z;
		while (r && strncmp(r, "Plural-Forms:", 13)) {
			z = strchr(r, '\n');
			r = z ? z+1 : 0;
		}
		if (r) {
			r += 13;
			while (isspace(*r)) r++;
			if (!strncmp(r, "nplurals=", 9)) {
				np = strtoul(r+9, &z, 10);
				r = z;
			}
			while (*r && *r != ';') r++;
			if (*r) {
				r++;
				while (isspace(*r)) r++;
				if (!strncmp(r, "plural=", 7))
					rule = r+7;
			}
		}
		a_store(&p->nplurals, np);
		a_cas_p(&p->plural_rule, 0, (void *)rule);
	}
	if (p->nplurals) {
		unsigned long plural = __pleval(p->plural_rule, n);
		if (plural > p->nplurals) goto notrans;
		while (plural--) {
			size_t rem = p->map_size - (trans - (char *)p->map);
			size_t l = strnlen(trans, rem);
			if (l+1 >= rem)
				goto notrans;
			trans += l+1;
		}
	}
	return (char *)trans;
}