[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