added some pipe handling code
This commit is contained in:
		@ -31,16 +31,107 @@
 | 
				
			|||||||
#include <fcntl.h>
 | 
					#include <fcntl.h>
 | 
				
			||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int pro_make (stio_dev_t* dev, void* ctx)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	stio_dev_pro_t* pro = (stio_dev_pro_t*)dev;
 | 
					 | 
				
			||||||
	stio_dev_pro_make_t* arg = (stio_dev_pro_make_t*)ctx;
 | 
					 | 
				
			||||||
	stio_syshnd_t hnd[6];
 | 
					 | 
				
			||||||
	int i, minidx = -1, maxidx = -1;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (arg->flags & STIO_DEV_PRO_WRITEIN)
 | 
					static stio_dev_pro_t* make_sibling (stio_t* stio, stio_syshnd_t handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ========================================================================= */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static pid_t standard_fork_and_exec (stio_dev_pro_t* rdev, int pfds[], stio_dev_pro_make_t* info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						pid_t pid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pid = fork ();
 | 
				
			||||||
 | 
						if (fork() == -1) 
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (pipe(&hnd[0]) == -1)
 | 
							rdev->stio->errnum = stio_syserrtoerrnum(errno);
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pid == 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							stio_syshnd_t devnull = STIO_SYSHND_INVALID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* TODO: close all uneeded fds */
 | 
				
			||||||
 | 
							if (info->flags & STIO_DEV_PRO_WRITEIN)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								/* child should read */
 | 
				
			||||||
 | 
								close (pfds[1]);
 | 
				
			||||||
 | 
								pfds[1] = STIO_SYSHND_INVALID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/* let the pipe be standard input */
 | 
				
			||||||
 | 
								if (dup2 (pfds[0], 0) <= -1) goto child_oops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								close (pfds[0]);
 | 
				
			||||||
 | 
								pfds[0] = STIO_SYSHND_INVALID;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (info->flags & STIO_DEV_PRO_READOUT)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								/* child should write */
 | 
				
			||||||
 | 
								close (pfds[2]);
 | 
				
			||||||
 | 
								pfds[2] = STIO_SYSHND_INVALID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (dup2(pfds[3], 1) == -1) goto child_oops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (info->flags & STIO_DEV_PRO_ERRTOOUT)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (dup2(pfds[3], 2) == -1) goto child_oops;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								close (pfds[3]);
 | 
				
			||||||
 | 
								pfds[3] = STIO_SYSHND_INVALID;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (info->flags & STIO_DEV_PRO_READERR)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								close (pfds[4]);
 | 
				
			||||||
 | 
								pfds[4] = STIO_SYSHND_INVALID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (dup2(pfds[5], 2) == -1) goto child_oops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (info->flags & STIO_DEV_PRO_OUTTOERR)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (dup2(pfds[5], 1) == -1) goto child_oops;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								close (pfds[5]);
 | 
				
			||||||
 | 
								pfds[5] = STIO_SYSHND_INVALID;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ((info->flags & STIO_DEV_PRO_INTONUL) ||
 | 
				
			||||||
 | 
							    (info->flags & STIO_DEV_PRO_OUTTONUL) ||
 | 
				
			||||||
 | 
							    (info->flags & STIO_DEV_PRO_ERRTONUL))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							#if defined(O_LARGEFILE)
 | 
				
			||||||
 | 
								devnull = open ("/dev/null", O_RDWR | O_LARGEFILE, 0);
 | 
				
			||||||
 | 
							#else
 | 
				
			||||||
 | 
								devnull = open ("/dev/null", O_RDWR, 0);
 | 
				
			||||||
 | 
							#endif
 | 
				
			||||||
 | 
								if (devnull == STIO_SYSHND_INVALID) goto child_oops;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							//execv (param->argv[0], param->argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						child_oops:
 | 
				
			||||||
 | 
							if (devnull != STIO_SYSHND_INVALID) close(devnull);
 | 
				
			||||||
 | 
							_exit (128);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return pid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dev_pro_make (stio_dev_t* dev, void* ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						stio_dev_pro_t* rdev = (stio_dev_pro_t*)dev;
 | 
				
			||||||
 | 
						stio_dev_pro_make_t* info = (stio_dev_pro_make_t*)ctx;
 | 
				
			||||||
 | 
						stio_syshnd_t pfds[6];
 | 
				
			||||||
 | 
						int i, minidx = -1, maxidx = -1;
 | 
				
			||||||
 | 
						pid_t pid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (info->flags & STIO_DEV_PRO_WRITEIN)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (pipe(&pfds[0]) == -1)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			dev->stio->errnum = stio_syserrtoerrnum(errno);
 | 
								dev->stio->errnum = stio_syserrtoerrnum(errno);
 | 
				
			||||||
			goto oops;
 | 
								goto oops;
 | 
				
			||||||
@ -48,9 +139,9 @@ static int pro_make (stio_dev_t* dev, void* ctx)
 | 
				
			|||||||
		minidx = 0; maxidx = 1;
 | 
							minidx = 0; maxidx = 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (arg->flags & STIO_DEV_PRO_READOUT)
 | 
						if (info->flags & STIO_DEV_PRO_READOUT)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (pipe(&hnd[2]) == -1)
 | 
							if (pipe(&pfds[2]) == -1)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			dev->stio->errnum = stio_syserrtoerrnum(errno);
 | 
								dev->stio->errnum = stio_syserrtoerrnum(errno);
 | 
				
			||||||
			goto oops;
 | 
								goto oops;
 | 
				
			||||||
@ -59,9 +150,9 @@ static int pro_make (stio_dev_t* dev, void* ctx)
 | 
				
			|||||||
		maxidx = 3;
 | 
							maxidx = 3;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (arg->flags & STIO_DEV_PRO_READERR)
 | 
						if (info->flags & STIO_DEV_PRO_READERR)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (pipe(&hnd[4]) == -1)
 | 
							if (pipe(&pfds[4]) == -1)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			dev->stio->errnum = stio_syserrtoerrnum(errno);
 | 
								dev->stio->errnum = stio_syserrtoerrnum(errno);
 | 
				
			||||||
			goto oops;
 | 
								goto oops;
 | 
				
			||||||
@ -76,9 +167,14 @@ static int pro_make (stio_dev_t* dev, void* ctx)
 | 
				
			|||||||
		goto oops;
 | 
							goto oops;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* TODO: fork and exec... */
 | 
					/* TODO: more advanced fork and exec .. */
 | 
				
			||||||
 | 
						pid = standard_fork_and_exec (rdev, pfds, info);
 | 
				
			||||||
 | 
						if (pid <= -1) goto oops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (arg->flags & STIO_DEV_PRO_WRITEIN)
 | 
						rdev->child_pid = pid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* this is the parent process */
 | 
				
			||||||
 | 
						if (info->flags & STIO_DEV_PRO_WRITEIN)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * 012345
 | 
							 * 012345
 | 
				
			||||||
@ -86,11 +182,11 @@ static int pro_make (stio_dev_t* dev, void* ctx)
 | 
				
			|||||||
		 * X
 | 
							 * X
 | 
				
			||||||
		 * WRITE => 1
 | 
							 * WRITE => 1
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		close (hnd[0]);
 | 
							close (pfds[0]);
 | 
				
			||||||
		hnd[0] = STIO_SYSHND_INVALID;
 | 
							pfds[0] = STIO_SYSHND_INVALID;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (arg->flags & STIO_DEV_PRO_READOUT)
 | 
						if (info->flags & STIO_DEV_PRO_READOUT)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * 012345
 | 
							 * 012345
 | 
				
			||||||
@ -98,11 +194,11 @@ static int pro_make (stio_dev_t* dev, void* ctx)
 | 
				
			|||||||
		 *    X
 | 
							 *    X
 | 
				
			||||||
		 * READ => 2
 | 
							 * READ => 2
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		close (hnd[3]);
 | 
							close (pfds[3]);
 | 
				
			||||||
		hnd[3] = STIO_SYSHND_INVALID;
 | 
							pfds[3] = STIO_SYSHND_INVALID;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (arg->flags & STIO_DEV_PRO_READERR)
 | 
						if (info->flags & STIO_DEV_PRO_READERR)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * 012345
 | 
							 * 012345
 | 
				
			||||||
@ -110,31 +206,84 @@ static int pro_make (stio_dev_t* dev, void* ctx)
 | 
				
			|||||||
		 *      X
 | 
							 *      X
 | 
				
			||||||
		 * READ => 4
 | 
							 * READ => 4
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		close (hnd[5]);
 | 
							close (pfds[5]);
 | 
				
			||||||
		hnd[5] = STIO_SYSHND_INVALID;
 | 
							pfds[5] = STIO_SYSHND_INVALID;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (stio_makesyshndasync (pro->stio, hnd[1]) <= -1 ||
 | 
						if (stio_makesyshndasync (dev->stio, pfds[1]) <= -1 ||
 | 
				
			||||||
	    stio_makesyshndasync (pro->stio, hnd[2]) <= -1 ||
 | 
						    stio_makesyshndasync (dev->stio, pfds[2]) <= -1 ||
 | 
				
			||||||
	    stio_makesyshndasync (pro->stio, hnd[4]) <= -1) goto oops;
 | 
						    stio_makesyshndasync (dev->stio, pfds[4]) <= -1) goto oops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pfds[2] != STIO_SYSHND_INVALID)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							rdev->sibling[0] = make_sibling (dev->stio, pfds[2]);
 | 
				
			||||||
 | 
							if (!rdev->sibling[0]) goto oops;
 | 
				
			||||||
 | 
							pfds[2] = STIO_SYSHND_INVALID;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pfds[4] != STIO_SYSHND_INVALID)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							rdev->sibling[1] = make_sibling (dev->stio, pfds[4]);
 | 
				
			||||||
 | 
							if (!rdev->sibling[1])
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (rdev->sibling[0])
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									stio_dev_pro_kill (rdev->sibling[0]);
 | 
				
			||||||
 | 
									rdev->sibling[0] = STIO_NULL;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								goto oops;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							pfds[4] = STIO_SYSHND_INVALID;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rdev->pfd = pfds[1];
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
oops:
 | 
					oops:
 | 
				
			||||||
	for (i = minidx; i < maxidx; i++)
 | 
						for (i = minidx; i < maxidx; i++)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (hnd[i] != STIO_SYSHND_INVALID) close (hnd[i]);
 | 
							if (pfds[i] != STIO_SYSHND_INVALID) close (pfds[i]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return -1;
 | 
						return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dev_pro_make_sibling (stio_dev_t* dev, void* ctx)
 | 
				
			||||||
static void pro_kill (stio_dev_t* dev)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						stio_dev_pro_t* rdev = (stio_dev_pro_t*)dev;
 | 
				
			||||||
 | 
						stio_syshnd_t* handle = (stio_syshnd_t*)ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rdev->pfd = *handle;
 | 
				
			||||||
 | 
						if (stio_makesyshndasync (rdev->stio, rdev->pfd) <= -1) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int pro_read (stio_dev_t* dev, void* buf, stio_iolen_t* len)
 | 
					
 | 
				
			||||||
 | 
					static void dev_pro_kill (stio_dev_t* dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						stio_dev_pro_t* rdev = (stio_dev_pro_t*)dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (rdev->pfd != STIO_SYSHND_INVALID)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							close (rdev->pfd);
 | 
				
			||||||
 | 
							rdev->pfd = STIO_SYSHND_INVALID;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (rdev->sibling[0])
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							stio_dev_pro_kill (rdev->sibling[0]);
 | 
				
			||||||
 | 
							rdev->sibling[0] = STIO_NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (rdev->sibling[1])
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							stio_dev_pro_kill (rdev->sibling[1]);
 | 
				
			||||||
 | 
							rdev->sibling[1] = STIO_NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int dev_pro_read (stio_dev_t* dev, void* buf, stio_iolen_t* len, stio_devadr_t* srcadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stio_dev_pro_t* pro = (stio_dev_pro_t*)dev;
 | 
						stio_dev_pro_t* pro = (stio_dev_pro_t*)dev;
 | 
				
			||||||
	ssize_t x;
 | 
						ssize_t x;
 | 
				
			||||||
@ -152,33 +301,61 @@ static int pro_read (stio_dev_t* dev, void* buf, stio_iolen_t* len)
 | 
				
			|||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int pro_write (stio_dev_t* dev, const void* data, stio_iolen_t* len)
 | 
					static int dev_pro_write (stio_dev_t* dev, const void* data, stio_iolen_t* len, const stio_devadr_t* dstadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return -1;
 | 
						return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static stio_syshnd_t pro_getsyshnd (stio_dev_t* dev)
 | 
					static stio_syshnd_t dev_pro_getsyshnd (stio_dev_t* dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stio_dev_pro_t* pro = (stio_dev_pro_t*)dev;
 | 
						stio_dev_pro_t* pro = (stio_dev_pro_t*)dev;
 | 
				
			||||||
	return (stio_syshnd_t)pro->pfd;
 | 
						return (stio_syshnd_t)pro->pfd;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int pro_ioctl (stio_dev_t* dev, int cmd, void* arg)
 | 
					static int dev_pro_ioctl (stio_dev_t* dev, int cmd, void* arg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
						switch (cmd)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							case STIO_DEV_PRO_KILL
 | 
				
			||||||
 | 
							case STIO_DEV_PRO_CLOSEIN:
 | 
				
			||||||
 | 
							case STIO_DEV_PRO_CLOSEOUT:
 | 
				
			||||||
 | 
							case STIO_DEV_PROC_CLOSEERR: 
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static stio_dev_mth_t pro_mth = 
 | 
					static stio_dev_mth_t dev_pro_methods = 
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	pro_make,
 | 
						dev_pro_make,
 | 
				
			||||||
	pro_kill,
 | 
						dev_pro_kill,
 | 
				
			||||||
	pro_getsyshnd,
 | 
						dev_pro_getsyshnd,
 | 
				
			||||||
	pro_read,
 | 
					
 | 
				
			||||||
	pro_write,
 | 
						dev_pro_read,
 | 
				
			||||||
	pro_ioctl
 | 
						dev_pro_write,
 | 
				
			||||||
 | 
						dev_pro_ioctl
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static stio_dev_mth_t dev_pro_methods_sibling =
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						dev_pro_make_sibling,
 | 
				
			||||||
 | 
						dev_pro_kill,
 | 
				
			||||||
 | 
						dev_pro_getsyshnd,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dev_pro_read,
 | 
				
			||||||
 | 
						dev_pro_write,
 | 
				
			||||||
 | 
						dev_pro_ioctl
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ========================================================================= */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int pro_ready (stio_dev_t* dev, int events)
 | 
					static int pro_ready (stio_dev_t* dev, int events)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stio_dev_pro_t* pro = (stio_dev_pro_t*)dev;
 | 
						stio_dev_pro_t* pro = (stio_dev_pro_t*)dev;
 | 
				
			||||||
@ -211,22 +388,35 @@ static int pro_on_read (stio_dev_t* dev, const void* data, stio_iolen_t len, con
 | 
				
			|||||||
	return pro->on_read (pro, data, len);
 | 
						return pro->on_read (pro, data, len);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int pro_on_write (stio_dev_t* dev, void* wrctx, const stio_devadr_t* dstadr)
 | 
					static int pro_on_write (stio_dev_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_devadr_t* dstadr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stio_dev_pro_t* pro = (stio_dev_pro_t*)dev;
 | 
						stio_dev_pro_t* pro = (stio_dev_pro_t*)dev;
 | 
				
			||||||
	return pro->on_write (pro, wrctx);
 | 
						return pro->on_write (pro, wrctx);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static stio_dev_evcb_t pro_evcb =
 | 
					static stio_dev_evcb_t dev_pro_event_callbacks =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	pro_ready,
 | 
						pro_ready,
 | 
				
			||||||
	pro_on_read,
 | 
						pro_on_read,
 | 
				
			||||||
	pro_on_write
 | 
						pro_on_write
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ========================================================================= */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static stio_dev_pro_t* make_sibling (stio_t* stio, stio_syshnd_t handle)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (stio_dev_pro_t*)stio_makedev (
 | 
				
			||||||
 | 
							stio, STIO_SIZEOF(stio_dev_pro_t), 
 | 
				
			||||||
 | 
							&dev_pro_methods_sibling, &dev_pro_event_callbacks, (void*)&handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
stio_dev_pro_t* stio_dev_pro_make (stio_t* stio, stio_size_t xtnsize, const stio_dev_pro_make_t* data)
 | 
					stio_dev_pro_t* stio_dev_pro_make (stio_t* stio, stio_size_t xtnsize, const stio_dev_pro_make_t* data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return (stio_dev_pro_t*)stio_makedev (stio, STIO_SIZEOF(stio_dev_pro_t) + xtnsize, &pro_mth, &pro_evcb, (void*)data);
 | 
						return (stio_dev_pro_t*)stio_makedev (
 | 
				
			||||||
 | 
							stio, STIO_SIZEOF(stio_dev_pro_t) + xtnsize, 
 | 
				
			||||||
 | 
							&dev_pro_methods, &dev_pro_event_callbacks, (void*)data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void stio_dev_pro_kill (stio_dev_pro_t* pro)
 | 
					void stio_dev_pro_kill (stio_dev_pro_t* pro)
 | 
				
			||||||
@ -258,4 +448,5 @@ stio_dev_pro_t* stio_dev_pro_getdev (stio_dev_pro_t* pro, stio_dev_pro_type_t ty
 | 
				
			|||||||
	pro->dev->stio = STIO_EINVAL;
 | 
						pro->dev->stio = STIO_EINVAL;
 | 
				
			||||||
	return STIO_NULL;
 | 
						return STIO_NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -48,10 +48,10 @@ struct stio_dev_pro_t
 | 
				
			|||||||
	STIO_DEV_HEADERS;
 | 
						STIO_DEV_HEADERS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stio_syshnd_t pfd;
 | 
						stio_syshnd_t pfd;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* bitwised-ORed of #stio_dev_pro_state_t enumerators */
 | 
					 | 
				
			||||||
	stio_dev_pro_type_t type;
 | 
						stio_dev_pro_type_t type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						stio_intptr_t child_pid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stio_dev_pro_t* sibling[2];
 | 
						stio_dev_pro_t* sibling[2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stio_dev_pro_on_read_t on_read;
 | 
						stio_dev_pro_on_read_t on_read;
 | 
				
			||||||
@ -65,12 +65,17 @@ enum stio_dev_pro_make_flag_t
 | 
				
			|||||||
	STIO_DEV_PRO_WRITEIN  = (1 << 0),
 | 
						STIO_DEV_PRO_WRITEIN  = (1 << 0),
 | 
				
			||||||
	STIO_DEV_PRO_READOUT  = (1 << 1),
 | 
						STIO_DEV_PRO_READOUT  = (1 << 1),
 | 
				
			||||||
	STIO_DEV_PRO_READERR  = (1 << 2),
 | 
						STIO_DEV_PRO_READERR  = (1 << 2),
 | 
				
			||||||
	STIO_DEV_PRO_INTONUL  = (1 << 3),
 | 
					
 | 
				
			||||||
	STIO_DEV_PRO_OUTTONUL = (1 << 4),
 | 
						STIO_DEV_PRO_ERRTOOUT = (1 << 3),
 | 
				
			||||||
	STIO_DEV_PRO_ERRTONUL = (1 << 5),
 | 
						STIO_DEV_PRO_OUTTOERR = (1 << 4),
 | 
				
			||||||
	STUO_DEV_PRO_DROPIN   = (1 << 6),
 | 
					
 | 
				
			||||||
	STUO_DEV_PRO_DROPOUT  = (1 << 7),
 | 
						STIO_DEV_PRO_INTONUL  = (1 << 5),
 | 
				
			||||||
	STUO_DEV_PRO_DROPERR  = (1 << 8)
 | 
						STIO_DEV_PRO_OUTTONUL = (1 << 6),
 | 
				
			||||||
 | 
						STIO_DEV_PRO_ERRTONUL = (1 << 7),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						STUO_DEV_PRO_DROPIN   = (1 << 8),
 | 
				
			||||||
 | 
						STUO_DEV_PRO_DROPOUT  = (1 << 9),
 | 
				
			||||||
 | 
						STUO_DEV_PRO_DROPERR  = (1 << 10)
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
typedef enum stio_dev_pro_make_flag_t stio_dev_pro_make_flag_t;
 | 
					typedef enum stio_dev_pro_make_flag_t stio_dev_pro_make_flag_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -100,7 +105,7 @@ STIO_EXPORT void stio_dev_pro_kill (
 | 
				
			|||||||
STIO_EXPORT int stio_dev_pro_write (
 | 
					STIO_EXPORT int stio_dev_pro_write (
 | 
				
			||||||
	stio_dev_pro_t*  pro,
 | 
						stio_dev_pro_t*  pro,
 | 
				
			||||||
	const void*      data,
 | 
						const void*      data,
 | 
				
			||||||
	stio_iolen_t       len,
 | 
						stio_iolen_t     len,
 | 
				
			||||||
	void*            wrctx
 | 
						void*            wrctx
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -64,7 +64,7 @@ stio_sckhnd_t stio_openasyncsck (stio_t* stio, int domain, int type, int proto)
 | 
				
			|||||||
	stio_sckhnd_t sck;
 | 
						stio_sckhnd_t sck;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(_WIN32)
 | 
					#if defined(_WIN32)
 | 
				
			||||||
	sck = WSASocket (domain, type, proto, NULL, 0, WSA_FLAG_OVERLAPPED /*| WSA_FLAG_NO_HANDLE_INHERIT*/);
 | 
						sck = WSASocket (domain, type, proto, NULL, 0, WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
 | 
				
			||||||
	if (sck == STIO_SCKHND_INVALID) 
 | 
						if (sck == STIO_SCKHND_INVALID) 
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* stio_seterrnum (dev->stio, STIO_ESYSERR); or translate errno to stio errnum */
 | 
							/* stio_seterrnum (dev->stio, STIO_ESYSERR); or translate errno to stio errnum */
 | 
				
			||||||
@ -78,13 +78,24 @@ stio_sckhnd_t stio_openasyncsck (stio_t* stio, int domain, int type, int proto)
 | 
				
			|||||||
		return STIO_SCKHND_INVALID;
 | 
							return STIO_SCKHND_INVALID;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(FD_CLOEXEC)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							int flags = fcntl (sck, F_GETFD, 0);
 | 
				
			||||||
 | 
							if (fcntl (sck, F_SETFD, flags | FD_CLOEXEC) == -1)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								stio->errnum = stio_syserrtoerrnum(errno);
 | 
				
			||||||
 | 
								return STIO_SCKHND_INVALID;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (stio_makesckasync (stio, sck) <= -1)
 | 
						if (stio_makesckasync (stio, sck) <= -1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		close (sck);
 | 
							close (sck);
 | 
				
			||||||
		return STIO_SCKHND_INVALID;
 | 
							return STIO_SCKHND_INVALID;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* TODO: set CLOEXEC if it's defined */
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return sck;
 | 
						return sck;
 | 
				
			||||||
@ -536,7 +547,7 @@ static int dev_sck_ioctl (stio_dev_t* dev, int cmd, void* arg)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static stio_dev_mth_t dev_mth_sck_stateless = 
 | 
					static stio_dev_mth_t dev_sck_methods_stateless = 
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	dev_sck_make,
 | 
						dev_sck_make,
 | 
				
			||||||
	dev_sck_kill,
 | 
						dev_sck_kill,
 | 
				
			||||||
@ -548,7 +559,7 @@ static stio_dev_mth_t dev_mth_sck_stateless =
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static stio_dev_mth_t dev_mth_sck_stateful = 
 | 
					static stio_dev_mth_t dev_sck_methods_stateful = 
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	dev_sck_make,
 | 
						dev_sck_make,
 | 
				
			||||||
	dev_sck_kill,
 | 
						dev_sck_kill,
 | 
				
			||||||
@ -791,14 +802,14 @@ static int dev_evcb_sck_on_write_stateless (stio_dev_t* dev, stio_iolen_t wrlen,
 | 
				
			|||||||
	return rdev->on_write (rdev, wrlen, wrctx, dstadr->ptr);
 | 
						return rdev->on_write (rdev, wrlen, wrctx, dstadr->ptr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static stio_dev_evcb_t dev_evcb_sck_stateful =
 | 
					static stio_dev_evcb_t dev_sck_event_callbacks_stateful =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	dev_evcb_sck_ready_stateful,
 | 
						dev_evcb_sck_ready_stateful,
 | 
				
			||||||
	dev_evcb_sck_on_read_stateful,
 | 
						dev_evcb_sck_on_read_stateful,
 | 
				
			||||||
	dev_evcb_sck_on_write_stateful
 | 
						dev_evcb_sck_on_write_stateful
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static stio_dev_evcb_t dev_evcb_sck_stateless =
 | 
					static stio_dev_evcb_t dev_sck_event_callbacks_stateless =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	dev_evcb_sck_ready_stateless,
 | 
						dev_evcb_sck_ready_stateless,
 | 
				
			||||||
	dev_evcb_sck_on_read_stateless,
 | 
						dev_evcb_sck_on_read_stateless,
 | 
				
			||||||
@ -819,11 +830,15 @@ stio_dev_sck_t* stio_dev_sck_make (stio_t* stio, stio_size_t xtnsize, const stio
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if (sck_type_map[info->type].extra_dev_capa & STIO_DEV_CAPA_STREAM) /* can't use the IS_STATEFUL() macro yet */
 | 
						if (sck_type_map[info->type].extra_dev_capa & STIO_DEV_CAPA_STREAM) /* can't use the IS_STATEFUL() macro yet */
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		rdev = (stio_dev_sck_t*)stio_makedev (stio, STIO_SIZEOF(stio_dev_sck_t) + xtnsize, &dev_mth_sck_stateful, &dev_evcb_sck_stateful, (void*)info);
 | 
							rdev = (stio_dev_sck_t*)stio_makedev (
 | 
				
			||||||
 | 
								stio, STIO_SIZEOF(stio_dev_sck_t) + xtnsize, 
 | 
				
			||||||
 | 
								&dev_sck_methods_stateful, &dev_sck_event_callbacks_stateful, (void*)info);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		rdev = (stio_dev_sck_t*)stio_makedev (stio, STIO_SIZEOF(stio_dev_sck_t) + xtnsize, &dev_mth_sck_stateless, &dev_evcb_sck_stateless, (void*)info);
 | 
							rdev = (stio_dev_sck_t*)stio_makedev (
 | 
				
			||||||
 | 
								stio, STIO_SIZEOF(stio_dev_sck_t) + xtnsize,
 | 
				
			||||||
 | 
								&dev_sck_methods_stateless, &dev_sck_event_callbacks_stateless, (void*)info);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return rdev;
 | 
						return rdev;
 | 
				
			||||||
 | 
				
			|||||||
@ -286,7 +286,7 @@ STIO_EXPORT int stio_dev_sck_listen (
 | 
				
			|||||||
STIO_EXPORT int stio_dev_sck_write (
 | 
					STIO_EXPORT int stio_dev_sck_write (
 | 
				
			||||||
	stio_dev_sck_t*       dev,
 | 
						stio_dev_sck_t*       dev,
 | 
				
			||||||
	const void*           data,
 | 
						const void*           data,
 | 
				
			||||||
	stio_iolen_t            len,
 | 
						stio_iolen_t          len,
 | 
				
			||||||
	void*                 wrctx,
 | 
						void*                 wrctx,
 | 
				
			||||||
	const stio_sckadr_t*  dstadr
 | 
						const stio_sckadr_t*  dstadr
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
@ -294,7 +294,7 @@ STIO_EXPORT int stio_dev_sck_write (
 | 
				
			|||||||
STIO_EXPORT int stio_dev_sck_timedwrite (
 | 
					STIO_EXPORT int stio_dev_sck_timedwrite (
 | 
				
			||||||
	stio_dev_sck_t*       dev,
 | 
						stio_dev_sck_t*       dev,
 | 
				
			||||||
	const void*           data,
 | 
						const void*           data,
 | 
				
			||||||
	stio_iolen_t            len,
 | 
						stio_iolen_t          len,
 | 
				
			||||||
	const stio_ntime_t*   tmout,
 | 
						const stio_ntime_t*   tmout,
 | 
				
			||||||
	void*                 wrctx,
 | 
						void*                 wrctx,
 | 
				
			||||||
	const stio_sckadr_t*  dstadr
 | 
						const stio_sckadr_t*  dstadr
 | 
				
			||||||
@ -313,28 +313,10 @@ static STIO_INLINE int stio_dev_sck_read (stio_dev_sck_t* sck, int enabled)
 | 
				
			|||||||
	return stio_dev_read ((stio_dev_t*)sck, enabled);
 | 
						return stio_dev_read ((stio_dev_t*)sck, enabled);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
static STIO_INLINE int stio_dev_sck_write (stio_dev_sck_t* sck, const void* data, stio_iolen_t len, void* wrctx, const stio_devadr_t* dstadr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return stio_dev_write ((stio_dev_t*)sck, data, len, wrctx, STIO_NULL);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static STIO_INLINE int stio_dev_sck_timedwrite (stio_dev_sck_t* sck, const void* data, stio_iolen_t len, const stio_ntime_t* tmout, void* wrctx)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return stio_dev_timedwrite ((stio_dev_t*)sck, data, len, tmout, wrctx, STIO_NULL);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define stio_dev_sck_halt(sck) stio_dev_halt((stio_dev_t*)sck)
 | 
					#define stio_dev_sck_halt(sck) stio_dev_halt((stio_dev_t*)sck)
 | 
				
			||||||
#define stio_dev_sck_read(sck,enabled) stio_dev_read((stio_dev_t*)sck, enabled)
 | 
					#define stio_dev_sck_read(sck,enabled) stio_dev_read((stio_dev_t*)sck, enabled)
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
#define stio_dev_sck_write(sck,data,len,wrctx) stio_dev_write((stio_dev_t*)sck, data, len, wrctx, STIO_NULL)
 | 
					 | 
				
			||||||
#define stio_dev_sck_timedwrite(sck,data,len,tmout,wrctx) stio_dev_timedwrite((stio_dev_t*)sck, data, len, tmout, wrctx, STIO_NULL)
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user