int main(void)
{
  /* Setup */
  identifier = (int *)calloc_safe(1, sizeof(int));
  *identifier = PARENT_IDENTIFIER;
  process_number = -1;

  /* Open file for reading */
  FILE *input_file = fopen_safe("input.txt", "r");

  /* Create necessary pipes */
  create_pipes();

  /* Fork children processes */
  pid_t main_id = getpid(); // main_id contains parent process ID

  create_mappers(main_id);
  if (getpid() == main_id) // more efficient to include this statement
    create_reducers(main_id);

  /* Close proper pipe ends */
  close_pipe_ends();

  /* Parse the input file. Processes handle properly. */
  parse_file(input_file);

  // free heap ptrs

  return 0;
}
 tmp_pipes(int nb_pipes):
 tmpdir_(create_tmp_dir()),
 pipes_(create_pipes(tmpdir_, nb_pipes))
 {
   for(auto it = pipes_.cbegin(); it != pipes_.cend(); ++it)
     pipes_paths_.push_back(it->c_str());
 }
Example #3
0
void
initialize_overhead(iter_t iterations, void* cookie)
{
	int i;
	int procs;
	int* p;
	struct _state* pState = (struct _state*)cookie;

	if (iterations) return;

	pState->pids = NULL;
	pState->p = (int**)malloc(pState->procs * (sizeof(int*) + 2 * sizeof(int)));
	pState->data = (pState->process_size > 0) ? malloc(pState->process_size) : NULL;
	if (!pState->p || (pState->process_size > 0 && !pState->data)) {
		perror("malloc");
		exit(1);
	}
	p = (int*)&pState->p[pState->procs];
	for (i = 0; i < pState->procs; ++i) {
		pState->p[i] = p;
		p += 2;
	}

	if (pState->data)
		bzero(pState->data, pState->process_size);

	procs = create_pipes(pState->p, pState->procs);
	if (procs < pState->procs) {
		cleanup_overhead(0, cookie);
		exit(1);
	}
}
Example #4
0
int run_job(JOB* job)
{
	int i, **pipes = NULL;

	if (job == NULL || job->cmd == NULL)
		return -1;

	if (job->ncmd > 1)
	{
		pipes = create_pipes(job->ncmd-1);
		if (pipes == NULL)
			return -1;
	}

	job->run_count = job->ncmd;
	job_list_push(job);
	job->pgid = 0;

	for (i = 0; i < job->ncmd; i++)
	{
		int input, output;
		
		if (i == 0)
		{
			if (job->inputfd != -1)
				input = job->inputfd;
			else
				input = 0;
		}
		else
			input = pipes[i-1][0];

		if (i == job->ncmd-1)
		{
			if (job->outputfd != -1)
				output = job->outputfd;
			else
				output = 1;
		}
		else
			output = pipes[i][1];
		
		job->pid[i] = run_cmd(job->cmd[i], input, output, pipes, job->ncmd-1, job->pgid);
		if (job->pid[i] <= 0)
			job->run_count--;		/* Built-in commands and failed executions are not running processes */
		else if (job->pgid == 0)
		{
			job->pgid = job->pid[i];		
			job->lastmodified = time(NULL); /* A new job is a 'recently modified job' to fg/bg default */
		}
	}
	
	destroy_pipes(&pipes, job->ncmd-1);

	if (job->blocking)
		fg_wait(job);
	
	return 0;
}
Example #5
0
int shim_do_pipe2 (int * filedes, int flags)
{
    if (!filedes)
        return -EINVAL;

    int ret = 0;

    struct shim_handle * hdl1 = get_new_handle();
    struct shim_handle * hdl2 = get_new_handle();

    if (!hdl1 || !hdl2) {
        ret = -ENOMEM;
        goto out;
    }

    hdl1->type       = TYPE_PIPE;
    set_handle_fs(hdl1, &pipe_builtin_fs);
    hdl1->flags      = O_RDONLY;
    hdl1->acc_mode   = MAY_READ;

    hdl2->type       = TYPE_PIPE;
    set_handle_fs(hdl2, &pipe_builtin_fs);
    hdl2->flags      = O_WRONLY;
    hdl2->acc_mode   = MAY_WRITE;

    if ((ret = create_pipes(&hdl1->info.pipe.pipeid,
                            &hdl1->pal_handle, &hdl2->pal_handle,
                            &hdl1->uri, flags)) < 0)
        goto out;

    qstrcopy(&hdl2->uri, &hdl2->uri);

    flags = flags & O_CLOEXEC ? FD_CLOEXEC : 0;
    int vfd1 = set_new_fd_handle(hdl1, flags, NULL);
    int vfd2 = set_new_fd_handle(hdl2, flags, NULL);

    if (vfd1 < 0 || vfd2 < 0) {
        if (vfd1 >= 0) {
            struct shim_handle * tmp = detach_fd_handle(vfd1, NULL, NULL);
            if (tmp)
                close_handle(tmp);
        }
        if (vfd2 >= 0) {
            struct shim_handle * tmp = detach_fd_handle(vfd2, NULL, NULL);
            if (tmp)
                close_handle(tmp);
        }
        goto out;
    }

    filedes[0] = vfd1;
    filedes[1] = vfd2;
out:
    if (hdl1)
        put_handle(hdl1);
    if (hdl2)
        put_handle(hdl2);
    return ret;
}
Example #6
0
int	prepa_pipes(t_cmd *cmd, int i)
{
    while (cmd[i].token != NULL && cmd[i].token[0] != ';')
    {
        if ((strcmp(cmd[i].token, "|") == 0))
            create_pipes(cmd, i);
        else if ((strcmp(cmd[i].token, "||") == 0))
            cmd[i].fdout = 1;
        else if ((strcmp(cmd[i].token, "&&") == 0))
            cmd[i].fdout = 1;
        i++;
    }
    if (cmd[i].type == 0)
        cmd[i].fdout = 1;
    return (0);
}
Example #7
0
static foreign_t
process_create(term_t exe, term_t options)
{ p_options info;
  int rc = FALSE;

  memset(&info, 0, sizeof(info));

  if ( !get_exe(exe, &info) )
    goto out;
  if ( !parse_options(options, &info) )
    goto out;
  if ( !create_pipes(&info) )
    goto out;

  rc = do_create_process(&info);

out:
  free_options(&info);

  return rc;
}
Example #8
0
// This method rapresents the conversation function to be passed to the PAM library
int pamconv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *data) {
	char *buf = (char *) calloc(PAM_MAX_RESP_SIZE, sizeof(char));
	char nomepipe[1024];
	int i;

	if (num_msg <= 0 || num_msg > PAM_MAX_NUM_MSG)
		return (PAM_CONV_ERR);

	if ((*resp = calloc(num_msg, sizeof **resp)) == NULL)
		return (PAM_BUF_ERR);

	for (i = 0; i < num_msg; ++i) {
		create_pipes();
	
		resp[i]->resp_retcode = 0;
		resp[i]->resp = NULL;

		// Watch the type of the message and acts accordingly
		switch (msg[i]->msg_style) {
			case PAM_PROMPT_ECHO_OFF:
				sprintf(nomepipe, "%s%s_tipo", PREFIX, sessionID);
				write_file(&nomepipe[0], "PROMPT_ECHO_OFF", 0);
				break;

			case PAM_PROMPT_ECHO_ON:
				sprintf(nomepipe, "%s%s_tipo", PREFIX, sessionID);
				write_file(&nomepipe[0], "PROMPT_ECHO_ON", 0);
				break;

			case PAM_ERROR_MSG:
				sprintf(nomepipe, "%s%s_tipo", PREFIX, sessionID);
				write_file(&nomepipe[0], "ERROR_MSG", 0);
				break;

			case PAM_TEXT_INFO:
				sprintf(nomepipe, "%s%s_tipo", PREFIX, sessionID);
				write_file(&nomepipe[0], "TEXT_INFO", 0);
				break;

			default:
				goto fail;
		}

		sprintf(nomepipe, "%s%s_testo", PREFIX, sessionID);
		write_file(&nomepipe[0], msg[i]->msg, 0);

		// If the message type needs a response from the user, reads it
		sprintf(nomepipe, "%s%s_risposta", PREFIX, sessionID);
		if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF || msg[i]->msg_style == PAM_PROMPT_ECHO_ON) {
			read_file(&nomepipe[0], &buf);

			resp[i]->resp = strdup(buf);
			if (resp[i]->resp == NULL)
				goto fail;
		}
		// TODO AB
		printf("get response: %s.\n", buf);
		remove(&nomepipe[0]);
	}
	return (PAM_SUCCESS);

fail:
	while (i)
		free(resp[--i]);

	free(*resp);
	*resp = NULL;

	return (PAM_CONV_ERR);
}
Example #9
0
int
main(int ac, char **av)
{
	int	i, max_procs;
	double	overhead = 0;

	if (ac < 2) {
usage:		printf("Usage: %s [-s kbytes] processes [processes ...]\n",
		    av[0]);
		exit(1);
	}

	/*
	 * Need 4 byte ints.
	 */
	if (sizeof(int) != 4) {
		fprintf(stderr, "Fix sumit() in ctx.c.\n");
		exit(1);
	}

	/*
	 * If they specified a context size, get it.
	 */
	if (!strcmp(av[1], "-s")) {
		if (ac < 4) {
			goto usage;
		}
		process_size = atoi(av[2]) * 1024;
		if (process_size > 0) {
			data = (int *)calloc(1, max(process_size, CHUNK));
			BENCHO(sumit(CHUNK), sumit(0), 0);
			overhead = gettime();
			overhead /= get_n();
			overhead *= process_size;
			overhead /= CHUNK;
		}
		ac -= 2;
		av += 2;
	}

#if	defined(sgi) && defined(PIN)
	ncpus = sysmp(MP_NPROCS);
	sysmp(MP_MUSTRUN, 0);
#endif
	for (max_procs = atoi(av[1]), i = 1; i < ac; ++i) {
		int procs = atoi(av[i]);
		if (max_procs < procs) max_procs = procs;
	}
	max_procs = create_pipes(p, max_procs);
	overhead += pipe_cost(p, max_procs);
	max_procs = create_daemons(p, pids, max_procs);
	fprintf(stderr, "\n\"size=%dk ovr=%.2f\n", process_size/1024, overhead);
	for (i = 1; i < ac; ++i) {
		double	time;
		int	procs = atoi(av[i]);

		if (procs > max_procs) continue;

		BENCH(ctx(procs, max_procs), 0);
		time = usecs_spent();
		time /= get_n();
		time /= procs;
		time /= TRIPS;
		time -= overhead;
	    	fprintf(stderr, "%d %.2f\n", procs, time);
	}

	/*
	 * Close the pipes and kill the children.
	 */
     	killem(max_procs);
     	for (i = 0; i < max_procs; ++i) {
		close(p[i][0]);
		close(p[i][1]);
		if (i > 0) {
			wait(0);
		}
	}
	return (0);
}
Example #10
0
int main(int argc, const char* argv[])
{
    int status, bg_pipes[2], num_pipes, flags;
    struct sigaction act_bg_term, act_int_old, act_int_new;
    /* Define handler for SIGINT (ignore) */
    act_int_new.sa_handler = SIG_IGN;
    act_int_new.sa_flags = 0;
    if (sigaction(SIGINT, &act_int_new, &act_int_old))
        perror("Failed to change handler for SIGINT");

    /* Define handler for detecting background process termination */
    if (SIGNAL_DETECTION == 1)
    {
        if (sigaction(SIGUSR1, NULL, &act_bg_term))
            perror("Failed to get handler for SIGUSR1");
        act_bg_term.sa_handler = sig_bg_handler;
        act_bg_term.sa_flags = SA_RESTART;
        if (sigaction(SIGUSR1, &act_bg_term, NULL))
            perror("Failed to set handler for SIGUSR1");
    }

    /* Create pipe for printing background process info */
    num_pipes = 1;
    create_pipes(bg_pipes, num_pipes);

    /* Configure pipe to be non-blocking on read end */
    flags = fcntl(bg_pipes[0], F_GETFL, 0);
    fcntl(bg_pipes[0], F_SETFL, flags | O_NONBLOCK);

    while (1)
    {
        char input[80], cmd[80];
        int i;

        /* Wait for all defunct children */
        /* Continue even if no child has exited */
        if (!(SIGNAL_DETECTION == 1))
            while (waitpid(-1, &status, WNOHANG | WUNTRACED) > 0);

        /* Print prompt */
        if (!print_prompt()) continue;

        /* Exit if error occurs */
        if (!fgets(input, 80, stdin))
        {
            perror("Failed to get input");
            continue;
        }

        /* Remove newline, if present */
        i = strlen(input) - 1;
        if (input[i] == '\n') input[i] = '\0';

        /* Read given commands */
        i = 0; /* Input index */
        i = read_cmd(cmd, input, i);

        if (strcmp(cmd, "exit") == 0)
            break;
        else if (strcmp(cmd, "cd") == 0)
            cd(input, cmd, i);
        else if (strcmp(cmd, "checkEnv") == 0)
            check_env(input, i);
        else if (cmd[0] == '\0') {} /* Just print process info */
        else
            general_cmd(input, &act_int_old, bg_pipes);

        /* Print accumulated process information */
        print_process_info(bg_pipes);
    }

    /* Close pipe for printing background process info */
    close_pipes(bg_pipes, num_pipes);

    exit_shell();

    return 0;
}
Example #11
0
int general_cmd(char* input, const struct sigaction* act_int_old,
        const int* bg_pipes)
{
    int pipes[2];                 /* File descriptors from piping */
    int fds[4];                   /* File descriptors to dupe */
    int background_process;       /* Whether to run in the background */
    int status;                   /* Wait status */
    int i;                        /* Command index */
    int j = 1;                    /* Loop index */
    int num_pipes = 1;            /* Number of pipes to create */
    char* args[80];               /* All arguments to the command */
    char arg[80];                 /* One argument to command */
    char cmd[80];                 /* The command to be executed */
    unsigned long exec_time;      /* Execution time */
    pid_t pid;                    /* PID of child */
    struct timeval time_before;   /* Time before execution of command */
    struct timeval time_after;    /* Time after execution of command */

    create_pipes(pipes, num_pipes);
    fds[0] = -1;
    fds[1] = -1;
    fds[2] = -1;
    fds[3] = -1;

    /* Read the entire command string */
    background_process = 0;
    for (i = 0; ; ++i)
    {
        /* Check if the process should run in the background */
        if (input[i] == '&')
        {
            background_process = 1;
            input[i] = '\0';
            break;
        }
        else if (input[i] == '\0')
        {
            break;
        }
    }

    /* Read the command */
    i = read_cmd(cmd, input, 0);
    /* First argument in list must be file name */
    args[0] = cmd;

    /* Read arguments to the command */
    while (input[i] != '\0')
    {
        i = read_cmd(arg, input, i);
        args[j] = arg;
        ++j;
    }
    /* Argument list to execvp is NULL terminated */
    args[j] = (char*) NULL;

    pid = fork(); /* Create new child process that handles execution */

    /* Child process */
    if (pid == 0)
    {
        /* Save current stdout file descriptor */
        if (background_process)
        {
            /* Write termination info to process info pipe */
            if (dup2(bg_pipes[1], WRITE) < 0)
            {
                perror("Failed to duplicate file descriptor for writing");
                return 0;
            }

            /* Write err info to process info process pipe */
            if (dup2(bg_pipes[1], ERROR) < 0)
            {
                perror("Failed to duplicate file descriptor for errors");
                return 0;
            }

            /* Close file descriptor */
            if (close(bg_pipes[1]))
            {
                perror("Failed to delete file descriptor");
                return 0;
            }
        }

        /* Restore normal interrupt behaviour */
        if (sigaction(SIGINT, act_int_old, NULL))
            perror("Failed to change handler for SIGINT in child");

        /* Measure execution time */
        gettimeofday(&time_before, NULL);

        if (!fork_exec_cmd(cmd, pipes, fds, args, num_pipes, 0))
        {
            perror(cmd);
            return 0;
        }
        if ((pid = wait(&status)) < 0)
        {
            perror("Failed to wait for executing process");
            return 0;
        }

        /* Calculate execution time */
        gettimeofday(&time_after, NULL);
        exec_time = 1000 * (time_after.tv_sec - time_before.tv_sec) +
        (time_after.tv_usec - time_before.tv_usec) / 1000;
        printf("(pid: %d) %s finished executing in %lu ms.\n", pid, cmd, exec_time);

        /* Notify parent of termination */
        if (SIGNAL_DETECTION == 1 && background_process)
        {
            if (kill(getppid(), SIGUSR1))
            {
                perror("Failed to notify parent of termination");
                return 0;
            }
        }

        _exit(0); /* exit() unreliable */
    }
    /* Error */
    else if (pid < 0)
    {
        perror("Failed to fork child process");
        exit(1);
    }
    /* Parent process */
    else
    {
        /* The parent process comes here after forking */
        if (!background_process)
        {
            if (waitpid(pid, &status, 0) < 0)
            {
                perror("Failed to wait for process");
                return 0;
            }
        }
    }

    /* Let the parent processes close all pipes */
    close_pipes(pipes, num_pipes);

    return 1;
}
Example #12
0
int check_env(const char* input, int i)
{
    int pipes[6];                   /* File descriptors from piping */
    int fds[4];                     /* File descriptors to dupe */
    int status;                     /* Wait status */
    int j = 1;                      /* Loop index */
    int num_pipes = 2;              /* Number of pipes to create */
    char* args[80];                 /* All arguments to grep */
    char* pager = getenv("PAGER");  /* PAGER enviroment variable */
    char cmd[80];                   /* One grep parameter */

    /* Read arguments to grep */
    while (input[i] != '\0')
    {
        i = read_cmd(cmd, input, i);
        args[j] = cmd;
        ++j;
    }

    /* If arguments were given, one pipe is needed for grep */
    if (j > 1) num_pipes = 3;

    /* Create all pipes beforehand */
    create_pipes(pipes, num_pipes);

    /* Argument list to execvp is NULL terminated */
    args[j] = (char*) NULL;

    /* First argument in list must be file name */
    args[0] = cmd;

    /* pipe fds: (0, 1) [2, 3, 4, 5, 6, 7] */

    /* PIPE READ WRITE */
    /* 1    2    3     */
    /* 2    4    5     */
    /* 3    6    7     */

    /* PROC READ WRITE */
    /* 1    0    3     */
    /* 2    2    5     */
    /* 3    4    7     */
    /* 4    6    1     */

    /* Pipe and execute printenv */
    fds[0] = -1;
    fds[1] = -1;
    fds[2] = 1;
    fds[3] = WRITE;
    if (!fork_exec_cmd("printenv", pipes, fds, NULL, num_pipes, 0))
    {
        perror("Failed to execute printenv");
        return 0;
    }

    /* Only pipe and excute grep if arguments were given */
    fds[0] = 0;
    fds[1] = READ;
    fds[2] = 3;
    fds[3] = WRITE;
    if (num_pipes == 3)
    {
        if (!fork_exec_cmd("grep", pipes, fds, args, num_pipes, 0))
        {
            perror("Failed to to execute grep");
            return 0;
        }
    }

    /* Pipe and execute sort */
    if (num_pipes == 3)
    {
        fds[0] = 2;
        fds[1] = READ;
        fds[2] = 5;
        fds[3] = WRITE;
    }
    if (!fork_exec_cmd("sort", pipes, fds, NULL, num_pipes, 0))
    {
        perror("Failed to to execute sort");
        return 0;
    }

    /* Try to pipe and execute with PAGER environment variable */
    fds[0] = (num_pipes == 3) ? 4 : 2;
    fds[1] = READ;
    fds[2] = -1;
    fds[3] = -1;
    if (pager)
    {
        if (!fork_exec_cmd(pager, pipes, fds, NULL, num_pipes, 0))
        {
            perror("Failed to to execute checkEnv with environment pager");
            return 0;
        }
    }
    /* Try to pipe and execute with pager `less`, then `more` */
    else
    {
        if (!fork_exec_cmd("more", pipes, fds, NULL, num_pipes, 1))
        {
            perror("Failed to to execute checkEnv with default pagers");
            return 0;
        }
    }

    /* Let the parent processes close all pipes */
    close_pipes(pipes, num_pipes);

    /* Let the parent processes wait for all children */
    for (j = 0; j < num_pipes + 1; ++j)
    {
        /* Wait for the processes to finish */
        if (wait(&status) < 0)
        {
            perror("Failed to wait for process");
            return 0;
        }
    }

    return 1;
}
Example #13
0
static int start_mbrola(const char *voice_path)
{
	int error, p_stdin[2], p_stdout[2], p_stderr[2];
	ssize_t written;
	char charbuf[20];

	if (mbr_state != MBR_INACTIVE) {
		err("mbrola init request when already initialized");
		return -1;
	}

	error = create_pipes(p_stdin, p_stdout, p_stderr);
	if (error)
		return -1;

	mbr_pid = fork();

	if (mbr_pid == -1) {
		error = errno;
		close_pipes(p_stdin, p_stdout, p_stderr);
		err("fork(): %s", strerror(error));
		return -1;
	}

	if (mbr_pid == 0) {
		int i;

		if (dup2(p_stdin[0], 0) == -1 ||
		    dup2(p_stdout[1], 1) == -1 ||
		    dup2(p_stderr[1], 2) == -1) {
			snprintf(mbr_errorbuf, sizeof(mbr_errorbuf),
			         "dup2(): %s\n", strerror(errno));
			written = write(p_stderr[1], mbr_errorbuf, strlen(mbr_errorbuf));
			(void)written;   // suppress 'variable not used' warning
			_exit(1);
		}

		for (i = p_stderr[1]; i > 2; i--)
			close(i);
		signal(SIGHUP, SIG_IGN);
		signal(SIGINT, SIG_IGN);
		signal(SIGQUIT, SIG_IGN);
		signal(SIGTERM, SIG_IGN);

		snprintf(charbuf, sizeof(charbuf), "%g", mbr_volume);
		execlp("mbrola", "mbrola", "-e", "-v", charbuf,
		       voice_path, "-", "-.wav", (char *)NULL);
		/* if execution reaches this point then the exec() failed */
		snprintf(mbr_errorbuf, sizeof(mbr_errorbuf),
		         "mbrola: %s\n", strerror(errno));
		written = write(2, mbr_errorbuf, strlen(mbr_errorbuf));
		(void)written;   // suppress 'variable not used' warning
		_exit(1);
	}

	snprintf(charbuf, sizeof(charbuf), "/proc/%d/stat", mbr_pid);
	mbr_proc_stat = open(charbuf, O_RDONLY);
	if (mbr_proc_stat == -1) {
		error = errno;
		close_pipes(p_stdin, p_stdout, p_stderr);
		waitpid(mbr_pid, NULL, 0);
		mbr_pid = 0;
		err("/proc is unaccessible: %s", strerror(error));
		return -1;
	}

	signal(SIGPIPE, SIG_IGN);

	if (fcntl(p_stdin[1], F_SETFL, O_NONBLOCK) == -1 ||
	    fcntl(p_stdout[0], F_SETFL, O_NONBLOCK) == -1 ||
	    fcntl(p_stderr[0], F_SETFL, O_NONBLOCK) == -1) {
		error = errno;
		close_pipes(p_stdin, p_stdout, p_stderr);
		waitpid(mbr_pid, NULL, 0);
		mbr_pid = 0;
		err("fcntl(): %s", strerror(error));
		return -1;
	}

	mbr_cmd_fd = p_stdin[1];
	mbr_audio_fd = p_stdout[0];
	mbr_error_fd = p_stderr[0];
	close(p_stdin[0]);
	close(p_stdout[1]);
	close(p_stderr[1]);

	mbr_state = MBR_IDLE;
	return 0;
}
Example #14
0
int shim_do_socketpair (int domain, int type, int protocol, int * sv)
{
    if (domain != AF_UNIX)
        return -EAFNOSUPPORT;

    if (type != SOCK_STREAM)
        return -EPROTONOSUPPORT;

    if (!sv)
        return -EINVAL;

    int ret = 0;
    struct shim_handle * hdl1 = get_new_handle();
    struct shim_handle * hdl2 = get_new_handle();

    if (!hdl1 || !hdl2) {
        ret = -ENOMEM;
        goto out;
    }

    struct shim_sock_handle * sock1 = &hdl1->info.sock;
    struct shim_sock_handle * sock2 = &hdl2->info.sock;

    hdl1->type          = TYPE_SOCK;
    set_handle_fs(hdl1, &socket_builtin_fs);
    hdl1->flags         = O_RDONLY;
    hdl1->acc_mode      = MAY_READ|MAY_WRITE;
    sock1->domain       = domain;
    sock1->sock_type    = type & ~(SOCK_NONBLOCK|SOCK_CLOEXEC);
    sock1->protocol     = protocol;
    sock1->sock_state   = SOCK_ACCEPTED;

    hdl2->type          = TYPE_SOCK;
    set_handle_fs(hdl2, &socket_builtin_fs);
    hdl1->flags         = O_WRONLY;
    hdl2->acc_mode      = MAY_READ|MAY_WRITE;
    sock2->domain       = domain;
    sock2->sock_type    = type & ~(SOCK_NONBLOCK|SOCK_CLOEXEC);
    sock2->protocol     = protocol;
    sock2->sock_state   = SOCK_CONNECTED;

    if ((ret = create_pipes(&sock1->addr.un.pipeid, &hdl1->pal_handle,
                            &hdl2->pal_handle, &hdl1->uri,
                            type & SOCK_NONBLOCK ? O_NONBLOCK : 0)) < 0)
        goto out;

    sock2->addr.un.pipeid = sock1->addr.un.pipeid;
    qstrcopy(&hdl2->uri, &hdl1->uri);

    int flags = type & SOCK_CLOEXEC ? FD_CLOEXEC : 0;
    int vfd1 = set_new_fd_handle(hdl1, flags, NULL);
    int vfd2 = set_new_fd_handle(hdl2, flags, NULL);

    if (vfd1 < 0 || vfd2 < 0) {
        if (vfd1 >= 0) {
            struct shim_handle * tmp = detach_fd_handle(vfd1, NULL, NULL);
            if (tmp)
                close_handle(tmp);
        }
        if (vfd2 >= 0) {
            struct shim_handle * tmp = detach_fd_handle(vfd2, NULL, NULL);
            if (tmp)
                close_handle(tmp);
        }
        goto out;
    }

    sv[0] = vfd1;
    sv[1] = vfd2;
out:
    if (hdl1)
        put_handle(hdl1);
    if (hdl2)
        put_handle(hdl2);
    return ret;
}