Example #1
0
bstreamhandle
open_temp_file_stream(void)
{
	bstreamhandle h;
	char *t;
	int fd;

	str_errno = 0;

	t = (char *)get_tmp_name();

	if (strlcat(t, "/cdXXXXXX", PATH_MAX) >= PATH_MAX)
		return (NULL);

	fd = mkstemp(t);

	if (debug)
		(void) printf("temp is: %s length: %d\n", t, strlen(t));

	if (fd < 0)
		return (NULL);
	(void) unlink(t);

	h = (bstreamhandle)my_zalloc(sizeof (*h));
	h->bstr_fd = fd;
	h->bstr_read = file_stream_read;
	h->bstr_write = file_stream_write;
	h->bstr_close = file_stream_close;
	h->bstr_size = file_stream_size;
	h->bstr_rewind = file_stream_rewind;

	return (h);
}
Example #2
0
/*
 * check_avail_temp_space returns 0 if there is adequate space
 * in the temporary directory, or a non-zero error code if
 * something goes wrong
 */
int
check_avail_temp_space(size_t req_size)
{
	struct statvfs buf;
	u_longlong_t free_size = 0;

	if (statvfs(get_tmp_name(), &buf) < 0) {
		return (errno);
	}

	free_size = buf.f_bfree * buf.f_frsize;

	if (free_size <= req_size)
		return (ENOMEM);

	return (0);
}
Example #3
0
static void server_job(snd_pcm_direct_t *dmix)
{
	int ret, sck, i;
	int max = 128, current = 0;
	struct pollfd pfds[max + 1];

	server_job_dmix = dmix;
	/* don't allow to be killed */
	signal(SIGHUP, server_job_signal);
	signal(SIGQUIT, server_job_signal);
	signal(SIGTERM, server_job_signal);
	signal(SIGKILL, server_job_signal);
	/* close all files to free resources */
	i = sysconf(_SC_OPEN_MAX);
#ifdef SERVER_JOB_DEBUG
	while (--i >= 3) {
#else
	while (--i >= 0) {
#endif
		if (i != dmix->server_fd && i != dmix->hw_fd)
			close(i);
	}
	
	/* detach from parent */
	setsid();

	pfds[0].fd = dmix->server_fd;
	pfds[0].events = POLLIN | POLLERR | POLLHUP;

	server_printf("DIRECT SERVER STARTED\n");
	while (1) {
		ret = poll(pfds, current + 1, 500);
		server_printf("DIRECT SERVER: poll ret = %i, revents[0] = 0x%x, errno = %i\n", ret, pfds[0].revents, errno);
		if (ret < 0) {
			if (errno == EINTR)
				continue;
			/* some error */
			break;
		}
		if (ret == 0 || (pfds[0].revents & (POLLERR | POLLHUP))) {	/* timeout or error? */
			struct shmid_ds buf;
			snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
			if (shmctl(dmix->shmid, IPC_STAT, &buf) < 0) {
				_snd_pcm_direct_shm_discard(dmix);
				snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
				continue;
			}
			server_printf("DIRECT SERVER: nattch = %i\n", (int)buf.shm_nattch);
			if (buf.shm_nattch == 1)	/* server is the last user, exit */
				break;
			snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
			continue;
		}
		if (pfds[0].revents & POLLIN) {
			ret--;
			sck = accept(dmix->server_fd, 0, 0);
			if (sck >= 0) {
				server_printf("DIRECT SERVER: new connection %i\n", sck);
				if (current == max) {
					close(sck);
				} else {
					unsigned char buf = 'A';
					pfds[current+1].fd = sck;
					pfds[current+1].events = POLLIN | POLLERR | POLLHUP;
					_snd_send_fd(sck, &buf, 1, dmix->hw_fd);
					server_printf("DIRECT SERVER: fd sent ok\n");
					current++;
				}
			}
		}
		for (i = 0; i < current && ret > 0; i++) {
			struct pollfd *pfd = &pfds[i+1];
			unsigned char cmd;
			server_printf("client %i revents = 0x%x\n", pfd->fd, pfd->revents);
			if (pfd->revents & (POLLERR | POLLHUP)) {
				ret--;
				close(pfd->fd);
				pfd->fd = -1;
				continue;
			}
			if (!(pfd->revents & POLLIN))
				continue;
			ret--;
			if (read(pfd->fd, &cmd, 1) == 1)
				cmd = 0 /*process command */;
		}
		for (i = 0; i < current; i++) {
			if (pfds[i+1].fd < 0) {
				if (i + 1 != max)
					memcpy(&pfds[i+1], &pfds[i+2], sizeof(struct pollfd) * (max - i - 1));
				current--;
			}
		}
	}
	server_cleanup(dmix);
	server_printf("DIRECT SERVER EXIT\n");
#ifdef SERVER_JOB_DEBUG
	close(0); close(1); close(2);
#endif
	_exit(EXIT_SUCCESS);
}

int snd_pcm_direct_server_create(snd_pcm_direct_t *dmix)
{
	int ret;

	dmix->server_fd = -1;

	ret = get_tmp_name(dmix->shmptr->socket_name, sizeof(dmix->shmptr->socket_name));
	if (ret < 0)
		return ret;
	
	ret = make_local_socket(dmix->shmptr->socket_name, 1, dmix->ipc_perm, dmix->ipc_gid);
	if (ret < 0)
		return ret;
	dmix->server_fd = ret;

	ret = listen(dmix->server_fd, 4);
	if (ret < 0) {
		close(dmix->server_fd);
		return ret;
	}
	
	ret = fork();
	if (ret < 0) {
		close(dmix->server_fd);
		return ret;
	} else if (ret == 0) {
		ret = fork();
		if (ret == 0)
			server_job(dmix);
		_exit(EXIT_SUCCESS);
	} else {
		waitpid(ret, NULL, 0);
	}
	dmix->server_pid = ret;
	dmix->server = 1;
	return 0;
}