Exemplo n.º 1
0
int main()
{
	int * pipe_req = pipe_create();
	int * pipe_ans = pipe_create();
	pid_t fork_res = fork();
	
	switch(fork_res)
	{
		case -1:	printf("Stopped. Fork error.\n");
				break;
		case 0:		close(pipe_req[1]);
				close(pipe_ans[0]);
				run_server(pipe_req[0], pipe_ans[1]);
				close(pipe_req[0]);
				close(pipe_ans[1]);				
				break;
		default:	close(pipe_req[0]);
				close(pipe_ans[1]);
				run_client(pipe_req[1], pipe_ans[0]);
				close(pipe_req[1]);
				close(pipe_ans[0]);
				break;
	};

	pipe_delete(pipe_req);
	pipe_delete(pipe_ans);

	return 0;
}
Exemplo n.º 2
0
/* ARGSUSED */
int
sys_opipe(struct proc *p, void *v, register_t *retval)
{
	struct filedesc *fdp = p->p_fd;
	struct file *rf, *wf;
	struct pipe *rpipe, *wpipe;
	int fd, error;

	fdplock(fdp);

	rpipe = pool_get(&pipe_pool, PR_WAITOK);
	error = pipe_create(rpipe);
	if (error != 0)
		goto free1;
	wpipe = pool_get(&pipe_pool, PR_WAITOK);
	error = pipe_create(wpipe);
	if (error != 0)
		goto free2;

	error = falloc(p, &rf, &fd);
	if (error != 0)
		goto free2;
	rf->f_flag = FREAD | FWRITE;
	rf->f_type = DTYPE_PIPE;
	rf->f_data = rpipe;
	rf->f_ops = &pipeops;
	retval[0] = fd;

	error = falloc(p, &wf, &fd);
	if (error != 0)
		goto free3;
	wf->f_flag = FREAD | FWRITE;
	wf->f_type = DTYPE_PIPE;
	wf->f_data = wpipe;
	wf->f_ops = &pipeops;
	retval[1] = fd;

	rpipe->pipe_peer = wpipe;
	wpipe->pipe_peer = rpipe;

	FILE_SET_MATURE(rf);
	FILE_SET_MATURE(wf);

	fdpunlock(fdp);
	return (0);

free3:
	fdremove(fdp, retval[0]);
	closef(rf, p);
	rpipe = NULL;
free2:
	(void)pipeclose(wpipe);
free1:
	if (rpipe != NULL)
		(void)pipeclose(rpipe);
	fdpunlock(fdp);
	return (error);
}
Exemplo n.º 3
0
/*
 * The main program to "drive" the pipeline...
 */
int main (int argc, char *argv[])
{
    pipe_t my_pipe;
    long value, result;
    int status;
    char line[128];

    pipe_create (&my_pipe, 10);
    printf ("Enter integer values, or \"=\" for next result\n");

    while (1) {
        printf ("Data> ");
        if (fgets (line, sizeof (line), stdin) == NULL) exit (0);
        if (strlen (line) <= 1) continue;
        if (strlen (line) <= 2 && line[0] == '=') {
            if (pipe_result (&my_pipe, &result))
                printf ("Result is %ld\n", result);
            else
                printf ("Pipe is empty\n");
        } else {
            if (sscanf (line, "%ld", &value) < 1)
                fprintf (stderr, "Enter an integer value\n");
            else
                pipe_start (&my_pipe, value);
        }
    }
}
Exemplo n.º 4
0
// start_routine for thread A
void* threadA_routine (void *args) {

	// local variable
	char buf[BUFFER_SIZE];
	int rc;

	ThreadData_t * this_data = (ThreadData_t *)args;

	for (;;) {
	// block until pipe write semaphore reached
	sem_wait(this_data->pipeWrite_sem);

	printf("......................................\n");
	// read a line from data.txt
	// if eof reached, then thread A B C will stop
	rc = read_line(this_data->fp0, buf);
	if ((rc == 0) && (eof_reached == 1))
		terminateAll();

	// create a pipe 
	pipe_create(this_data->pipefd);

	// write the line to pipe
	pipe_in(this_data->pipefd, buf);

	printf("thread A completed\n");

	// post the pipe read signal
	sem_post(this_data->pipeRead_sem);

	}

}
Exemplo n.º 5
0
Arquivo: files.c Projeto: fixos/fixos
int sys_pipe2(int pipefd[2], int flags) {
	struct process *proc;
	int fdin, fdout;

	(void)flags;

	proc = process_get_current();
	for(fdin=0; fdin<PROCESS_MAX_FILE && proc->files[fdin] != NULL; fdin++);
	for(fdout=fdin+1; fdout<PROCESS_MAX_FILE && proc->files[fdout] != NULL; fdout++);

	if(fdin < PROCESS_MAX_FILE && fdout < PROCESS_MAX_FILE) {
		struct file *files[2];
		if(pipe_create(files) == 0) {
			proc->files[fdin] = files[0];
			pipefd[0] = fdin;
			proc->files[fdout] = files[1];
			pipefd[1] = fdout;

			return 0;
		}
		else {
			printk(LOG_ERR, "sys_pipe2: pipe creation failed\n");
		}
	}
	else {
		printk(LOG_WARNING, "sys_pipe2: no more file desc\n");
	}
	return -1;

}
Exemplo n.º 6
0
int main(int argc, char *argv[]) {
	pipe_t pipe;
	int value, result;
	char line[128];

	pipe_create(&pipe, 2);
	printf("Enter inter value, or '=' for next result\n");

	while (1) {
		printf("Data> ");
		E_TEST(NULL, fgets(line, sizeof(line), stdin));
		if (strlen(line) <= 1) continue;
		if (strlen(line) <= 2 && line[0] == '=') {
			if (pipe_result(&pipe, &result))
				printf("Result is %d\n", result);
			else
				printf("Pipe is empty\n");
		} else {
			if (sscanf(line, "%d", &value) < 1)
				fprintf(stderr, "Enter an integer value\n");
			else 
				pipe_start(&pipe, value);
		}
	}
	return 0 ;
}
Exemplo n.º 7
0
/**
 *  POSIX 1003.1b 6.1.1 Create an Inter-Process Channel
 */
int pipe(
  int filsdes[2]
)
{
  if (filsdes == NULL)
    rtems_set_errno_and_return_minus_one( EFAULT );

  return pipe_create(filsdes);
}
Exemplo n.º 8
0
static void worker_control_create (worker_t *worker)
{
    if (pipe_create (&worker->wakeup_fd[0]) < 0)
    {
        ERROR0 ("pipe failed, descriptor limit?");
        abort();
    }
    sock_set_blocking (worker->wakeup_fd[0], 0);
    sock_set_blocking (worker->wakeup_fd[1], 0);
}
Exemplo n.º 9
0
Arquivo: pipe.c Projeto: Ace-Tang/APUE
int main()
{
	pipe_t mypipe;
	long value, result;
	int status, len;
	char line[128];
	stage_t *stage, *stage_next;

	pipe_create(&mypipe, 10);
	printf("Enter integer value, or \"=\" for result, enter quit to leave\n");

	while(1)
	{
		printf("Data > ");
		if (fgets(line, sizeof line, stdin) == NULL || my_strcmp("quit", line))
			break;
		len = strlen(line);
		if (len <= 1)
			continue;
		if (len <= 2 && line[0] == '=')
		{
			if (pipe_result(&mypipe, &result))
				printf("result is %ld\n", result);
			else 
				printf("pipe is empty\n");
		}
		else
		{
			status = sscanf(line, "%ld", &value);
			if (status < 1)
				printf("please enter integer\n");
			else
				pipe_start(&mypipe, value);
		}
	}

	for (stage = mypipe.head; stage != NULL;)
	{
		stage_next = stage->next;
		free(stage);
		printf("free stage\n");
		stage = stage_next;
	}

	printf("end of pipe\n");
}
Exemplo n.º 10
0
struct l2_packet_data * l2_packet_init(
	const char *ifname, const u8 *own_addr, unsigned short protocol,
	void (*rx_callback)(void *ctx, const u8 *src_addr,
			    const u8 *buf, size_t len),
	void *rx_callback_ctx, int l2_hdr)
{
	struct l2_packet_data *l2;

	l2 = os_zalloc(sizeof(struct l2_packet_data));
	if (l2 == NULL)
		return NULL;
	os_strncpy(l2->ifname, ifname, sizeof(l2->ifname));
	l2->rx_callback = rx_callback;
	l2->rx_callback_ctx = rx_callback_ctx;
	l2->l2_hdr = l2_hdr;

	/*
	 * TODO: open connection for receiving frames
	 */
#if 1	//xhchen
	l2->write_fd = socket(PF_INET,SOCK_STREAM,0);
	diag_printf("Open socket(PF_INET, SOCK_STREAM), fd=%d\n", l2->write_fd);
	
	l2->fd = pipe_create(NULL);
	diag_printf("Open pipe for l2 socket, fd=%d\n", l2->fd);
	if (l2->fd < 0) {
		perror("open pipe for l2 socket");
		close(l2->write_fd);
		l2->write_fd = -1;
		l2->fd = -1;
	}
	
	g_l2_pipe = l2->fd;
	
	os_memcpy(l2->own_addr, own_addr, sizeof(l2->own_addr));
#else
	l2->fd = -1;
#endif
	eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL);

	return l2;
}
Exemplo n.º 11
0
void restart_child_process()
{
	close(pipe_handles[1]);
	do_del_conn(pipe_handles[2], 2);
	shmq_destroy ();

	shmq_create();
	pipe_create ();

	pid_t pid;

	if ((pid = fork ()) < 0)
		ERROR_LOG("fork child process, fail");
	//parent process
	else if (pid > 0) {
		close (pipe_handles[3]);
		close (pipe_handles[0]);
		do_add_conn (pipe_handles[2], PIPE_TYPE_FD, NULL);

	//child process
	} else {
		close (pipe_handles[1]);
		close (pipe_handles[2]);

		net_init (MAXFDS, pipe_handles[0]);

		if (handle_init () != 0)
			goto out;

		while (!stop || !handle_fini ())
			net_loop (1000, RCVBUFSZ, 0);

out:
		shmq_destroy ();
	}
}
Exemplo n.º 12
0
int
dopipe(struct proc *p, int *ufds, int flags)
{
	struct filedesc *fdp = p->p_fd;
	struct file *rf, *wf;
	struct pipe *rpipe, *wpipe = NULL;
	int fds[2], error;

	rpipe = pool_get(&pipe_pool, PR_WAITOK);
	error = pipe_create(rpipe);
	if (error != 0)
		goto free1;
	wpipe = pool_get(&pipe_pool, PR_WAITOK);
	error = pipe_create(wpipe);
	if (error != 0)
		goto free1;

	fdplock(fdp);

	error = falloc(p, &rf, &fds[0]);
	if (error != 0)
		goto free2;
	rf->f_flag = FREAD | FWRITE | (flags & FNONBLOCK);
	rf->f_type = DTYPE_PIPE;
	rf->f_data = rpipe;
	rf->f_ops = &pipeops;

	error = falloc(p, &wf, &fds[1]);
	if (error != 0)
		goto free3;
	wf->f_flag = FREAD | FWRITE | (flags & FNONBLOCK);
	wf->f_type = DTYPE_PIPE;
	wf->f_data = wpipe;
	wf->f_ops = &pipeops;

	if (flags & O_CLOEXEC) {
		fdp->fd_ofileflags[fds[0]] |= UF_EXCLOSE;
		fdp->fd_ofileflags[fds[1]] |= UF_EXCLOSE;
	}

	rpipe->pipe_peer = wpipe;
	wpipe->pipe_peer = rpipe;

	FILE_SET_MATURE(rf, p);
	FILE_SET_MATURE(wf, p);

	error = copyout(fds, ufds, sizeof(fds));
	if (error != 0) {
		fdrelease(p, fds[0]);
		fdrelease(p, fds[1]);
	}
	fdpunlock(fdp);
	return (error);

free3:
	fdremove(fdp, fds[0]);
	closef(rf, p);
	rpipe = NULL;
free2:
	fdpunlock(fdp);
free1:
	pipeclose(wpipe);
	pipeclose(rpipe);
	return (error);
}
Exemplo n.º 13
0
// public API
APIE process_spawn(ObjectID executable_id, ObjectID arguments_id,
                   ObjectID environment_id, ObjectID working_directory_id,
                   uint32_t uid, uint32_t gid, ObjectID stdin_id,
                   ObjectID stdout_id, ObjectID stderr_id, Session *session,
                   uint16_t object_create_flags, bool release_on_death,
                   ProcessStateChangedFunction state_changed, void *opaque,
                   ObjectID *id, Process **object) {
	int phase = 0;
	APIE error_code;
	String *executable;
	List *arguments;
	Array arguments_array;
	int i;
	char **item;
	List *environment;
	Array environment_array;
	String *working_directory;
	File *stdin;
	File *stdout;
	File *stderr;
	pid_t pid;
	int status_pipe[2];
	int sc_open_max;
	FILE *log_file;
	Process *process;

	// acquire and lock executable string object
	error_code = string_get_acquired_and_locked(executable_id, &executable);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	phase = 1;

	if (*executable->buffer == '\0') {
		error_code = API_E_INVALID_PARAMETER;

		log_warn("Cannot spawn child process using empty executable name");

		goto cleanup;
	}

	// lock arguments list object
	error_code = list_get_acquired_and_locked(arguments_id, OBJECT_TYPE_STRING,
	                                          &arguments);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	phase = 2;

	// prepare arguments array for execvpe
	if (array_create(&arguments_array, 1 + arguments->items.count + 1, sizeof(char *), true) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not create arguments array for spawning child process (executable: %s): %s (%d)",
		          executable->buffer, get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 3;

	item = array_append(&arguments_array);

	if (item == NULL) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not append to arguments array for spawning child process (executable: %s): %s (%d)",
		          executable->buffer, get_errno_name(errno), errno);

		goto cleanup;
	}

	*item = executable->buffer;

	for (i = 0; i < arguments->items.count; ++i) {
		item = array_append(&arguments_array);

		if (item == NULL) {
			error_code = api_get_error_code_from_errno();

			log_error("Could not append to arguments array for spawning child process (executable: %s): %s (%d)",
			          executable->buffer, get_errno_name(errno), errno);

			goto cleanup;
		}

		*item = (*(String **)array_get(&arguments->items, i))->buffer;
	}

	item = array_append(&arguments_array);

	if (item == NULL) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not append to arguments array for spawning child process (executable: %s): %s (%d)",
		          executable->buffer, get_errno_name(errno), errno);

		goto cleanup;
	}

	*item = NULL;

	// lock environment list object
	error_code = list_get_acquired_and_locked(environment_id, OBJECT_TYPE_STRING,
	                                          &environment);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	phase = 4;

	// prepare environment array for execvpe
	if (array_create(&environment_array, environment->items.count + 1, sizeof(char *), true) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not create environment array for spawning child process (executable: %s): %s (%d)",
		          executable->buffer, get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 5;

	for (i = 0; i < environment->items.count; ++i) {
		item = array_append(&environment_array);

		if (item == NULL) {
			error_code = api_get_error_code_from_errno();

			log_error("Could not append to environment array for spawning child process (executable: %s): %s (%d)",
			          executable->buffer, get_errno_name(errno), errno);

			goto cleanup;
		}

		// FIXME: if item is not <name>=<value>, but just <name> then use the parent <value>

		*item = (*(String **)array_get(&environment->items, i))->buffer;
	}

	item = array_append(&environment_array);

	if (item == NULL) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not append to environment array for spawning child process (executable: %s): %s (%d)",
		          executable->buffer, get_errno_name(errno), errno);

		goto cleanup;
	}

	*item = NULL;

	// acquire and lock working directory string object
	error_code = string_get_acquired_and_locked(working_directory_id, &working_directory);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	phase = 6;

	if (*working_directory->buffer == '\0') {
		error_code = API_E_INVALID_PARAMETER;

		log_warn("Cannot spawn child process (executable: %s) using empty working directory name",
		         executable->buffer);

		goto cleanup;
	}

	if (*working_directory->buffer != '/') {
		error_code = API_E_INVALID_PARAMETER;

		log_warn("Cannot spawn child process (executable: %s) using working directory with relative name '%s'",
		         executable->buffer, working_directory->buffer);

		goto cleanup;
	}

	// acquire stdin file object
	error_code = file_get_acquired(stdin_id, &stdin);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	phase = 7;

	// acquire stdout file object
	error_code = file_get_acquired(stdout_id, &stdout);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	phase = 8;

	// acquire stderr file object
	error_code = file_get_acquired(stderr_id, &stderr);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	phase = 9;

	// create status pipe
	if (pipe(status_pipe) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not create status pipe for spawning child process (executable: %s): %s (%d)",
		          executable->buffer, get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 10;

	// fork
	log_debug("Forking to spawn child process (executable: %s)", executable->buffer);

	error_code = process_fork(&pid);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	if (pid == 0) { // child
		close(status_pipe[0]);

		// change user and groups
		error_code = process_set_identity(uid, gid);

		if (error_code != API_E_SUCCESS) {
			goto child_error;
		}

		// change directory
		if (chdir(working_directory->buffer) < 0) {
			error_code = api_get_error_code_from_errno();

			log_error("Could not change directory to '%s' for child process (executable: %s, pid: %u): %s (%d)",
			          working_directory->buffer, executable->buffer, getpid(), get_errno_name(errno), errno);

			goto child_error;
		}

		// get open FD limit
		sc_open_max = sysconf(_SC_OPEN_MAX);

		if (sc_open_max < 0) {
			error_code = api_get_error_code_from_errno();

			log_error("Could not get SC_OPEN_MAX value: %s (%d)",
			          get_errno_name(errno), errno);

			goto child_error;
		}

		// redirect stdin
		if (dup2(file_get_read_handle(stdin), STDIN_FILENO) != STDIN_FILENO) {
			error_code = api_get_error_code_from_errno();

			log_error("Could not redirect stdin for child process (executable: %s, pid: %u): %s (%d)",
			          executable->buffer, getpid(), get_errno_name(errno), errno);

			goto child_error;
		}

		// redirect stdout
		if (dup2(file_get_write_handle(stdout), STDOUT_FILENO) != STDOUT_FILENO) {
			error_code = api_get_error_code_from_errno();

			log_error("Could not redirect stdout for child process (executable: %s, pid: %u): %s (%d)",
			          executable->buffer, getpid(), get_errno_name(errno), errno);

			goto child_error;
		}

		// stderr is the default log output in non-daemon mode. if this is
		// the case then disable the log output before redirecting stderr to
		// avoid polluting stderr for the new process
		log_file = log_get_file();

		if (log_file != NULL && fileno(log_file) == STDERR_FILENO) {
			log_debug("Disable logging to stderr for child process (executable: %s, pid: %u)",
			          executable->buffer, getpid());

			log_set_file(NULL);
		}

		// redirect stderr
		if (dup2(file_get_write_handle(stderr), STDERR_FILENO) != STDERR_FILENO) {
			error_code = api_get_error_code_from_errno();

			log_error("Could not redirect stderr for child process (executable: %s, pid: %u): %s (%d)",
			          executable->buffer, getpid(), get_errno_name(errno), errno);

			goto child_error;
		}

		// notify parent
		if (robust_write(status_pipe[1], &error_code, sizeof(error_code)) < 0) {
			error_code = api_get_error_code_from_errno();

			log_error("Could not write to status pipe for child process (executable: %s, pid: %u): %s (%d)",
			          executable->buffer, getpid(), get_errno_name(errno), errno);

			goto child_error;
		}

		// disable log output. if stderr was not the current log output then
		// the log file is still open at this point. the next step is to close
		// all remaining file descriptors. just for good measure disable the
		// log output beforehand
		log_set_file(NULL);

		// close all file descriptors except the std* ones
		for (i = STDERR_FILENO + 1; i < sc_open_max; ++i) {
			close(i);
		}

		// execvpe only returns in case of an error
		execvpe(executable->buffer, (char **)arguments_array.bytes, (char **)environment_array.bytes);

		if (errno == ENOENT) {
			_exit(PROCESS_E_DOES_NOT_EXIST);
		} else {
			_exit(PROCESS_E_CANNOT_EXECUTE);
		}

	child_error:
		// notify parent in all cases
		if (robust_write(status_pipe[1], &error_code, sizeof(error_code)) < 0) {
			log_error("Could not write to status pipe for child process (executable: %s, pid: %u): %s (%d)",
			          executable->buffer, getpid(), get_errno_name(errno), errno);
		}

		close(status_pipe[1]);

		_exit(PROCESS_E_INTERNAL_ERROR);
	}

	phase = 11;

	// wait for child to start successfully
	if (robust_read(status_pipe[0], &error_code, sizeof(error_code)) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not read from status pipe for child process (executable: %s, pid: %u): %s (%d)",
		          executable->buffer, pid, get_errno_name(errno), errno);

		goto cleanup;
	}

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	// create process object
	process = calloc(1, sizeof(Process));

	if (process == NULL) {
		error_code = API_E_NO_FREE_MEMORY;

		log_error("Could not allocate process object: %s (%d)",
		          get_errno_name(ENOMEM), ENOMEM);

		goto cleanup;
	}

	phase = 12;

	// setup process object
	process->executable = executable;
	process->arguments = arguments;
	process->environment = environment;
	process->working_directory = working_directory;
	process->uid = uid;
	process->gid = gid;
	process->pid = pid;
	process->stdin = stdin;
	process->stdout = stdout;
	process->stderr = stderr;
	process->release_on_death = release_on_death;
	process->state_changed = state_changed;
	process->opaque = opaque;
	process->state = PROCESS_STATE_RUNNING;
	process->timestamp = time(NULL);
	process->exit_code = 0; // invalid

	if (pipe_create(&process->state_change_pipe, 0) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not create state change pipe child process (executable: %s, pid: %u): %s (%d)",
		          executable->buffer, pid, get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 13;

	if (event_add_source(process->state_change_pipe.read_end, EVENT_SOURCE_TYPE_GENERIC,
	                     EVENT_READ, process_handle_state_change, process) < 0) {
		goto cleanup;
	}

	phase = 14;

	// create process object
	error_code = object_create(&process->base,
	                           OBJECT_TYPE_PROCESS,
	                           session,
	                           object_create_flags |
	                           OBJECT_CREATE_FLAG_INTERNAL,
	                           process_destroy,
	                           process_signature);

	if (error_code != API_E_SUCCESS) {
		goto cleanup;
	}

	phase = 15;

	if (id != NULL) {
		*id = process->base.id;
	}

	if (object != NULL) {
		*object = process;
	}

	// start thread to wait for child process state changes
	thread_create(&process->wait_thread, process_wait, process);

	log_debug("Spawned process object (id: %u, executable: %s, pid: %u)",
	          process->base.id, executable->buffer, process->pid);

	close(status_pipe[0]);
	close(status_pipe[1]);
	array_destroy(&arguments_array, NULL);
	array_destroy(&environment_array, NULL);

cleanup:
	switch (phase) { // no breaks, all cases fall through intentionally
	case 14:
		event_remove_source(process->state_change_pipe.read_end, EVENT_SOURCE_TYPE_GENERIC);

	case 13:
		pipe_destroy(&process->state_change_pipe);

	case 12:
		free(process);

	case 11:
		kill(pid, SIGKILL);

	case 10:
		close(status_pipe[0]);
		close(status_pipe[1]);

	case 9:
		file_release(stderr);

	case 8:
		file_release(stdout);

	case 7:
		file_release(stdin);

	case 6:
		string_unlock_and_release(working_directory);

	case 5:
		array_destroy(&environment_array, NULL);

	case 4:
		list_unlock_and_release(environment);

	case 3:
		array_destroy(&arguments_array, NULL);

	case 2:
		list_unlock_and_release(arguments);

	case 1:
		string_unlock_and_release(executable);

	default:
		break;
	}

	return phase == 15 ? API_E_SUCCESS : error_code;
}
Exemplo n.º 14
0
int iokit_init(void) {
	int phase = 0;
	Semaphore handshake;

	log_debug("Initializing IOKit subsystem");

	// create notification pipe
	if (pipe_create(&_notification_pipe) < 0) {
		log_error("Could not create notification pipe: %s (%d)",
		          get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 1;

	if (event_add_source(_notification_pipe.read_end, EVENT_SOURCE_TYPE_GENERIC,
	                     EVENT_READ, iokit_forward_notifications, NULL) < 0) {
		goto cleanup;
	}

	phase = 2;

	// create notification poll thread
	if (semaphore_create(&handshake) < 0) {
		log_error("Could not create handshake semaphore: %s (%d)",
		          get_errno_name(errno), errno);

		goto cleanup;
	}

	thread_create(&_poll_thread, iokit_poll_notifications, &handshake);

	semaphore_acquire(&handshake);
	semaphore_destroy(&handshake);

	phase = 3;

	if (!_running) {
		log_error("Could not start notification poll thread");

		goto cleanup;
	}

	phase = 4;

cleanup:
	switch (phase) { // no breaks, all cases fall through intentionally
	case 3:
		thread_destroy(&_poll_thread);

	case 2:
		event_remove_source(_notification_pipe.read_end, EVENT_SOURCE_TYPE_GENERIC);

	case 1:
		pipe_destroy(&_notification_pipe);

	default:
		break;
	}

	return phase == 4 ? 0 : -1;
}
Exemplo n.º 15
0
int event_init_platform(void) {
	int phase = 0;

	// create read set
	if (event_reserve_socket_set(&_socket_read_set, 32) < 0) {
		log_error("Could not create socket read set: %s (%d)",
		          get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 1;

	// create write set
	if (event_reserve_socket_set(&_socket_write_set, 32) < 0) {
		log_error("Could not create socket write set: %s (%d)",
		          get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 2;

	// create error set
	if (event_reserve_socket_set(&_socket_error_set, 32) < 0) {
		log_error("Could not create socket error set: %s (%d)",
		          get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 3;

	// create stop pipe
	if (pipe_create(&_stop_pipe, 0) < 0) {
		log_error("Could not create stop pipe: %s (%d)",
		          get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 4;

	if (event_add_source(_stop_pipe.read_end, EVENT_SOURCE_TYPE_GENERIC,
	                     EVENT_READ, NULL, NULL) < 0) {
		goto cleanup;
	}

	phase = 5;

	// create USB poll thread
	_usb_poll_running = false;
	_usb_poll_stuck = false;

	if (usbi_pipe(_usb_poll_suspend_pipe) < 0) {
		log_error("Could not create USB suspend pipe");

		goto cleanup;
	}

	phase = 6;

	if (pipe_create(&_usb_poll_ready_pipe, 0) < 0) {
		log_error("Could not create USB ready pipe: %s (%d)",
		          get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 7;

	if (array_create(&_usb_poll_pollfds, 32, sizeof(struct usbi_pollfd), true) < 0) {
		log_error("Could not create USB pollfd array: %s (%d)",
		          get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 8;

	if (semaphore_create(&_usb_poll_resume) < 0) {
		log_error("Could not create USB resume semaphore: %s (%d)",
		          get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 9;

	if (semaphore_create(&_usb_poll_suspend) < 0) {
		log_error("Could not create USB suspend semaphore: %s (%d)",
		          get_errno_name(errno), errno);

		goto cleanup;
	}

	phase = 10;

cleanup:
	switch (phase) { // no breaks, all cases fall through intentionally
	case 9:
		semaphore_destroy(&_usb_poll_suspend);

	case 8:
		semaphore_destroy(&_usb_poll_resume);

	case 7:
		pipe_destroy(&_usb_poll_ready_pipe);

	case 6:
		usbi_close(_usb_poll_suspend_pipe[0]);
		usbi_close(_usb_poll_suspend_pipe[1]);

	case 5:
		event_remove_source(_stop_pipe.read_end, EVENT_SOURCE_TYPE_GENERIC);

	case 4:
		pipe_destroy(&_stop_pipe);

	case 3:
		free(_socket_error_set);

	case 2:
		free(_socket_write_set);

	case 1:
		free(_socket_read_set);

	default:
		break;
	}

	return phase == 10 ? 0 : -1;
}
Exemplo n.º 16
0
/* ARGSUSED */
int
pipe(proc_t p, __unused struct pipe_args *uap, int32_t *retval)
{
	struct fileproc *rf, *wf;
	struct pipe *rpipe, *wpipe;
	lck_mtx_t   *pmtx;
	int fd, error;

	if ((pmtx = lck_mtx_alloc_init(pipe_mtx_grp, pipe_mtx_attr)) == NULL)
	        return (ENOMEM);
	
	rpipe = wpipe = NULL;
	if (pipe_create(&rpipe) || pipe_create(&wpipe)) {
	        error = ENFILE;
		goto freepipes;
	}
        /*
	 * allocate the space for the normal I/O direction up
	 * front... we'll delay the allocation for the other
	 * direction until a write actually occurs (most likely it won't)...
         */
	error = pipespace(rpipe, choose_pipespace(rpipe->pipe_buffer.size, 0));
        if (error)
	        goto freepipes;

	TAILQ_INIT(&rpipe->pipe_evlist);
	TAILQ_INIT(&wpipe->pipe_evlist);

	error = falloc(p, &rf, &fd, vfs_context_current());
	if (error) {
	        goto freepipes;
	}
	retval[0] = fd;

	/*
	 * for now we'll create half-duplex pipes(refer returns section above). 
	 * this is what we've always supported..
	 */
	rf->f_flag = FREAD;
	rf->f_data = (caddr_t)rpipe;
	rf->f_ops = &pipeops;

	error = falloc(p, &wf, &fd, vfs_context_current());
	if (error) {
		fp_free(p, retval[0], rf);
	        goto freepipes;
	}
	wf->f_flag = FWRITE;
	wf->f_data = (caddr_t)wpipe;
	wf->f_ops = &pipeops;

	rpipe->pipe_peer = wpipe;
	wpipe->pipe_peer = rpipe;
	/* both structures share the same mutex */
	rpipe->pipe_mtxp = wpipe->pipe_mtxp = pmtx; 

	retval[1] = fd;
#if CONFIG_MACF
	/*
	 * XXXXXXXX SHOULD NOT HOLD FILE_LOCK() XXXXXXXXXXXX
	 *
	 * struct pipe represents a pipe endpoint.  The MAC label is shared
	 * between the connected endpoints.  As a result mac_pipe_label_init() and
	 * mac_pipe_label_associate() should only be called on one of the endpoints
	 * after they have been connected.
	 */
	mac_pipe_label_init(rpipe);
	mac_pipe_label_associate(kauth_cred_get(), rpipe);
	wpipe->pipe_label = rpipe->pipe_label;
#endif
	proc_fdlock_spin(p);
	procfdtbl_releasefd(p, retval[0], NULL);
	procfdtbl_releasefd(p, retval[1], NULL);
	fp_drop(p, retval[0], rf, 1);
	fp_drop(p, retval[1], wf, 1);
	proc_fdunlock(p);


	return (0);

freepipes:
	pipeclose(rpipe); 
	pipeclose(wpipe); 
	lck_mtx_free(pmtx, pipe_mtx_grp);

	return (error);
}
Exemplo n.º 17
0
Arquivo: c_cmd.cpp Projeto: pouba/os
int parse_part(char* part, run_params* par) {
	char* cmd = (char*)malloc(sizeof(char) * MAX_CMD_LEN);
	int pos_part = 0, pos_cmd = 0;
	int c;
	int return_val;

	run_params* act_par = (run_params*)malloc(sizeof(run_params));
	memcpy_s(act_par, sizeof(run_params), par, sizeof(run_params));

	int in_q = 0;

	return_val = 0;
	while (true) {
		c = part[pos_part];

		if (c == '"') in_q = 1 - in_q;

		if ((c == CMD_PIPE_CHAR) && (!in_q)) {
			cmd[pos_cmd] = '\0';
			pos_part++;

			run_params* act_par_new = (run_params*)malloc(sizeof(run_params));
			memcpy_s(act_par_new, sizeof(run_params), act_par, sizeof(run_params));

			pipe_in* in_new = (pipe_in*)(malloc(sizeof pipe_in));
			pipe_out* out_new = (pipe_out*)(malloc(sizeof pipe_out));
			pipe_create(in_new, out_new, 1, 0);

			act_par_new->out = in_new;
			act_par->in = out_new;

			int ret = parse_cmd(cmd, act_par_new, par, 0);
			if (ret == 1) {
				return_val = 1;
				goto end;
			}
			pos_cmd = 0;
		}
		else if (c == '\0') {
			cmd[pos_cmd] = '\0';
			pos_part++;

			run_params* act_par_new = (run_params*)malloc(sizeof(run_params));
			memcpy_s(act_par_new, sizeof(run_params), act_par, sizeof(run_params));

			int ret = parse_cmd(cmd, act_par_new, par, 1);
			if (ret == 1) {
				return_val = 1;
				goto end;
			}
			return_val = 0;
			goto end;
		}
		else {
			cmd[pos_cmd] = part[pos_part];
			pos_cmd++;
			pos_part++;
		}

	}

	end: 
	free(cmd);
	return return_val;
}
Exemplo n.º 18
0
Arquivo: Main.cpp Projeto: pouba/os
int main()
{
	srand((int)time(NULL));

	node* root_dir = node_create("Computer", NULL, 1);
	node* root = node_create("C:", root_dir, 1);
	node* n1 = node_create("n1", root, 0);
	node* n2 = node_create("n2", root, 0);
	node* n3 = node_create("n3", root, 0);
	node* n4 = node_create("n4", root, 1);
	node* n5 = node_create("n5", root, 1);
	node* n5a = node_create("n5a", n5, 0);
	node* n5b = node_create("n5b", n5, 0);

	char* str = "n1 - aaaaaa\nbbbb\ncccc\nfskdhjs\ndsfj\niuyffj\n\n\nejrwehjr\n";
	n1->content = (char*)malloc(sizeof(char) * strlen(str)+1);
	memcpy(n1->content, str, strlen(str)+1);
	n1->content_len = strlen(n1->content);

	str = "";
	n2->content = (char*)malloc(sizeof(char) * strlen(str)+1);
	memcpy(n2->content, str, strlen(str)+1);
	n2->content_len = strlen(n2->content);

	str = "n3 - ,m,mkjhseur\nsjagfjhsdhj\n";
	n3->content = (char*)malloc(sizeof(char) * strlen(str)+1);
	memcpy(n3->content, str, strlen(str)+1);
	n3->content_len = strlen(n3->content);

	str = "n4 - yighjgjhgfyufyt\n";
	n4->content = (char*)malloc(sizeof(char) * strlen(str)+1);
	memcpy(n4->content, str, strlen(str) + 1);
	n4->content_len = strlen(n4->content);



	str = "n5a - 45455\n";
	n5a->content = (char*)malloc(sizeof(char) * strlen(str)+1);
	memcpy(n5a->content, str, strlen(str) + 1);
	n5a->content_len = strlen(n5a->content);

	str = "n5b - 1010\n";
	n5b->content = (char*)malloc(sizeof(char) * strlen(str)+1);
	memcpy(n5b->content, str, strlen(str) + 1);
	n5b->content_len = strlen(n5b->content);


	pipe_in* in_in = (pipe_in *)malloc(sizeof(pipe_in));
	pipe_out* in_out = (pipe_out *)malloc(sizeof(pipe_out));
	pipe_create(in_in, in_out, 0, 0, 1);

	pipe_in* out_in = (pipe_in *)malloc(sizeof(pipe_in));
	pipe_out* out_out = (pipe_out *)malloc(sizeof(pipe_out));
	pipe_create(out_in, out_out, 0, 0);

	pipe_in* err_in = (pipe_in *)malloc(sizeof(pipe_in));
	pipe_out* err_out = (pipe_out *)malloc(sizeof(pipe_out));
	pipe_create(err_in, err_out, 0, 0);


	HANDLE h_in = std_reader_run(in_in);
	HANDLE h_out = std_writter_run(out_out);
	HANDLE h_err = std_writter_run(err_out);

	run_params par;
	par.cmd_name = "cmd\0";
	par.in = in_out;
	par.out = out_in;
	par.err = err_in;
	par.start_node = root;
	par.root_node = root;
	par.args = (char**)malloc(sizeof(char*) * 1);
	par.args[0] = "-main";
	par.argc = 1;
	par.secret_params = 1;

	c_run( (LPTHREAD_START_ROUTINE) c_cmd_run, &par, 0);

	WaitForSingleObject(h_out, INFINITE);
	WaitForSingleObject(h_err, INFINITE);
	TerminateThread(h_in, 0); // needs to be terminated, otherwise would wait for input forever

	free(par.args);

    return 0;
}
Exemplo n.º 19
0
Arquivo: c_cmd.cpp Projeto: pouba/os
run_params* make_params(run_params* parent_par, char* in, char* out, char* err, int app, char** args, int argc, char* cmd_name) {
	run_params* nParams = (run_params*)malloc(sizeof(run_params));

	nParams->in = parent_par->in;
	nParams->out = parent_par->out;
	nParams->err = parent_par->err;

	nParams->start_node = parent_par->start_node;
	nParams->root_node = parent_par->root_node;
	nParams->cmd_name = cmd_name;

	nParams->argc = argc;
	nParams->args = args;
	nParams->secret_params = 0;

	if (in[0] != '\0') {
		node* node_in = node_get(in, nParams->root_node, nParams->start_node);
		if (node_in == NULL) {
			pipe_write_s(parent_par->err, "File not found!\n");
			return NULL;
		}
		if (node_in->directory) {
			pipe_write_s(parent_par->err, "Target is a directory!\n");
			return NULL;
		}
		// open file
		if (node_try_lock(node_in)) {
			pipe_in* p_in = (pipe_in *)malloc(sizeof(pipe_in));
			pipe_out* p_out = (pipe_out *)malloc(sizeof(pipe_out));
			pipe_create(p_in, p_out, 1, 1);
			file_reader_run(p_in, node_in);
			nParams->in = p_out;
		}
		else {
			pipe_write_s(parent_par->err, "Can not open the file.\n");
			return NULL;
		}
	}
	if (out[0] != '\0') {
		node* node_out = node_get(out, nParams->root_node, nParams->start_node);
		if (node_out == NULL) {
			node_out = node_create(out, nParams->start_node, 0);
			if (node_out == NULL) {
				pipe_write_s(parent_par->err, "Could not create the file!\n");
				return NULL;
			}
		}
		if (node_out->directory) {
			pipe_write_s(parent_par->err, "Target is a directory!\n");
			return NULL;
		}
		// open file
		if (node_try_lock(node_out)) {
			pipe_in* p_in = (pipe_in *)malloc(sizeof(pipe_in));
			pipe_out* p_out = (pipe_out *)malloc(sizeof(pipe_out));
			pipe_create(p_in, p_out, 1, 1);
			file_writter_run(p_out, node_out, app);
			nParams->out = p_in;
		}
		else {
			pipe_write_s(parent_par->err, "Can not open the file.\n");
		}
	}
	if (err[0] != '\0') {
		node* node_err = node_get(err, nParams->root_node, nParams->start_node);
		if (node_err == NULL) {
			node_err = node_create(err, nParams->start_node, 0);
			if (node_err == NULL) {
				pipe_write_s(parent_par->err, "Could not create the file!\n");
				return NULL;
			}
		}
		if (node_err->directory) {
			pipe_write_s(parent_par->err, "Target is a directory!\n");
			return NULL;
		}
		// open file
		if (node_try_lock(node_err)) {
			pipe_in* p_in = (pipe_in *)malloc(sizeof(pipe_in));
			pipe_out* p_out = (pipe_out *)malloc(sizeof(pipe_out));
			pipe_create(p_in, p_out, 1, 1);
			file_writter_run(p_out, node_err, 0);
			nParams->err = p_in;
		}
		else {
			pipe_write_s(parent_par->err, "Can not open the file.\n");
		}
		
	}


	return nParams;
}
Exemplo n.º 20
0
static error_t
open_hook (struct trivfs_peropen *po)
{
    error_t err = 0;
    int flags = po->openmodes;

    if (flags & (O_READ | O_WRITE))
    {
        mutex_lock (&active_fifo_lock);

        /* Wait until the active fifo has changed so that CONDITION is true.  */
#define WAIT(condition, noblock_err)					      \
  while (!err && !(condition))						      \
    {									      \
      if (flags & O_NONBLOCK)						      \
	{								      \
	  err = noblock_err;						      \
	  break;							      \
	}								      \
      else if (hurd_condition_wait (&active_fifo_changed, &active_fifo_lock)) \
	err = EINTR;							      \
    }

        if (flags & O_READ)
            /* When opening for read, what we do depends on what mode this server
               is running in.  The default (if ONE_READER is set) is to only
               allow one reader at a time, with additional opens for read
               blocking here until the old reader goes away; otherwise, we allow
               multiple readers.  If WAIT_FOR_WRITER is true, then once we've
               created a fifo, we also block until someone opens it for writing;
               otherwise, the first read will block until someone writes
               something.  */
        {
            if (one_reader)
                /* Wait until there isn't any active fifo, so we can make one. */
                WAIT (!active_fifo || !active_fifo->readers, EWOULDBLOCK);

            if (!err && active_fifo == NULL)
                /* No other readers, and indeed, no fifo; make one.  */
            {
                err = pipe_create (fifo_pipe_class, &active_fifo);
                if (! err)
                    active_fifo->flags &= ~PIPE_BROKEN; /* Avoid immediate EOF. */
            }
            if (!err)
            {
                pipe_add_reader (active_fifo);
                condition_broadcast (&active_fifo_changed);
                /* We'll unlock ACTIVE_FIFO_LOCK below; the writer code won't
                make us block because we've ensured that there's a reader
                 for it.  */

                if (wait_for_writer)
                    /* Wait until there's a writer.  */
                {
                    WAIT (active_fifo->writers, 0);
                    if (err)
                        /* Back out the new pipe creation.  */
                    {
                        pipe_remove_reader (active_fifo);
                        active_fifo = NULL;
                        condition_broadcast (&active_fifo_changed);
                    }
                }
            }
        }

        if (!err && (flags & O_WRITE))
            /* Open the active_fifo for writing.  If WAIT_FOR_READER is true,
               then we block until there's someone to read what we wrote,
               otherwise, if there's no fifo, we create one, which we just write
               into and leave it for someone to read later.  */
        {
            if (wait_for_reader)
                /* Wait until there's a fifo to write to.  */
                WAIT (active_fifo && active_fifo->readers, ENXIO);
            if (!err && active_fifo == NULL)
                /* No other readers, and indeed, no fifo; make one.  */
            {
                err = pipe_create (fifo_pipe_class, &active_fifo);
                if (!err)
                    active_fifo->flags &= ~PIPE_BROKEN;
            }
            if (!err)
            {
                pipe_add_writer (active_fifo);
                condition_broadcast (&active_fifo_changed);
            }
        }

        po->hook = active_fifo;

        mutex_unlock (&active_fifo_lock);
    }

    return err;
}
Exemplo n.º 21
0
// NOTE: this function needs to call RegisterServiceCtrlHandlerEx and
// SetServiceStatus in all circumstances if brickd is running as service
static int generic_main(bool log_to_file, bool debug, bool libusb_debug) {
	int exit_code = EXIT_FAILURE;
	const char *mutex_name = "Global\\Tinkerforge-Brick-Daemon-Single-Instance";
	HANDLE mutex_handle = NULL;
	bool fatal_error = false;
	DWORD service_exit_code = NO_ERROR;
	int rc;
	char filename[1024];
	int i;
	FILE *log_file = NULL;
	WSADATA wsa_data;
	DEV_BROADCAST_DEVICEINTERFACE notification_filter;
	HDEVNOTIFY notification_handle;

	mutex_handle = OpenMutex(SYNCHRONIZE, FALSE, mutex_name);

	if (mutex_handle == NULL) {
		rc = GetLastError();

		if (rc == ERROR_ACCESS_DENIED) {
			rc = service_is_running();

			if (rc < 0) {
				fatal_error = true;
				// FIXME: set service_exit_code

				goto error_mutex;
			} else if (rc) {
				fatal_error = true;
				service_exit_code = ERROR_SERVICE_ALREADY_RUNNING;

				log_error("Could not start as %s, another instance is already running as service",
				          _run_as_service ? "service" : "console application");

				goto error_mutex;
			}
		}

		if (rc != ERROR_FILE_NOT_FOUND) {
			fatal_error = true;
			// FIXME: set service_exit_code
			rc += ERRNO_WINAPI_OFFSET;

			log_error("Could not open single instance mutex: %s (%d)",
			          get_errno_name(rc), rc);

			goto error_mutex;
		}
	}

	if (mutex_handle != NULL) {
		fatal_error = true;
		service_exit_code = ERROR_SERVICE_ALREADY_RUNNING;

		log_error("Could not start as %s, another instance is already running",
		          _run_as_service ? "service" : "console application");

		goto error_mutex;
	}

	mutex_handle = CreateMutex(NULL, FALSE, mutex_name);

	if (mutex_handle == NULL) {
		fatal_error = true;
		// FIXME: set service_exit_code
		rc = ERRNO_WINAPI_OFFSET + GetLastError();

		log_error("Could not create single instance mutex: %s (%d)",
		          get_errno_name(rc), rc);

		goto error_mutex;
	}

	if (log_to_file) {
		if (GetModuleFileName(NULL, filename, sizeof(filename)) == 0) {
			rc = ERRNO_WINAPI_OFFSET + GetLastError();

			log_warn("Could not get module file name: %s (%d)",
			         get_errno_name(rc), rc);
		} else {
			i = strlen(filename);

			if (i < 4) {
				log_warn("Module file name '%s' is too short", filename);
			} else {
				filename[i - 3] = '\0';
				string_append(filename, "log", sizeof(filename));

				log_file = fopen(filename, "a+");

				if (log_file == NULL) {
					log_warn("Could not open log file '%s'", filename);
				} else {
					printf("Logging to '%s'\n", filename);

					log_set_file(log_file);
				}
			}
		}
	} else if (_run_as_service) {
		log_set_file(NULL);
	}

	if (!_run_as_service &&
	    !SetConsoleCtrlHandler(console_ctrl_handler, TRUE)) {
		rc = ERRNO_WINAPI_OFFSET + GetLastError();

		log_warn("Could not set console control handler: %s (%d)",
		         get_errno_name(rc), rc);
	}

	log_set_debug_override(debug);

	log_set_level(LOG_CATEGORY_EVENT, config_get_option("log_level.event")->value.log_level);
	log_set_level(LOG_CATEGORY_USB, config_get_option("log_level.usb")->value.log_level);
	log_set_level(LOG_CATEGORY_NETWORK, config_get_option("log_level.network")->value.log_level);
	log_set_level(LOG_CATEGORY_HOTPLUG, config_get_option("log_level.hotplug")->value.log_level);
	log_set_level(LOG_CATEGORY_HARDWARE, config_get_option("log_level.hardware")->value.log_level);
	log_set_level(LOG_CATEGORY_WEBSOCKET, config_get_option("log_level.websocket")->value.log_level);
	log_set_level(LOG_CATEGORY_OTHER, config_get_option("log_level.other")->value.log_level);

	if (config_has_error()) {
		log_error("Error(s) in config file '%s', run with --check-config option for details",
		          _config_filename);

		fatal_error = true;

		goto error_config;
	}

	if (_run_as_service) {
		log_info("Brick Daemon %s started (as service)", VERSION_STRING);
	} else {
		log_info("Brick Daemon %s started", VERSION_STRING);
	}

	if (config_has_warning()) {
		log_warn("Warning(s) in config file '%s', run with --check-config option for details",
		         _config_filename);
	}

	// initialize service status
error_config:
error_mutex:
	if (_run_as_service) {
		if (service_init(service_control_handler) < 0) {
			// FIXME: set service_exit_code
			goto error;
		}

		if (!fatal_error) {
			// service is starting
			service_set_status(SERVICE_START_PENDING, NO_ERROR);
		}
	}

	if (fatal_error) {
		goto error;
	}

	// initialize WinSock2
	if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0) {
		// FIXME: set service_exit_code
		rc = ERRNO_WINAPI_OFFSET + WSAGetLastError();

		log_error("Could not initialize Windows Sockets 2.2: %s (%d)",
		          get_errno_name(rc), rc);

		goto error_event;
	}

	if (event_init() < 0) {
		// FIXME: set service_exit_code
		goto error_event;
	}

	if (hardware_init() < 0) {
		// FIXME: set service_exit_code
		goto error_hardware;
	}

	if (usb_init(libusb_debug) < 0) {
		// FIXME: set service_exit_code
		goto error_usb;
	}

	// create notification pipe
	if (pipe_create(&_notification_pipe) < 0) {
		// FIXME: set service_exit_code

		log_error("Could not create notification pipe: %s (%d)",
		          get_errno_name(errno), errno);

		goto error_pipe;
	}

	if (event_add_source(_notification_pipe.read_end, EVENT_SOURCE_TYPE_GENERIC,
	                     EVENT_READ, forward_notifications, NULL) < 0) {
		// FIXME: set service_exit_code
		goto error_pipe_add;
	}

	// register device notification
	ZeroMemory(&notification_filter, sizeof(notification_filter));

	notification_filter.dbcc_size = sizeof(notification_filter);
	notification_filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
	notification_filter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;

	if (_run_as_service) {
		notification_handle = RegisterDeviceNotification((HANDLE)service_get_status_handle(),
		                                                 &notification_filter,
		                                                 DEVICE_NOTIFY_SERVICE_HANDLE);
	} else {
		if (message_pump_start() < 0) {
			// FIXME: set service_exit_code
			goto error_pipe_add;
		}

		notification_handle = RegisterDeviceNotification(_message_pump_hwnd,
		                                                 &notification_filter,
		                                                 DEVICE_NOTIFY_WINDOW_HANDLE);
	}

	if (notification_handle == NULL) {
		// FIXME: set service_exit_code
		rc = ERRNO_WINAPI_OFFSET + GetLastError();

		log_error("Could not register for device notification: %s (%d)",
		          get_errno_name(rc), rc);

		goto error_notification;
	}

	if (network_init() < 0) {
		// FIXME: set service_exit_code
		goto error_network;
	}

	// running
	if (_run_as_service) {
		service_set_status(SERVICE_RUNNING, NO_ERROR);
	}

	if (event_run(network_cleanup_clients_and_zombies) < 0) {
		// FIXME: set service_exit_code
		goto error_run;
	}

	exit_code = EXIT_SUCCESS;

error_run:
	network_exit();

error_network:
	UnregisterDeviceNotification(notification_handle);

error_notification:
	if (!_run_as_service) {
		message_pump_stop();
	}

	event_remove_source(_notification_pipe.read_end, EVENT_SOURCE_TYPE_GENERIC);

error_pipe_add:
	pipe_destroy(&_notification_pipe);

error_pipe:
	usb_exit();

error_usb:
	hardware_exit();

error_hardware:
	event_exit();

error_event:
	log_info("Brick Daemon %s stopped", VERSION_STRING);

error:
	if (!_run_as_service) {
		// unregister the console handler before exiting the log. otherwise a
		// control event might be send to the control handler after the log
		// is not available anymore and the control handler tries to write a
		// log messages triggering a crash. this situation could easily be
		// created by clicking the close button of the command prompt window
		// while the getch call is waiting for the user to press a key.
		SetConsoleCtrlHandler(console_ctrl_handler, FALSE);
	}

	log_exit();

	config_exit();

	if (_run_as_service) {
		// because the service process can be terminated at any time after
		// entering SERVICE_STOPPED state the mutex is closed beforehand,
		// even though this creates a tiny time window in which the service
		// is still running but the mutex is not held anymore
		if (mutex_handle != NULL) {
			CloseHandle(mutex_handle);
		}

		// service is now stopped
		service_set_status(SERVICE_STOPPED, service_exit_code);
	} else {
		if (_pause_before_exit) {
			printf("Press any key to exit...\n");
			getch();
		}

		if (mutex_handle != NULL) {
			CloseHandle(mutex_handle);
		}
	}

	return exit_code;
}
Exemplo n.º 22
0
// simple exec (no pipe included, but for piping OUTs)
int fork_and_exec_pipe(int connfd, char **cmd, int p_n) {

    // if(strcmp(cmd[0], "cat")==0 && cmd[1]==NULL)    return SKIP_SHIFT;

    // create pipe
    int client_id = clients_get_id_from_socket(connfd);
    int *fd = pipe_create(client_id, p_n);

    pid_t pid;
    pid = fork();

    if(pid<0) {                     // if error

        fprintf(stderr, "Fork failed\n");
        exit(EXIT_FAILURE);

    } else if (pid ==0) {           // if child

        // output old_pipe content if exist
        int *op = get_old_pipe(client_id);
        if(op!=NULL) {

            memset(pipe_buff, 0, sizeof(pipe_buff)); 

            int count;
            if( (count = read(op[READ], pipe_buff, SIZE_PIPE_BUFF)) < 0 ) {
                fprintf(stderr, "read pipe connent error: %s\n", strerror(errno));
            }

            if(close(op[READ]) < 0) {
                fprintf(stderr, "pipe close error (old_pipe in): %s\n", strerror(errno));
                exit(EXIT_FAILURE);
            }

            if(DEBUG)   debug_print_pipe_cat_content(count);

            if( write(fd[WRITE], pipe_buff, count) < 0 ) {
                fprintf(stderr, "write pipe connent error: %s\n", strerror(errno));
            }

        }

        // redirect STDOUT to pipe
        if(close(fd[READ]) < 0) {
            fprintf(stderr, "pipe close error (fd in): %s\n", strerror(errno));
            exit(EXIT_FAILURE);
        }
        dup2(fd[WRITE], STDOUT_FILENO);
        if(!DEBUG)  dup2(connfd, STDERR_FILENO);

        // DEBUG
        if(DEBUG)   debug_print_pipe_map(client_id);

        // redirect STDIN to pipe_map[0][READ]
        int fd_in = pipe_get(client_id);
        if(fd_in)   dup2(fd_in, STDIN_FILENO);

        if(cmd[0][0]=='/' || execvp(cmd[0], cmd)<0) {
            fprintf(stderr, "Unknown command: [%s].\n", cmd[0]);
            fprintf(stdout, "Unknown command: [%s].\n", cmd[0]);
            fflush(stderr);
            close(fd[WRITE]);
            exit(EXIT_FAILURE);
        }

        exit(EXIT_SUCCESS);

    } else {                        // if parent

        int return_val;    
        waitpid(pid, &return_val, 0);
        if( close(fd[WRITE]) < 0 ) {
            fprintf(stderr, "pipe close error (fd out): %s\n", strerror(errno));
            exit(EXIT_FAILURE);
        }
        if(WEXITSTATUS(return_val) == EXIT_FAILURE) return EXIT_FAILURE;

    }

    return EXIT_SUCCESS;

}
Exemplo n.º 23
0
/* ARGSUSED */
int
sys_pipe(struct proc *p, void *v, register_t *retval)
{
	struct sys_pipe_args /* {
		syscallarg(int *) fdp;
	} */ *uap = v;
	struct filedesc *fdp = p->p_fd;
	struct file *rf, *wf;
	struct pipe *rpipe, *wpipe = NULL;
	int fds[2], error;

	rpipe = pool_get(&pipe_pool, PR_WAITOK);
	error = pipe_create(rpipe);
	if (error != 0)
		goto free1;
	wpipe = pool_get(&pipe_pool, PR_WAITOK);
	error = pipe_create(wpipe);
	if (error != 0)
		goto free1;

	fdplock(fdp);

	error = falloc(p, &rf, &fds[0]);
	if (error != 0)
		goto free2;
	rf->f_flag = FREAD | FWRITE;
	rf->f_type = DTYPE_PIPE;
	rf->f_data = rpipe;
	rf->f_ops = &pipeops;

	error = falloc(p, &wf, &fds[1]);
	if (error != 0)
		goto free3;
	wf->f_flag = FREAD | FWRITE;
	wf->f_type = DTYPE_PIPE;
	wf->f_data = wpipe;
	wf->f_ops = &pipeops;

	rpipe->pipe_peer = wpipe;
	wpipe->pipe_peer = rpipe;

	FILE_SET_MATURE(rf, p);
	FILE_SET_MATURE(wf, p);

	error = copyout(fds, SCARG(uap, fdp), sizeof(fds));
	if (error != 0) {
		fdrelease(p, fds[0]);
		fdrelease(p, fds[1]);
	}
	fdpunlock(fdp);
	return (error);

free3:
	fdremove(fdp, fds[0]);
	closef(rf, p);
	rpipe = NULL;
free2:
	fdpunlock(fdp);
free1:
	pipeclose(wpipe);
	pipeclose(rpipe);
	return (error);
}
Exemplo n.º 24
0
// NOTE: this function needs to call RegisterServiceCtrlHandlerEx and
// SetServiceStatus in all circumstances if brickd is running as service
static int generic_main(int log_to_file, int debug) {
	int exit_code = EXIT_FAILURE;
	const char *mutex_name = "Global\\Tinkerforge-Brick-Daemon-Single-Instance";
	HANDLE mutex_handle = NULL;
	int mutex_error = 0;
	DWORD service_exit_code = NO_ERROR;
	int rc;
	char filename[1024];
	int i;
	FILE *logfile = NULL;
	WSADATA wsa_data;
	DEV_BROADCAST_DEVICEINTERFACE notification_filter;
	HDEVNOTIFY notification_handle;

	mutex_handle = OpenMutex(SYNCHRONIZE, FALSE, mutex_name);

	if (mutex_handle == NULL) {
		rc = GetLastError();

		if (rc == ERROR_ACCESS_DENIED) {
			rc = service_is_running();

			if (rc < 0) {
				mutex_error = 1;
				// FIXME: set service_exit_code

				goto error_mutex;
			} else if (rc) {
				mutex_error = 1;
				service_exit_code = ERROR_SERVICE_ALREADY_RUNNING;

				log_error("Could not start as %s, another instance is already running as service",
				          _run_as_service ? "service" : "console application");

				goto error_mutex;
			}
		}

		if (rc != ERROR_FILE_NOT_FOUND) {
			mutex_error = 1;
			// FIXME: set service_exit_code
			rc += ERRNO_WINAPI_OFFSET;

			log_error("Could not open single instance mutex: %s (%d)",
			          get_errno_name(rc), rc);

			goto error_mutex;
		}
	}

	if (mutex_handle != NULL) {
		mutex_error = 1;
		service_exit_code = ERROR_SERVICE_ALREADY_RUNNING;

		log_error("Could not start as %s, another instance is already running",
		          _run_as_service ? "service" : "console application");

		goto error_mutex;
	}

	mutex_handle = CreateMutex(NULL, FALSE, mutex_name);

	if (mutex_handle == NULL) {
		mutex_error = 1;
		// FIXME: set service_exit_code
		rc = ERRNO_WINAPI_OFFSET + GetLastError();

		log_error("Could not create single instance mutex: %s (%d)",
		          get_errno_name(rc), rc);

		goto error_mutex;
	}

	if (!_run_as_service &&
	    !SetConsoleCtrlHandler(console_ctrl_handler, TRUE)) {
		rc = ERRNO_WINAPI_OFFSET + GetLastError();

		log_warn("Could not set console control handler: %s (%d)",
		          get_errno_name(rc), rc);
	}

	if (log_to_file) {
		if (GetModuleFileName(NULL, filename, sizeof(filename)) == 0) {
			rc = ERRNO_WINAPI_OFFSET + GetLastError();

			log_warn("Could not get module file name: %s (%d)",
			         get_errno_name(rc), rc);
		} else {
			i = strlen(filename);

			if (i < 4) {
				log_warn("Module file name '%s' is too short", filename);
			} else {
				strcpy(filename + i - 3, "log");

				logfile = fopen(filename, "a+");

				if (logfile == NULL) {
					log_warn("Could not open logfile '%s'", filename);
				} else {
					log_set_file(logfile);
				}
			}
		}
	}

	if (debug) {
		log_set_level(LOG_CATEGORY_EVENT, LOG_LEVEL_DEBUG);
		log_set_level(LOG_CATEGORY_USB, LOG_LEVEL_DEBUG);
		log_set_level(LOG_CATEGORY_NETWORK, LOG_LEVEL_DEBUG);
		log_set_level(LOG_CATEGORY_HOTPLUG, LOG_LEVEL_DEBUG);
		log_set_level(LOG_CATEGORY_OTHER, LOG_LEVEL_DEBUG);
	} else {
		log_set_level(LOG_CATEGORY_EVENT, config_get_log_level(LOG_CATEGORY_EVENT));
		log_set_level(LOG_CATEGORY_USB, config_get_log_level(LOG_CATEGORY_USB));
		log_set_level(LOG_CATEGORY_NETWORK, config_get_log_level(LOG_CATEGORY_NETWORK));
		log_set_level(LOG_CATEGORY_HOTPLUG, config_get_log_level(LOG_CATEGORY_HOTPLUG));
		log_set_level(LOG_CATEGORY_OTHER, config_get_log_level(LOG_CATEGORY_OTHER));
	}

	if (_run_as_service) {
		log_info("Brick Daemon %s started (as service)", VERSION_STRING);
	} else {
		log_info("Brick Daemon %s started", VERSION_STRING);
	}

	if (config_has_error()) {
		log_warn("Errors found in config file '%s', run with --check-config option for details",
		         _config_filename);
	}

	// initialize service status
error_mutex:
	if (_run_as_service) {
		if (service_init(service_control_handler) < 0) {
			// FIXME: set service_exit_code
			goto error;
		}

		if (!mutex_error) {
			// service is starting
			service_set_status(SERVICE_START_PENDING, NO_ERROR);
		}
	}

	if (mutex_error) {
		goto error;
	}

	// initialize WinSock2
	if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0) {
		// FIXME: set service_exit_code
		rc = ERRNO_WINAPI_OFFSET + WSAGetLastError();

		log_error("Could not initialize Windows Sockets 2.2: %s (%d)",
		          get_errno_name(rc), rc);

		goto error_event;
	}

	if (event_init() < 0) {
		// FIXME: set service_exit_code
		goto error_event;
	}

	if (usb_init() < 0) {
		// FIXME: set service_exit_code
		goto error_usb;
	}

	// create notification pipe
	if (pipe_create(_notification_pipe) < 0) {
		// FIXME: set service_exit_code

		log_error("Could not create notification pipe: %s (%d)",
		          get_errno_name(errno), errno);

		goto error_pipe;
	}

	if (event_add_source(_notification_pipe[0], EVENT_SOURCE_TYPE_GENERIC,
	                     EVENT_READ, forward_notifications, NULL) < 0) {
		// FIXME: set service_exit_code
		goto error_pipe_add;
	}

	// register device notification
	ZeroMemory(&notification_filter, sizeof(notification_filter));

	notification_filter.dbcc_size = sizeof(notification_filter);
	notification_filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
	notification_filter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;

	if (_run_as_service) {
		notification_handle = RegisterDeviceNotification((HANDLE)service_get_status_handle(),
		                                                 &notification_filter,
		                                                 DEVICE_NOTIFY_SERVICE_HANDLE);
	} else {
		if (message_pump_start() < 0) {
			// FIXME: set service_exit_code
			goto error_pipe_add;
		}

		notification_handle = RegisterDeviceNotification(_message_pump_hwnd,
		                                                 &notification_filter,
		                                                 DEVICE_NOTIFY_WINDOW_HANDLE);
	}

	if (notification_handle == NULL) {
		// FIXME: set service_exit_code
		rc = ERRNO_WINAPI_OFFSET + GetLastError();

		log_error("Could not register for device notification: %s (%d)",
		          get_errno_name(rc), rc);

		goto error_notification;
	}

	if (network_init() < 0) {
		// FIXME: set service_exit_code
		goto error_network;
	}

	// running
	if (_run_as_service) {
		service_set_status(SERVICE_RUNNING, NO_ERROR);
	}

	if (event_run() < 0) {
		// FIXME: set service_exit_code
		goto error_run;
	}

	exit_code = EXIT_SUCCESS;

error_run:
	network_exit();

error_network:
	UnregisterDeviceNotification(notification_handle);

error_notification:
	if (!_run_as_service) {
		message_pump_stop();
	}

	event_remove_source(_notification_pipe[0], EVENT_SOURCE_TYPE_GENERIC);

error_pipe_add:
	pipe_destroy(_notification_pipe);

error_pipe:
	usb_exit();

error_usb:
	event_exit();

error_event:
	log_info("Brick Daemon %s stopped", VERSION_STRING);

error:
	log_exit();

	config_exit();

	if (_run_as_service) {
		// because the service process can be terminated at any time after
		// entering SERVICE_STOPPED state the mutex is closed beforehand,
		// even though this creates a tiny time window in which the service
		// is still running but the mutex is not held anymore
		if (mutex_handle != NULL) {
			CloseHandle(mutex_handle);
		}

		// service is now stopped
		service_set_status(SERVICE_STOPPED, service_exit_code);
	} else {
		if (_pause_before_exit) {
			printf("Press any key to exit...\n");
			getch();
		}

		if (mutex_handle != NULL) {
			CloseHandle(mutex_handle);
		}
	}

	return exit_code;
}