Annotation of src/usr.bin/aucat/pipe.c, Revision 1.8
1.6 ratchov 1: /*
2: * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
3: *
4: * Permission to use, copy, modify, and distribute this software for any
5: * purpose with or without fee is hereby granted, provided that the above
6: * copyright notice and this permission notice appear in all copies.
7: *
8: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15: */
16:
1.1 ratchov 17: #include <sys/time.h>
18: #include <sys/types.h>
1.6 ratchov 19:
1.1 ratchov 20: #include <err.h>
21: #include <errno.h>
22: #include <fcntl.h>
23: #include <poll.h>
24: #include <stdio.h>
25: #include <stdlib.h>
26: #include <unistd.h>
27:
28: #include "conf.h"
29: #include "pipe.h"
1.8 ! ratchov 30: #ifdef DEBUG
! 31: #include "dbg.h"
! 32: #endif
1.1 ratchov 33:
34: struct fileops pipe_ops = {
35: "pipe",
36: sizeof(struct pipe),
37: pipe_close,
38: pipe_read,
39: pipe_write,
40: NULL, /* start */
41: NULL, /* stop */
42: pipe_nfds,
43: pipe_pollfd,
44: pipe_revents
45: };
46:
47: struct pipe *
48: pipe_new(struct fileops *ops, int fd, char *name)
49: {
50: struct pipe *f;
51:
52: f = (struct pipe *)file_new(ops, name, 1);
1.4 ratchov 53: if (f == NULL)
54: return NULL;
1.1 ratchov 55: f->fd = fd;
56: return f;
57: }
58:
59: unsigned
60: pipe_read(struct file *file, unsigned char *data, unsigned count)
61: {
62: struct pipe *f = (struct pipe *)file;
63: int n;
1.7 ratchov 64:
1.1 ratchov 65: while ((n = read(f->fd, data, count)) < 0) {
66: f->file.state &= ~FILE_ROK;
67: if (errno == EAGAIN) {
1.8 ! ratchov 68: #ifdef DEBUG
! 69: if (debug_level >= 4) {
! 70: file_dbg(&f->file);
! 71: dbg_puts(": reading blocked\n");
! 72: }
! 73: #endif
1.1 ratchov 74: } else {
75: warn("%s", f->file.name);
76: file_eof(&f->file);
77: }
78: return 0;
79: }
80: if (n == 0) {
1.7 ratchov 81: f->file.state &= ~FILE_ROK; /* XXX: already cleared in file_eof */
1.1 ratchov 82: file_eof(&f->file);
83: return 0;
84: }
85: return n;
86: }
87:
88:
89: unsigned
90: pipe_write(struct file *file, unsigned char *data, unsigned count)
91: {
92: struct pipe *f = (struct pipe *)file;
93: int n;
1.3 ratchov 94:
1.1 ratchov 95: while ((n = write(f->fd, data, count)) < 0) {
96: f->file.state &= ~FILE_WOK;
97: if (errno == EAGAIN) {
1.8 ! ratchov 98: #ifdef DEBUG
! 99: if (debug_level >= 4) {
! 100: file_dbg(&f->file);
! 101: dbg_puts(": writing blocked\n");
! 102: }
! 103: #endif
1.1 ratchov 104: } else {
105: if (errno != EPIPE)
106: warn("%s", f->file.name);
107: file_hup(&f->file);
108: }
109: return 0;
110: }
111: return n;
112: }
113:
114: int
115: pipe_nfds(struct file *file) {
116: return 1;
117: }
118:
119: int
120: pipe_pollfd(struct file *file, struct pollfd *pfd, int events)
121: {
122: struct pipe *f = (struct pipe *)file;
123:
124: pfd->fd = f->fd;
125: pfd->events = events;
1.2 ratchov 126: return (events != 0) ? 1 : 0;
1.1 ratchov 127: }
128:
129: int
130: pipe_revents(struct file *f, struct pollfd *pfd)
131: {
132: return pfd->revents;
133: }
134:
135: void
136: pipe_close(struct file *file)
137: {
138: struct pipe *f = (struct pipe *)file;
139:
140: close(f->fd);
141: }