LispFile * LispFopen(char *path, int mode) { LispFile *file; int descriptor; int flags = O_NOCTTY; /* check read/write attributes */ if ((mode & (READ_BIT | WRITE_BIT)) == (READ_BIT | WRITE_BIT)) flags |= O_RDWR; else if (mode & READ_BIT) flags |= O_RDONLY; else if (mode & WRITE_BIT) flags |= O_WRONLY; /* create if does not exist */ if (mode & WRITE_BIT) { flags |= O_CREAT; /* append if exists? */ if (mode & APPEND_BIT) flags |= O_APPEND; else flags |= O_TRUNC; } /* open file */ descriptor = open(path, flags, 0666); if (descriptor < 0) return (NULL); /* initialize LispFile structure */ file = LispFdopen(descriptor, mode); if (file == NULL) close(descriptor); return (file); }
/* XXX Non standard functions below */ LispObj * Lisp_MakePipe(LispBuiltin *builtin) /* make-pipe command-line &key :direction :element-type :external-format */ { char *string; LispObj *stream = NIL; int flags, direction; LispFile *error_file; LispPipe *program; int ifd[2]; int ofd[2]; int efd[2]; char *argv[4]; LispObj *command_line, *odirection, *element_type, *external_format; external_format = ARGUMENT(3); element_type = ARGUMENT(2); odirection = ARGUMENT(1); command_line = ARGUMENT(0); if (PATHNAMEP(command_line)) command_line = CAR(command_line->data.quote); else if (!STRINGP(command_line)) LispDestroy("%s: %s is a bad pathname", STRFUN(builtin), STROBJ(command_line)); if (odirection != UNSPEC) { direction = -1; if (KEYWORDP(odirection)) { if (odirection == Kprobe) direction = DIR_PROBE; else if (odirection == Kinput) direction = DIR_INPUT; else if (odirection == Koutput) direction = DIR_OUTPUT; else if (odirection == Kio) direction = DIR_IO; } if (direction == -1) LispDestroy("%s: bad :DIRECTION %s", STRFUN(builtin), STROBJ(odirection)); } else direction = DIR_INPUT; if (element_type != UNSPEC) { /* just check argument... */ if (SYMBOLP(element_type) && ATOMID(element_type) == Scharacter) ; /* do nothing */ else if (KEYWORDP(element_type) && ATOMID(element_type) == Sdefault) ; /* do nothing */ else LispDestroy("%s: only :%s and %s supported for :ELEMENT-TYPE, not %s", STRFUN(builtin), Sdefault, Scharacter, STROBJ(element_type)); } if (external_format != UNSPEC) { /* just check argument... */ if (SYMBOLP(external_format) && ATOMID(external_format) == Scharacter) ; /* do nothing */ else if (KEYWORDP(external_format) && ATOMID(external_format) == Sdefault) ; /* do nothing */ else LispDestroy("%s: only :%s and %s supported for :EXTERNAL-FORMAT, not %s", STRFUN(builtin), Sdefault, Scharacter, STROBJ(external_format)); } string = THESTR(command_line); program = LispMalloc(sizeof(LispPipe)); if (direction != DIR_PROBE) { argv[0] = "sh"; argv[1] = "-c"; argv[2] = string; argv[3] = NULL; pipe(ifd); pipe(ofd); pipe(efd); if ((program->pid = fork()) == 0) { close(0); close(1); close(2); dup2(ofd[0], 0); dup2(ifd[1], 1); dup2(efd[1], 2); close(ifd[0]); close(ifd[1]); close(ofd[0]); close(ofd[1]); close(efd[0]); close(efd[1]); execve("/bin/sh", argv, environ); exit(-1); } else if (program->pid < 0) LispDestroy("%s: fork: %s", STRFUN(builtin), strerror(errno)); program->input = LispFdopen(ifd[0], FILE_READ | FILE_UNBUFFERED); close(ifd[1]); program->output = LispFdopen(ofd[1], FILE_WRITE | FILE_UNBUFFERED); close(ofd[0]); error_file = LispFdopen(efd[0], FILE_READ | FILE_UNBUFFERED); close(efd[1]); } else { program->pid = -1; program->input = program->output = error_file = NULL; } flags = direction == DIR_PROBE ? 0 : STREAM_READ; program->errorp = FILESTREAM(error_file, command_line, flags); flags = 0; if (direction != DIR_PROBE) { if (direction == DIR_INPUT || direction == DIR_IO) flags |= STREAM_READ; if (direction == DIR_OUTPUT || direction == DIR_IO) flags |= STREAM_WRITE; } stream = PIPESTREAM(program, command_line, flags); LispMused(program); return (stream); }