[Commit] nickle file.c, 1.52, 1.53 nickle.h, 1.108, 1.109 value.h, 1.92, 1.93

Bart Massey commit at keithp.com
Sun Oct 12 22:33:38 PDT 2003


Committed by: bart

Update of /local/src/CVS/nickle
In directory home.keithp.com:/tmp/cvs-serv2126

Modified Files:
	file.c nickle.h value.h 
Log Message:
Replace pipe() builtin with filter() and mkpipe().  Yes, the
name mkpipe() is a poor choice, but didn't want existing
apps to be confused about what happened.  Will implement
popen() atop these primitives eventually.



Index: file.c
===================================================================
RCS file: /local/src/CVS/nickle/file.c,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -d -r1.52 -r1.53
--- file.c	11 Oct 2003 09:50:05 -0000	1.52
+++ file.c	13 Oct 2003 04:33:36 -0000	1.53
@@ -14,6 +14,7 @@
 #include	<sys/wait.h>
 #include	<errno.h>
 #include	<sys/socket.h>
+#include        <assert.h>
 #include	"nickle.h"
 #include	"ref.h"
 #include	"gram.h"
@@ -748,93 +749,103 @@
 }
 
 Value
-FilePopen (char *program, char *argv[], char *mode, int *errp)
+FileFilter (char *program, char *args[], Value filev, int *errp)
 {
     ENTER ();
-    int	    fd, fds[2], errfds[2];
     int	    pid;
-    Value   file;
-    int	    flags = 0;
     int     errcode, nread;
+    int	    i;
+    int     errpipe[2];
+    int     fdlimit;
+    int     fds[3];
 
-    switch (mode[0]) {
-    case 'r':
-	if (mode[1] == '+')
-	    flags |= FileWritable;
-	flags |= FileReadable;
-	break;
-    case 'w':
-    case 'a':
-	if (mode[1] == '+')
-	    flags |= FileReadable;
-	flags |= FileWritable;
-	break;
+    /* set up process files */
+    for (i = 0; i < 3; i++) {
+	Value f = BoxValue (filev->array.values, i);
+	if (i == 0 && !(f->file.flags & FileReadable)) {
+	    RaiseStandardException (exception_invalid_argument,
+				    "File::filter: process input not readable",
+				    2, f, Void);
+	    RETURN (Void);
+	}
+	if (i == 1 && !(f->file.flags & FileWritable)) {
+	    RaiseStandardException (exception_invalid_argument,
+				    "File::filter: process output not writable",
+				    2, f, Void);
+	    RETURN (Void);
+	}
+	if (i == 2 && !(f->file.flags & FileWritable)) {
+	    RaiseStandardException (exception_invalid_argument,
+				    "File::filter: process error not writable",
+				    2, f, Void);
+	    RETURN (Void);
+	}
+	fds[i] = f->file.fd;
     }
-    if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0)
-    {
+
+    if (pipe (errpipe) < 0) {
 	*errp = errno;
-	RETURN(0);
+	RETURN (0);
     }
-    if (pipe(errfds) < 0) {
+    pid = fork ();
+    if (pid == -1) {
 	*errp = errno;
-	RETURN(0);
+	RETURN (0);
     }
-    switch ((pid = fork ())) {
-    case -1:
-	close (fds[0]);
-	close (fds[1]);
-	close (errfds[0]);
-	close (errfds[1]);
-	*errp = errno;
-	fd = -1;
-	break;
-    case 0:
-	if (flags & FileReadable)
-	    dup2 (fds[1], 1);
-	else
-	    shutdown (fds[1], SHUT_WR);
-	if (flags & FileWritable)
-	    dup2 (fds[1], 0);
-	else
-	    shutdown (fds[1], SHUT_RD);
-	close (fds[0]);
-	close (fds[1]);
-	close (errfds[0]);
-	fcntl (errfds[1], F_SETFD, FD_CLOEXEC);
-	execvp (program, argv);
+    if (pid == 0) {
+	/* child */
+	for (i = 0; i < 3; i++)
+	    dup2 (fds[i], i);
+	fdlimit = sysconf(_SC_OPEN_MAX);
+	for (; i < fdlimit; i++)
+	    if (i != errpipe[1])
+		close (i);
+	fcntl (errpipe[1], F_SETFD, FD_CLOEXEC);
+	execvp (program, args);
 	errcode = errno & 0xff;
-	write(errfds[1], &errcode, 1);
-	close(errfds[1]);
+	write (errpipe[1], &errcode, 1);
 	exit (1);
-    default:
-	close(errfds[1]);
-	nread = read(errfds[0], &errcode, 1);
-	if (nread != 0) {
-	    if (nread == 1)
-		*errp = errcode;
-	    close(errfds[0]);
-	    RETURN(0);
-	}
-	close(errfds[0]);
-        if (!(flags & FileReadable))
-	    shutdown (fds[0], SHUT_RD);
-	if (!(flags & FileWritable))
-	    shutdown (fds[0], SHUT_WR);
-	fd = fds[0];
-	break;
     }
-    if (fd >= 0)
-    {
-	file = FileCreate (fd, flags);
-	file->file.flags |= FilePipe;
-	file->file.pid = pid;
+    /* parent */
+    close (errpipe[1]);
+    nread = read(errpipe[0], &errcode, 1);
+    if (nread != 0) {
+	*errp = errcode;
+	assert (nread == 1);
+	close (errpipe[0]);
+	RETURN(0);
     }
-    else
-    {
+    close (errpipe[0]);
+    for (i = 0; i < 3; i++) {
+	Value f = BoxValue (filev->array.values, i);
+	if (f->file.flags & FilePipe)
+	    f->file.pid = pid;
+    }
+    RETURN (NewInt(pid));
+}
+
+Value
+FileMakePipe (int *errp)
+{
+    ENTER ();
+    Value   file, files;
+    int	    two = 2;
+    int     fds[2];
+
+    if (pipe (fds) < 0) {
 	*errp = errno;
-	file = 0;
+	RETURN (0);
     }
-    RETURN (file);
+
+    /* gather and return results */
+    files = NewArray (False, False, typePrim[rep_file], 1, &two);
+    file = FileCreate (fds[0], FileReadable);
+    file->file.flags |= FilePipe;
+    BoxValueSet (files->array.values, 0, file);
+    file = FileCreate (fds[1], FileWritable);
+    file->file.flags |= FilePipe;
+    BoxValueSet (files->array.values, 1, file);
+    RETURN (files);
 }
 
 int

Index: nickle.h
===================================================================
RCS file: /local/src/CVS/nickle/nickle.h,v
retrieving revision 1.108
retrieving revision 1.109
diff -u -d -r1.108 -r1.109
--- nickle.h	24 Jul 2003 18:10:19 -0000	1.108
+++ nickle.h	13 Oct 2003 04:33:36 -0000	1.109
@@ -947,6 +947,7 @@
 Value	do_Debug_done (void);
 Value	do_Debug_collect (void);
 Value   do_Debug_help (void);
+Value	do_File_mkpipe (void);
 
 /* one argument builtins */
 Value	do_putbyte (Value);
@@ -1043,8 +1044,8 @@
 /* three argument builtins */
 Value	do_File_vfprintf (Value, Value, Value);
 Value	do_String_substr (Value, Value, Value);
-Value	do_File_pipe (Value, Value, Value);
 Value	do_File_reopen (Value, Value, Value);
+Value	do_File_filter (Value file, Value argv, Value filev);
 
 /* four argument builtins */
 Value	do_Command_lex_input (Value file, Value name, Value after, Value interactive);

Index: value.h
===================================================================
RCS file: /local/src/CVS/nickle/value.h,v
retrieving revision 1.92
retrieving revision 1.93
diff -u -d -r1.92 -r1.93
--- value.h	25 Jul 2003 23:47:54 -0000	1.92
+++ value.h	13 Oct 2003 04:33:36 -0000	1.93
@@ -991,10 +991,11 @@
 void	FilePutType (Value f, Type *t, Bool minimal);
 void	FilePutBaseType (Value f, Type *t, Bool minimal);
 void	FilePutSubscriptType (Value f, Type *t, Bool minimal);
+Value   FileFilter (char *program, char *args[], Value filev, int *errp);
 Value	FileFopen (char *name, char *mode, int *errp);
 Value	FileReopen (char *name, char *mode, Value file, int *errp);
+Value   FileMakePipe (int *errp);
 void	FilePutArgType (Value f, ArgType *at);
-Value	FilePopen (char *program, char *args[], char *mode, int *errp);
 int	FileStatus (Value file);
 void	FileCheckBlocked (Bool block);
 void	FileSetBlocked (Value file, int flag);




More information about the Commit mailing list