Annotation of src/usr.bin/aucat/pipe.c, Revision 1.14
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.12 deraadt 19: #include <sys/signal.h>
1.6 ratchov 20:
1.1 ratchov 21: #include <err.h>
22: #include <errno.h>
23: #include <fcntl.h>
24: #include <poll.h>
25: #include <stdio.h>
26: #include <stdlib.h>
27: #include <unistd.h>
28:
29: #include "conf.h"
30: #include "pipe.h"
1.8 ratchov 31: #ifdef DEBUG
32: #include "dbg.h"
33: #endif
1.1 ratchov 34:
35: struct fileops pipe_ops = {
36: "pipe",
37: sizeof(struct pipe),
38: pipe_close,
39: pipe_read,
40: pipe_write,
41: NULL, /* start */
42: NULL, /* stop */
43: pipe_nfds,
44: pipe_pollfd,
45: pipe_revents
46: };
47:
48: struct pipe *
49: pipe_new(struct fileops *ops, int fd, char *name)
50: {
51: struct pipe *f;
52:
53: f = (struct pipe *)file_new(ops, name, 1);
1.4 ratchov 54: if (f == NULL)
55: return NULL;
1.1 ratchov 56: f->fd = fd;
57: return f;
58: }
59:
1.14 ! ratchov 60: unsigned int
! 61: pipe_read(struct file *file, unsigned char *data, unsigned int count)
1.1 ratchov 62: {
63: struct pipe *f = (struct pipe *)file;
64: int n;
1.7 ratchov 65:
1.1 ratchov 66: while ((n = read(f->fd, data, count)) < 0) {
67: f->file.state &= ~FILE_ROK;
68: if (errno == EAGAIN) {
1.8 ratchov 69: #ifdef DEBUG
70: if (debug_level >= 4) {
71: file_dbg(&f->file);
72: dbg_puts(": reading blocked\n");
73: }
74: #endif
1.1 ratchov 75: } else {
76: warn("%s", f->file.name);
77: file_eof(&f->file);
78: }
79: return 0;
80: }
81: if (n == 0) {
1.7 ratchov 82: f->file.state &= ~FILE_ROK; /* XXX: already cleared in file_eof */
1.1 ratchov 83: file_eof(&f->file);
84: return 0;
85: }
86: return n;
87: }
88:
89:
1.14 ! ratchov 90: unsigned int
! 91: pipe_write(struct file *file, unsigned char *data, unsigned int count)
1.1 ratchov 92: {
93: struct pipe *f = (struct pipe *)file;
94: int n;
1.3 ratchov 95:
1.1 ratchov 96: while ((n = write(f->fd, data, count)) < 0) {
97: f->file.state &= ~FILE_WOK;
98: if (errno == EAGAIN) {
1.8 ratchov 99: #ifdef DEBUG
100: if (debug_level >= 4) {
101: file_dbg(&f->file);
102: dbg_puts(": writing blocked\n");
103: }
104: #endif
1.1 ratchov 105: } else {
106: if (errno != EPIPE)
107: warn("%s", f->file.name);
108: file_hup(&f->file);
109: }
110: return 0;
111: }
112: return n;
113: }
114:
115: int
116: pipe_nfds(struct file *file) {
117: return 1;
118: }
119:
120: int
121: pipe_pollfd(struct file *file, struct pollfd *pfd, int events)
122: {
123: struct pipe *f = (struct pipe *)file;
124:
125: pfd->fd = f->fd;
126: pfd->events = events;
1.2 ratchov 127: return (events != 0) ? 1 : 0;
1.1 ratchov 128: }
129:
130: int
131: pipe_revents(struct file *f, struct pollfd *pfd)
132: {
133: return pfd->revents;
134: }
135:
136: void
137: pipe_close(struct file *file)
138: {
139: struct pipe *f = (struct pipe *)file;
140:
141: close(f->fd);
1.13 ratchov 142: file_slowaccept = 0;
1.1 ratchov 143: }
1.11 ratchov 144:
145: off_t
146: pipe_endpos(struct file *file)
147: {
148: struct pipe *f = (struct pipe *)file;
149: off_t pos;
150:
151: pos = lseek(f->fd, 0, SEEK_END);
152: if (pos < 0) {
153: #ifdef DEBUG
154: file_dbg(&f->file);
155: dbg_puts(": couldn't get file size\n");
156: #endif
157: return 0;
158: }
159: return pos;
160: }
161:
162: int
163: pipe_seek(struct file *file, off_t pos)
164: {
165: struct pipe *f = (struct pipe *)file;
166: off_t newpos;
167:
168: newpos = lseek(f->fd, pos, SEEK_SET);
169: if (newpos < 0) {
170: #ifdef DEBUG
171: file_dbg(&f->file);
172: dbg_puts(": couldn't seek\n");
173: #endif
174: /* XXX: call eof() */
175: return 0;
176: }
177: return 1;
178: }
179:
180: int
181: pipe_trunc(struct file *file, off_t pos)
182: {
183: struct pipe *f = (struct pipe *)file;
184:
185: if (ftruncate(f->fd, pos) < 0) {
186: #ifdef DEBUG
187: file_dbg(&f->file);
188: dbg_puts(": couldn't truncate file\n");
189: #endif
190: /* XXX: call hup() */
191: return 0;
192: }
193: return 1;
194: }