if (debug) log_d("process_cgi: %d", p[0]);
int process_cgi(struct request *r){	struct cgi_parameters *cp;	uid_t u;	gid_t g;	struct pipe_params *pp;	int p[2], efd;	pid_t pid;	char curdir[PATHLEN], *s;	s = strrchr(r->path_translated, '/');	if (s == 0)		return 500;	sprintf(curdir, "%.*s", s - r->path_translated, r->path_translated);	pp = new_pipe_params();	if (pp == 0) {		r->cn->keepalive = 0;		return 503;	}	switch (r->c->script_identity) {	case SI_CHANGETOFIXED:		u = r->c->script_uid;		g = r->c->script_gid;		break;	case SI_CHANGETOOWNER:		u = r->finfo.st_uid;		g = r->finfo.st_gid;		break;	default:		u = 0;		g = 0;		break;	}	if (geteuid() == u) {		log_d("cannot run scripts withouth changing identity");		return 500;	}	cp = malloc(sizeof *cp);	if (cp == 0) {		log_d("process_cgi: out of memory");		return 500;	}	cp->cgi_envc = 0;	cp->cgi_envp = 0;	cp->cgi_argc = 0;	cp->cgi_argv = 0;	if (init_cgi_env(r, cp) == -1) {		log_d("process_cgi: out of memory");		destroy_parameters(cp);		return 500;	}	if (socketpair(AF_UNIX, SOCK_STREAM, 0, p) == -1) {		lerror("socketpair");		destroy_parameters(cp);		return 500;	}	fcntl(p[0], F_SETFD, FD_CLOEXEC);	fcntl(p[1], F_SETFD, FD_CLOEXEC);	if (r->c->child_filename) {		efd = open_log(r->c->child_filename);		if (efd == -1) {			close(p[0]);			close(p[1]);			destroy_parameters(cp);			return 500;		}		fcntl(efd, F_SETFD, FD_CLOEXEC);	} else		efd = -1;	pid = spawn(cp->cgi_argv[0], (char **) cp->cgi_argv, cp->cgi_envp, p[1], efd, u, g, curdir);	if (efd != -1)		close(efd);	close(p[1]);	if (pid == -1) {		close(p[0]);		destroy_parameters(cp);		r->cn->keepalive = 0;		return 503;	}	r->cn->pid = pid;	fcntl(p[0], F_SETFL, O_NONBLOCK);	init_child(pp, r, p[0]);	destroy_parameters(cp);	return -1;}