Annotation of src/usr.bin/aucat/pipe.c, Revision 1.9
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: }
1.9 ! ratchov 142:
! 143: off_t
! 144: pipe_endpos(struct file *file)
! 145: {
! 146: struct pipe *f = (struct pipe *)file;
! 147: off_t pos;
! 148:
! 149: pos = lseek(f->fd, 0, SEEK_END);
! 150: if (pos < 0) {
! 151: #ifdef DEBUG
! 152: file_dbg(&f->file);
! 153: dbg_puts(": couldn't get file size\n");
! 154: #endif
! 155: return 0;
! 156: }
! 157: return pos;
! 158: }
! 159:
! 160: int
! 161: pipe_seek(struct file *file, off_t pos)
! 162: {
! 163: struct pipe *f = (struct pipe *)file;
! 164: off_t newpos;
! 165:
! 166: newpos = lseek(f->fd, pos, SEEK_SET);
! 167: if (newpos < 0) {
! 168: #ifdef DEBUG
! 169: file_dbg(&f->file);
! 170: dbg_puts(": couldn't seek\n");
! 171: #endif
! 172: /* XXX: call eof() */
! 173: return 0;
! 174: }
! 175: return 1;
! 176: }
! 177:
! 178: int
! 179: pipe_trunc(struct file *file, off_t pos)
! 180: {
! 181: struct pipe *f = (struct pipe *)file;
! 182:
! 183: if (ftruncate(f->fd, pos) < 0) {
! 184: #ifdef DEBUG
! 185: file_dbg(&f->file);
! 186: dbg_puts(": couldn't truncate file\n");
! 187: #endif
! 188: /* XXX: call hup() */
! 189: return 0;
! 190: }
! 191: return 1;
! 192: }