/* Simple data structure that handles pipes * Ben Lynn */ /* Copyright (C) 2002 Benjamin Lynn (blynn@cs.stanford.edu) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include "pipe.h" void pipe_init(pipe_t p) { p->name = NULL; p->is_open = 0; } void pipe_open(pipe_t p) { struct stat stbuf; int status; //assert(!p->is_open); if (p->is_open) { fprintf(stderr, "BUG! Pipe already open\n"); return; } //create the pipe if necessary status = mkfifo(p->name, 0700); if (status == -1 && errno != EEXIST) { perror("mkfifo"); return; } //check it's a named pipe status = stat(p->name, &stbuf); if (status == -1) { perror("stat"); return; } if (!S_ISFIFO(stbuf.st_mode)) { fprintf(stderr, "input pipe error: %s is not a named pipe\n", p->name); return; } p->readfd = open(p->name, O_RDONLY | O_NONBLOCK); if (p->readfd == -1) { return; } p->writefd = open(p->name, O_WRONLY | O_NONBLOCK); if (p->writefd == -1) { return; } p->is_open = 1; } void pipe_close(pipe_t p) { //assert(p->is_open); close(p->readfd); close(p->writefd); p->is_open = 0; unlink(p->name); } void pipe_assign(pipe_t p, char *name) { if (p->is_open) { fprintf(stderr, "warning: closing old pipe\n"); pipe_close(p); } if (p->name) free(p->name); p->name = malloc(strlen(name) + 1); strcpy(p->name, name); p->is_open = 0; } int pipe_write(pipe_t p, char *s) { return write(p->writefd, s, strlen(s)); } void pipe_readflush(pipe_t p) { char buf[128]; int count; //assert(p->is_open); for (;;) { count = read(p->readfd, buf, 128); if (count <= 0) break; } } void pipe_free(pipe_t p) { if (p->is_open) pipe_close(p); if (p->name) free(p->name); }