Example #1
0
void *xcalloc(size_t nmemb, size_t size)
{
	void *result;

	result = calloc(nmemb, size);
	if (result == NULL) {
		errprintf("xcalloc: Out of memory!\n");
		abort();
	}

#ifdef MEMORY_DEBUG
	add_to_memlist(result, nmemb*size);
#endif
	return result;
}
Example #2
0
char *xstrdup(const char *s)
{
	char *result;

	if (s == NULL) {
		errprintf("xstrdup: Cannot dup NULL string\n");
		abort();
	}

	result = strdup(s);
	if (result == NULL) {
		errprintf("xstrdup: Out of memory\n");
		abort();
	}

#ifdef MEMORY_DEBUG
	add_to_memlist(result, strlen(result)+1);
#endif

	return result;
}
Example #3
0
hobbitd_channel_t *setup_channel(enum msgchannels_t chnid, int role)
{
	key_t key;
	struct stat st;
	struct sembuf s;
	hobbitd_channel_t *newch;
	unsigned int bufsz;
	int flags = ((role == CHAN_MASTER) ? (IPC_CREAT | 0600) : 0);
	char *bbh = xgetenv("BBHOME");

	if ( (bbh == NULL) || (stat(bbh, &st) == -1) ) {
		errprintf("BBHOME not defined, or points to invalid directory - cannot continue.\n");
		return NULL;
	}

	bufsz = 1024*shbufsz(chnid);
	dbgprintf("Setting up %s channel (id=%d)\n", channelnames[chnid], chnid);

	dbgprintf("calling ftok('%s',%d)\n", bbh, chnid);
	key = ftok(bbh, chnid);
	if (key == -1) {
		errprintf("Could not generate shmem key based on %s: %s\n", bbh, strerror(errno));
		return NULL;
	}
	dbgprintf("ftok() returns: 0x%X\n", key);

	newch = (hobbitd_channel_t *)malloc(sizeof(hobbitd_channel_t));
	newch->seq = 0;
	newch->channelid = chnid;
	newch->msgcount = 0;
	newch->shmid = shmget(key, bufsz, flags);
	if (newch->shmid == -1) {
		errprintf("Could not get shm of size %d: %s\n", bufsz, strerror(errno));
		xfree(newch);
		return NULL;
	}
	dbgprintf("shmget() returns: 0x%X\n", newch->shmid);

	newch->channelbuf = (char *) shmat(newch->shmid, NULL, 0);
	if (newch->channelbuf == (char *)-1) {
		errprintf("Could not attach shm %s\n", strerror(errno));
		if (role == CHAN_MASTER) shmctl(newch->shmid, IPC_RMID, NULL);
		xfree(newch);
		return NULL;
	}

	newch->semid = semget(key, 3, flags);
	if (newch->semid == -1) {
		errprintf("Could not get sem: %s\n", strerror(errno));
		shmdt(newch->channelbuf);
		if (role == CHAN_MASTER) shmctl(newch->shmid, IPC_RMID, NULL);
		xfree(newch);
		return NULL;
	}

	if (role == CHAN_CLIENT) {
		/*
		 * Clients must register their presence.
		 * We use SEM_UNDO; so if the client crashes, it wont leave a stale count.
		 */
		s.sem_num = CLIENTCOUNT; s.sem_op = +1; s.sem_flg = SEM_UNDO;
		if (semop(newch->semid, &s, 1) == -1) {
			errprintf("Could not register presence: %s\n", strerror(errno));
			shmdt(newch->channelbuf);
			xfree(newch);
			return NULL;
		}
	}
	else if (role == CHAN_MASTER) {
		int n;

		n = semctl(newch->semid, CLIENTCOUNT, GETVAL);
		if (n > 0) {
			errprintf("FATAL: hobbitd sees clientcount %d, should be 0\nCheck for hanging hobbitd_channel processes or stale semaphores\n", n);
			shmdt(newch->channelbuf);
			shmctl(newch->shmid, IPC_RMID, NULL);
			semctl(newch->semid, 0, IPC_RMID);
			xfree(newch);
			return NULL;
		}
	}

#ifdef MEMORY_DEBUG
	add_to_memlist(newch->channelbuf, bufsz);
#endif
	return newch;
}