Deutsch   English   Français   Italiano  
<ve1f1t$1mvdn$2@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: =?UTF-8?Q?Arne_Vajh=C3=B8j?= <arne@vajhoej.dk>
Newsgroups: comp.os.vms
Subject: Re: Apache + mod_php performance
Date: Mon, 7 Oct 2024 16:07:25 -0400
Organization: A noiseless patient Spider
Lines: 294
Message-ID: <ve1f1t$1mvdn$2@dont-email.me>
References: <vcv0bl$39mnj$1@dont-email.me> <vdp9f6$jbc$1@reader1.panix.com>
 <20241006181231.0000370b@yahoo.com> <vdvoeq$1jerg$1@dont-email.me>
 <ve103l$6lj$1@reader1.panix.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Mon, 07 Oct 2024 22:07:25 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="770b7fe61781a117db0c3db1803d8bb4";
	logging-data="1801655"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX18upe066CQZvvvYzPWDfH/6u0Gm5T8A6ts="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:t/ZL23qguuKhdZsIu+qH73U4hQ0=
Content-Language: en-US
In-Reply-To: <ve103l$6lj$1@reader1.panix.com>
Bytes: 7984

On 10/7/2024 11:52 AM, Dan Cross wrote:
> // Demonstration of a listener process that accepts
> // incoming TCP connections and passes them to a
> // worker process over Unix domain sockets.
> //
> // Dan Cross <cross@gajendra.net>
> 
> #include <sys/types.h>
> #include <sys/socket.h>
> #include <sys/uio.h>
> #include <netinet/in.h>
> 
> #include <stddef.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <string.h>
> 
> // Sends a file descripter, `fd`, over a Unix domain socket `sd`
> // via the 4.4BSD access rights passing mechanism.
> //
> // Returns 1 on success, -1 on failure.
> int
> sendfd(int sd, int fd)
> {
> 	struct msghdr mh;
> 	struct iovec iv;
> 	struct cmsghdr *ptr;
> 	size_t len;
> 	int ret;
> 	char dummy;
> 
> 	// Construct the control message header.  Note this is
> 	// malloc'ed to ensure proper alignment.
> 	len = CMSG_SPACE(sizeof(int));
> 	ptr = malloc(len);
> 	if (ptr == NULL)
> 		return -1;
> 	memset(ptr, 0, len);
> 	ptr->cmsg_len = len;
> 	ptr->cmsg_level = SOL_SOCKET;
> 	ptr->cmsg_type = SCM_RIGHTS;
> 	memcpy(CMSG_DATA(ptr), &fd, sizeof(int));
> 
> 	// We send a single byte of dummy data in case the
> 	// implementation does not pass control data with an
> 	// otherwise empty data transfer.
> 	dummy = 0;
> 	memset(&iv, 0, sizeof(iv));
> 	iv.iov_base = &dummy;
> 	iv.iov_len = 1;
> 
> 	// Construct the message header.  Points to the dummy
> 	// data and the control message header.
> 	memset(&mh, 0, sizeof(mh));
> 	mh.msg_name = NULL;
> 	mh.msg_namelen = 0;
> 	mh.msg_iov = &iv;
> 	mh.msg_iovlen = 1;
> 	mh.msg_control = (caddr_t)ptr;
> 	mh.msg_controllen = len;
> 	mh.msg_flags = 0;
> 
> 	// Loop in case there's no room in the kernel buffer
> 	// to send.  Cf.Stevens et al.
> 	do {
> 		ret = sendmsg(sd, &mh, 0);
> 	} while (ret == 0);
> 	free(ptr);
> 
> 	return ret;
> }
> 
> // Receives a file descriptor over the Unix domain socket `sd`
> // and store it into `*fdp` on success.
> //
> // Returns 1 on success, 0 on EOF, -1 on error.
> int
> recvfd(int sd, int *fdp)
> {
> 	struct msghdr mh;
> 	struct iovec iv;
> 	struct cmsghdr *ptr;
> 	size_t len;
> 	int ret;
> 	char dummy;
> 
> 	if (fdp == NULL)
> 		return -1;
> 
> 	// Allocate space for the control message.
> 	len = CMSG_SPACE(sizeof(int));
> 	ptr = malloc(len);
> 	if (ptr == NULL)
> 		return -1;
> 
> 	// Fill in an iovec to receive one byte of dummy data.
> 	// Required on some systems that do not pass control
> 	// messages on empty data transfers.
> 	memset(&iv, 0, sizeof(iv));
> 	iv.iov_base = &dummy;
> 	iv.iov_len = 1;
> 
> 	// Fill in the msghdr structure.  `recvmsg(2)` will
> 	// update it.
> 	memset(&mh, 0, sizeof(mh));
> 	mh.msg_name = NULL;
> 	mh.msg_namelen = 0;
> 	mh.msg_iov = &iv;
> 	mh.msg_iovlen = 1;
> 	mh.msg_control = ptr;
> 	mh.msg_controllen = len;
> 	mh.msg_flags = 0;
> 
> 	ret = recvmsg(sd, &mh, 0);
> 	if (ret <= 0) {
> 		free(ptr);
> 		return ret;
> 	}
> 	if (mh.msg_flags != 0) {
> 		free(ptr);
> 		return -1;
> 	}
> 	memcpy(fdp, CMSG_DATA(ptr), sizeof(int));
> 	free(ptr);
> 
> 	return 1;
> }
> 
> void
> dispatcher(int sdworker, int port)
> {
> 	int sd, nsd;
> 	struct sockaddr_in sa;
> 	struct sockaddr_in client;
> 	socklen_t clientlen;
> 
> 	sd = socket(AF_INET, SOCK_STREAM, 0);
> 	if (sd < 0) {
> 		perror("socket");
> 		close(sdworker);
> 		exit(EXIT_FAILURE);
> 	}
> 	memset(&sa, 0, sizeof sa);
> 	sa.sin_family = AF_INET;
> 	sa.sin_port = htons((unsigned short)port);
> 	sa.sin_addr.s_addr = htonl(INADDR_ANY);
> 	if (bind(sd, (struct sockaddr *)&sa, sizeof sa) < 0) {
> 		perror("bind");
> 		close(sdworker);
> 		close(sd);
> 		exit(EXIT_FAILURE);
> 	}
> 	if (listen(sd, 255) < 0) {
> 		perror("listen");
> 		close(sdworker);
> 		close(sd);
> 		exit(EXIT_FAILURE);
> 	}
> 
> 	memset(&client, 0, sizeof client);
> 	clientlen = sizeof client;
> 	while ((nsd = accept(sd, (struct sockaddr *)&client, &clientlen)) >= 0) {
> 		if (sendfd(sdworker, nsd) < 0) {
> 			perror("sendfd");
> 			close(sdworker);
> 			close(nsd);
> 			close(sd);
> 			exit(EXIT_FAILURE);
> 		}
> 		close(nsd);
> 	}
> }
> 
> static void
> echo(int sd)
> {
========== REMAINDER OF ARTICLE TRUNCATED ==========