1 /* $NetBSD: vstream.h,v 1.1.1.2 2011/03/02 19:32:46 tron Exp $ */ 2 3 #ifndef _VSTREAM_H_INCLUDED_ 4 #define _VSTREAM_H_INCLUDED_ 5 6 /*++ 7 /* NAME 8 /* vstream 3h 9 /* SUMMARY 10 /* simple buffered I/O package 11 /* SYNOPSIS 12 /* #include <vstream.h> 13 /* DESCRIPTION 14 /* .nf 15 16 /* 17 * System library. 18 */ 19 #include <sys/time.h> 20 #include <time.h> 21 #include <fcntl.h> 22 #include <stdarg.h> 23 #include <setjmp.h> 24 #include <unistd.h> 25 26 /* 27 * Utility library. 28 */ 29 #include <vbuf.h> 30 31 /* 32 * Simple buffered stream. The members of this structure are not part of the 33 * official interface and can change without prior notice. 34 */ 35 typedef ssize_t (*VSTREAM_FN) (int, void *, size_t, int, void *); 36 typedef int (*VSTREAM_WAITPID_FN) (pid_t, WAIT_STATUS_T *, int); 37 38 #ifdef NO_SIGSETJMP 39 #define VSTREAM_JMP_BUF jmp_buf 40 #else 41 #define VSTREAM_JMP_BUF sigjmp_buf 42 #endif 43 44 typedef struct VSTREAM { 45 VBUF buf; /* generic intelligent buffer */ 46 int fd; /* file handle, no 256 limit */ 47 VSTREAM_FN read_fn; /* buffer fill action */ 48 VSTREAM_FN write_fn; /* buffer fill action */ 49 ssize_t req_bufsize; /* requested read/write buffer size */ 50 void *context; /* application context */ 51 off_t offset; /* cached seek info */ 52 char *path; /* give it at least try */ 53 int read_fd; /* read channel (double-buffered) */ 54 int write_fd; /* write channel (double-buffered) */ 55 VBUF read_buf; /* read buffer (double-buffered) */ 56 VBUF write_buf; /* write buffer (double-buffered) */ 57 pid_t pid; /* vstream_popen/close() */ 58 VSTREAM_WAITPID_FN waitpid_fn; /* vstream_popen/close() */ 59 int timeout; /* read/write timout */ 60 VSTREAM_JMP_BUF *jbuf; /* exception handling */ 61 struct timeval iotime; /* time of last fill/flush */ 62 } VSTREAM; 63 64 extern VSTREAM vstream_fstd[]; /* pre-defined streams */ 65 66 #define VSTREAM_IN (&vstream_fstd[0]) 67 #define VSTREAM_OUT (&vstream_fstd[1]) 68 #define VSTREAM_ERR (&vstream_fstd[2]) 69 70 #define VSTREAM_FLAG_ERR VBUF_FLAG_ERR /* some I/O error */ 71 #define VSTREAM_FLAG_EOF VBUF_FLAG_EOF /* end of file */ 72 #define VSTREAM_FLAG_TIMEOUT VBUF_FLAG_TIMEOUT /* timeout error */ 73 #define VSTREAM_FLAG_FIXED VBUF_FLAG_FIXED /* fixed-size buffer */ 74 #define VSTREAM_FLAG_BAD VBUF_FLAG_BAD 75 76 #define VSTREAM_FLAG_READ (1<<8) /* read buffer */ 77 #define VSTREAM_FLAG_WRITE (1<<9) /* write buffer */ 78 #define VSTREAM_FLAG_SEEK (1<<10) /* seek info valid */ 79 #define VSTREAM_FLAG_NSEEK (1<<11) /* can't seek this file */ 80 #define VSTREAM_FLAG_DOUBLE (1<<12) /* double buffer */ 81 82 #define VSTREAM_PURGE_READ (1<<0) /* flush unread data */ 83 #define VSTREAM_PURGE_WRITE (1<<1) /* flush unwritten data */ 84 #define VSTREAM_PURGE_BOTH (VSTREAM_PURGE_READ|VSTREAM_PURGE_WRITE) 85 86 #define VSTREAM_BUFSIZE 4096 87 88 extern VSTREAM *vstream_fopen(const char *, int, mode_t); 89 extern int vstream_fclose(VSTREAM *); 90 extern off_t vstream_fseek(VSTREAM *, off_t, int); 91 extern off_t vstream_ftell(VSTREAM *); 92 extern int vstream_fpurge(VSTREAM *, int); 93 extern int vstream_fflush(VSTREAM *); 94 extern int vstream_fputs(const char *, VSTREAM *); 95 extern VSTREAM *vstream_fdopen(int, int); 96 extern int vstream_fdclose(VSTREAM *); 97 98 #define vstream_fread(v, b, n) vbuf_read(&(v)->buf, (b), (n)) 99 #define vstream_fwrite(v, b, n) vbuf_write(&(v)->buf, (b), (n)) 100 101 #define VSTREAM_PUTC(ch, vp) VBUF_PUT(&(vp)->buf, (ch)) 102 #define VSTREAM_GETC(vp) VBUF_GET(&(vp)->buf) 103 #define vstream_ungetc(vp, ch) vbuf_unget(&(vp)->buf, (ch)) 104 #define VSTREAM_EOF VBUF_EOF 105 106 #define VSTREAM_PUTCHAR(ch) VSTREAM_PUTC((ch), VSTREAM_OUT) 107 #define VSTREAM_GETCHAR() VSTREAM_GETC(VSTREAM_IN) 108 109 #define vstream_fileno(vp) ((vp)->fd) 110 #define vstream_req_bufsize(vp) ((const ssize_t) ((vp)->req_bufsize)) 111 #define vstream_context(vp) ((vp)->context) 112 #define vstream_ferror(vp) vbuf_error(&(vp)->buf) 113 #define vstream_feof(vp) vbuf_eof(&(vp)->buf) 114 #define vstream_ftimeout(vp) vbuf_timeout(&(vp)->buf) 115 #define vstream_clearerr(vp) vbuf_clearerr(&(vp)->buf) 116 #define VSTREAM_PATH(vp) ((vp)->path ? (const char *) (vp)->path : "unknown_stream") 117 #define vstream_ftime(vp) ((time_t) ((vp)->iotime.tv_sec)) 118 #define vstream_ftimeval(vp) ((vp)->iotime) 119 120 extern void vstream_control(VSTREAM *, int,...); 121 122 #define VSTREAM_CTL_END 0 123 #define VSTREAM_CTL_READ_FN 1 124 #define VSTREAM_CTL_WRITE_FN 2 125 #define VSTREAM_CTL_PATH 3 126 #define VSTREAM_CTL_DOUBLE 4 127 #define VSTREAM_CTL_READ_FD 5 128 #define VSTREAM_CTL_WRITE_FD 6 129 #define VSTREAM_CTL_WAITPID_FN 7 130 #define VSTREAM_CTL_TIMEOUT 8 131 #define VSTREAM_CTL_EXCEPT 9 132 #define VSTREAM_CTL_CONTEXT 10 133 #ifdef F_DUPFD 134 #define VSTREAM_CTL_DUPFD 11 135 #endif 136 #define VSTREAM_CTL_BUFSIZE 12 137 #define VSTREAM_CTL_SWAP_FD 13 138 139 extern VSTREAM *PRINTFLIKE(1, 2) vstream_printf(const char *,...); 140 extern VSTREAM *PRINTFLIKE(2, 3) vstream_fprintf(VSTREAM *, const char *,...); 141 142 extern VSTREAM *vstream_popen(int,...); 143 extern int vstream_pclose(VSTREAM *); 144 145 #define vstream_ispipe(vp) ((vp)->pid != 0) 146 147 #define VSTREAM_POPEN_END 0 /* terminator */ 148 #define VSTREAM_POPEN_COMMAND 1 /* command is string */ 149 #define VSTREAM_POPEN_ARGV 2 /* command is array */ 150 #define VSTREAM_POPEN_UID 3 /* privileges */ 151 #define VSTREAM_POPEN_GID 4 /* privileges */ 152 #define VSTREAM_POPEN_ENV 5 /* extra environment */ 153 #define VSTREAM_POPEN_SHELL 6 /* alternative shell */ 154 #define VSTREAM_POPEN_WAITPID_FN 7 /* child catcher, waitpid() compat. */ 155 #define VSTREAM_POPEN_EXPORT 8 /* exportable environment */ 156 157 extern VSTREAM *vstream_vfprintf(VSTREAM *, const char *, va_list); 158 159 extern ssize_t vstream_peek(VSTREAM *); 160 extern ssize_t vstream_bufstat(VSTREAM *, int); 161 162 #define VSTREAM_BST_FLAG_IN (1<<0) 163 #define VSTREAM_BST_FLAG_OUT (1<<1) 164 #define VSTREAM_BST_FLAG_PEND (1<<2) 165 166 #define VSTREAM_BST_MASK_DIR (VSTREAM_BST_FLAG_IN | VSTREAM_BST_FLAG_OUT) 167 #define VSTREAM_BST_IN_PEND (VSTREAM_BST_FLAG_IN | VSTREAM_BST_FLAG_PEND) 168 #define VSTREAM_BST_OUT_PEND (VSTREAM_BST_FLAG_OUT | VSTREAM_BST_FLAG_PEND) 169 170 #define vstream_peek(vp) vstream_bufstat((vp), VSTREAM_BST_IN_PEND) 171 172 /* 173 * Exception handling. We use pointer to jmp_buf to avoid a lot of unused 174 * baggage for streams that don't need this functionality. 175 * 176 * XXX sigsetjmp()/siglongjmp() save and restore the signal mask which can 177 * avoid surprises in code that manipulates signals, but unfortunately some 178 * systems have bugs in their implementation. 179 */ 180 #ifdef NO_SIGSETJMP 181 #define vstream_setjmp(stream) setjmp((stream)->jbuf[0]) 182 #define vstream_longjmp(stream, val) longjmp((stream)->jbuf[0], (val)) 183 #else 184 #define vstream_setjmp(stream) sigsetjmp((stream)->jbuf[0], 1) 185 #define vstream_longjmp(stream, val) siglongjmp((stream)->jbuf[0], (val)) 186 #endif 187 188 /* 189 * Tweaks and workarounds. 190 */ 191 extern int vstream_tweak_sock(VSTREAM *); 192 extern int vstream_tweak_tcp(VSTREAM *); 193 194 /* LICENSE 195 /* .ad 196 /* .fi 197 /* The Secure Mailer license must be distributed with this software. 198 /* AUTHOR(S) 199 /* Wietse Venema 200 /* IBM T.J. Watson Research 201 /* P.O. Box 704 202 /* Yorktown Heights, NY 10598, USA 203 /*--*/ 204 205 #endif 206