Annotation of OpenXM/src/kan96xx/plugin/file2.c, Revision 1.12
1.12 ! takayama 1: /*$OpenXM: OpenXM/src/kan96xx/plugin/file2.c,v 1.11 2004/12/16 08:42:14 takayama Exp $ */
1.1 maekawa 2: #include <stdio.h>
3: #include <sys/time.h>
4: #include <sys/types.h>
5: #include <unistd.h>
1.12 ! takayama 6: #include <signal.h>
1.10 takayama 7: #include <errno.h>
1.1 maekawa 8: #include "file2.h"
9:
1.7 takayama 10: /* If you use file2 standalone to output string,
11: make the following dummy definition;
12: int KsocketSelect0(int a,int b) { return(0); }
13: int oxSocketSelect0(int a,int b) { return(0); }
14: or define FORSTRING
15: */
16: #ifdef FORSTRING
17: #define KsocketSelect0(a,b) 0
18: #define oxSocketSelect0(a,b) 0
19: #endif
20:
1.1 maekawa 21: #ifdef KXX
1.9 takayama 22: #define sGC_malloc(n) malloc(n)
1.1 maekawa 23: #else
1.9 takayama 24: void *sGC_malloc(int size);
1.1 maekawa 25: #endif
1.2 takayama 26: int WatchStream = 0;
1.1 maekawa 27: /* Note: 1997, 12/6 cf. SS475/kxx/openxxx.tex, SS475/memo1.txt
28: The functions in file2.c should not accept interruptions
29: during its critical operations. The synchronization mechanism
30: has not yet been implemented.
31: */
32:
33: static int debug1 = 0;
34: static int checkfp2(FILE2 *fp2,char *s);
1.7 takayama 35: static int fp2fputcString(int c,FILE2 *fp2);
1.1 maekawa 36: static int checkfp2(FILE2 *fp2,char *s)
37: {
38: if (fp2 == NULL) {
39: fprintf(stderr,"%s: NULL pointer.\n",s);
40: return(-1);
41: }
42: if (fp2->initialized != 1) {
43: fprintf(stderr,"%s: fp is not initialized.\n",s);
44: return(-1);
45: }
46: return(0);
47: }
48:
49: FILE2 *fp2open(int fd) {
50: FILE2 *fp2;
51: if (debug1) {
52: printf("fp2open is called. \n");
53: }
1.9 takayama 54: fp2 = (FILE2 *) sGC_malloc(sizeof(FILE2));
1.7 takayama 55: if (fd < -1) {
1.1 maekawa 56: fprintf(stderr,"fp2open Invalid file descriptor %d\n",fd);
57: return(NULL);
58: }
1.7 takayama 59: /* fd == -1 ==> store in string. */
1.1 maekawa 60: if (fp2 == NULL) {
61: fprintf(stderr,"fp2open. No memory.\n");
62: return(NULL);
63: }
64: fp2->fd = fd;
65: fp2->initialized = 1;
66: checkfp2(fp2,"fp2open ");
67: fp2->readpos = 0;
68: fp2->readsize = 0;
69: fp2->writepos = 0;
70: fp2->limit = FILE2BSIZE;
1.9 takayama 71: fp2->readBuf = (char *) sGC_malloc(FILE2BSIZE);
72: fp2->writeBuf = (char *) sGC_malloc(FILE2BSIZE);
1.7 takayama 73: if ((fp2->readBuf == NULL) || (fp2->writeBuf == NULL)) {
74: fprintf(stderr,"fp2open. No more memory.\n");
75: return(NULL);
76: }
1.1 maekawa 77: fp2->watch = 0;
78: fp2->watchFile = NULL;
79: fp2->mathcapList = NULL;
1.5 takayama 80: fp2->log_incomming = NULL;
81: fp2->log_outgoing = NULL;
1.11 takayama 82: fp2->popened = 0;
83: fp2->pfp = NULL;
1.1 maekawa 84: return(fp2);
85: }
86:
1.11 takayama 87: void fp2setfp(FILE2 *fp2,FILE *fp,int popened) {
88: fp2->pfp = fp;
89: fp2->popened = popened;
90: }
1.1 maekawa 91:
92: int fp2fflush(FILE2 *fp2) {
93: int r;
94: if (debug1) {
95: printf("fp2fflush is called with FILE2 *%x.\n", (int )fp2);
96: fp2dumpBuffer(fp2);
97: printf("--------------------------\n");
98: }
99: if (checkfp2(fp2,"fp2fflush ") == -1) return(-1);
1.7 takayama 100: if (fp2->fd == -1) return(0);
1.1 maekawa 101: if (fp2->writepos > 0) {
1.12 ! takayama 102: signal(SIGPIPE,SIG_IGN);
1.1 maekawa 103: r = write(fp2->fd,fp2->writeBuf,fp2->writepos);
1.12 ! takayama 104: signal(SIGPIPE,SIG_DFL);
1.1 maekawa 105: fp2->writepos = 0;
106: if (r <= 0) {
107: fprintf(stderr,"fp2fflush(): write failed on %d.\n",fp2->fd);
1.12 ! takayama 108: if (errno == EPIPE) {
! 109: fprintf(stderr,"Your peer is closed --- SIGPIPE. Closing this fp2.\n");
! 110: fp2fclose(fp2);
! 111: return r;
! 112: }
1.1 maekawa 113: }
114: return(r);
115: }else{
116: return(0);
117: }
118: }
119:
120: int fp2fclose(FILE2 *fp2) {
121: int r;
122: if (checkfp2(fp2," fp2fclose ") == -1) return(-1);
1.7 takayama 123: if (fp2->fd == -1) return(0);
1.1 maekawa 124: r = fp2fflush(fp2);
125: if (r < 0) {
126: fprintf(stderr,"fp2fclose: flush error.\n");
127: return(-1);
128: }
1.11 takayama 129: if (fp2->pfp != NULL) {
130: if (fp2->popened) {
131: return pclose(fp2->pfp);
132: } else return fclose(fp2->pfp);
133: }
134: else return(close(fp2->fd));
1.1 maekawa 135: }
136:
137: int fp2fputc(int c,FILE2 *fp2) {
1.2 takayama 138: FILE *fp;
1.1 maekawa 139: if (debug1) {
140: printf("fp2fputc is called with %2x, fp2->writepos=%d, ",c,fp2->writepos);
141: printf("fp2 = %x.\n",(int) fp2);
142: }
1.2 takayama 143: if (fp2->watch || WatchStream) {
1.4 takayama 144: if (fp2->watch) fp = fp2->watchFile;
145: else fp = stderr;
1.6 takayama 146: fprintf(stderr,"put to <%x> ",fp2->fd); /* output the channel for debug */
1.1 maekawa 147: if (c >= ' ' && c <='z') {
1.3 takayama 148: fprintf(fp," %2x(%c)-> ",c& 0xff,c);
1.1 maekawa 149: }else{
1.3 takayama 150: fprintf(fp," %2x( )-> ",c& 0xff);
1.1 maekawa 151: }
152: fflush(NULL);
153: }
1.5 takayama 154: if (fp2->log_outgoing != NULL) fputc(c,fp2->log_outgoing);
1.1 maekawa 155: if (checkfp2(fp2," fp2fputc ") == -1) return(-1);
156: (fp2->writeBuf)[fp2->writepos] = c;
157: (fp2->writepos)++;
1.7 takayama 158: if (fp2->fd == -1) return(fp2fputcString(c,fp2));
1.1 maekawa 159: if (fp2->writepos < fp2->limit) {
160: return(c);
161: }else{
162: if (fp2fflush(fp2) <0) return(-1);
163: else return(c);
164: }
165: }
166:
167: int fp2fgetc(FILE2 *fp2) {
168: int c;
1.2 takayama 169: FILE *fp;
1.1 maekawa 170: /* printf("fp2fgetc is called. "); fflush(NULL); */
171: if (checkfp2(fp2," fp2fgetc ") == -1) return(-1);
172: if (fp2->readpos < fp2->readsize) {
173: fp2->readpos++;
174: c = fp2->readBuf[fp2->readpos -1];
1.2 takayama 175: if (fp2->watch || WatchStream) {
1.4 takayama 176: if (fp2->watch) fp = fp2->watchFile;
177: else fp = stderr;
1.6 takayama 178: fprintf(fp,"get from <%x> ",fp2->fd); /* output the channel for debug*/
1.1 maekawa 179: if (c >= ' ' && c <= 'z') {
1.4 takayama 180: fprintf(fp," %2x(%c) ",c,c);
1.1 maekawa 181: }else{
1.4 takayama 182: fprintf(fp," %2x( ) ",c);
1.1 maekawa 183: }
184: fflush(NULL);
185: }
1.5 takayama 186: if (fp2->log_incomming != NULL) fputc(c,fp2->log_incomming);
1.1 maekawa 187: return(c);
188: }else{
1.7 takayama 189: if (fp2->fd == -1) return(-1);
1.1 maekawa 190: fp2->readpos = 0;
191: fp2 ->readsize =
192: read(fp2->fd, fp2->readBuf, fp2->limit);
193: if (fp2->readsize == 0) {
1.2 takayama 194: if (fp2->watch || WatchStream) {
1.4 takayama 195: if (fp2->watch) fp = fp2->watchFile;
196: else fp = stderr;
197: fprintf(fp," <%2x ",c);
198: fflush(NULL);
1.1 maekawa 199: }
200: return(-1);
201: }
202: else {
203: return(fp2fgetc(fp2));
204: }
205: }
206: }
207:
208: int fp2select(FILE2 *fp2, int t) {
1.7 takayama 209: if (fp2->fd == -1) {
210: if (fp2->readpos < fp2->readsize) return(1);
211: else return(0);
212: }
1.1 maekawa 213: if (fp2->readpos < fp2->readsize) return(1);
214: else {
215: #ifdef KXX
216: return(oxSocketSelect0(fp2->fd,t));
217: #else
218: return(KsocketSelect0(fp2->fd,t));
219: #endif
220: }
221: }
222:
223: int fp2dumpBuffer(FILE2 *fp2) {
224: int i;
225: if (checkfp2(fp2," f2pdumpBuf ") == -1) {
226: return(-1);
227: }
228: printf("fd=%d\n",fp2->fd);
229: printf("initialied=%d\n",fp2->initialized);
230: printf("readpos=%d\n",fp2->readpos);
231: printf("readsize=%d\n",fp2->readsize);
232: printf("writepos=%d\n",fp2->writepos);
233: printf("limit=%d\n",fp2->limit);
234: for (i=0; i<fp2->readsize; i++) {
235: printf("readBuf[%d]=%2x ",i,fp2->readBuf[i]);
236: }
237: for (i=0; i<fp2->writepos; i++) {
238: printf("writeBuf[%d]=%2x ",i,fp2->writeBuf[i]);
239: }
240: printf("\n");
241: return(0);
242: }
243:
244: int fp2clearReadBuf(FILE2 *fp2) {
245: fd_set readfds;
246: struct timeval timeout;
247: int fd;
248: #define TMP00SIZE 2000
249: char tmp00[TMP00SIZE];
250: int n;
251:
252: if (checkfp2(fp2," fp2clearReadBuf ") == -1) {
253: return(-1);
254: }
1.7 takayama 255: if (fp2->fd == -1) return(0);
1.1 maekawa 256:
257: fp2->readsize=0; fp2->readpos = 0; /* Clear the buffer. */
258:
259: fd = fp2->fd;
260: while (1) {
261: FD_ZERO(&readfds);
262: FD_SET(fd,&readfds);
263: timeout.tv_sec = 0;
264: timeout.tv_usec = (long) 0;
265: fp2->readpos = fp2->readsize = 0;
266: if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,&timeout)<0) {
267: fprintf(stderr,"fp2clearReadBuf: Select error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
268: return(-1);
269: }
270: if (FD_ISSET(fd,&readfds)) {
271: n = read(fd,tmp00, TMP00SIZE);
272: if (n <= 0) {
1.4 takayama 273: fprintf(stderr,"fp2clearReadBuf: File is closed or read error.\n");
274: return(-1);
1.1 maekawa 275: }
276: if ( n < TMP00SIZE ) {
1.4 takayama 277: return(0);
1.1 maekawa 278: }
279: }else {
280: return(0);
281: }
282: }
283: }
284: int fp2write(FILE2 *os, char *data, int size) {
285: int i,r;
286: for (i=0; i<size; i++) {
287: r = fp2fputc(data[i],os);
288: }
289: return(r);
290: }
291:
292: int fp2watch(FILE2 *fp2,FILE *f)
293: {
294: if (f == NULL) {
295: fprintf(stderr,"fp2watch FILE *f is NULL.\n");
296: return(-1);
297: }
298: if (fp2 == NULL) {
299: fprintf(stderr,"fp2watch FILE2 *fp2 is NULL.\n");
300: return(-1);
301: }
302: if (fp2->watch) {
303: fprintf(stderr,"fp2watch: fp2 is already taking a log.");
304: return(-1);
305: }
306: fp2->watch = 1;
307: fp2->watchFile = f;
308: return(0);
309: }
310:
311: int fp2stopWatch(FILE2 *fp2)
312: {
313: if (fp2 == NULL) {
314: fprintf(stderr,"fp2stopWatch FILE2 *fp2 is NULL.\n");
315: return(-1);
316: }
317: if (!fp2->watch) {
318: fprintf(stderr,"fp2stopWatch: fp2 is not taking a log.");
319: return(-1);
320: }
321: fp2->watch=0;
322: if (fp2->watchFile != stdout) {
323: return(fclose(fp2->watchFile));
324: }
325: }
326:
1.5 takayama 327: int fp2log(FILE2 *fp,FILE *incomming,FILE *outgoing) {
328: fp->log_incomming = incomming;
329: fp->log_outgoing = outgoing;
330: return 0;
331: }
332: int fp2stopLog(FILE2 *fp) {
333: if (fp->log_incomming != NULL) fclose(fp->log_incomming);
334: if (fp->log_outgoing != NULL) fclose(fp->log_outgoing);
335: fp->log_incomming = fp->log_outgoing = NULL;
336: return 0;
337: }
1.7 takayama 338:
339: static int fp2fputcString(int c,FILE2 *fp2) {
340: unsigned char *newwrite,*newread;
341: int newsize;
342: int i;
343: (fp2->readBuf)[fp2->readsize] = c;
344: (fp2->readsize)++;
345: if ((fp2->writepos < fp2->limit) && (fp2->readsize < fp2->limit)) return(c);
346: if ((fp2->limit)*2 >=0x3000000) {
347: fprintf(stderr,"Too big output string.\n");
348: return(-1);
349: }
350: newsize = (fp2->limit)*2;
1.9 takayama 351: newwrite = (char *)sGC_malloc(newsize);
352: newread = (char *)sGC_malloc(newsize);
1.7 takayama 353: if ((newwrite == NULL) || (newread == NULL)) {
354: fprintf(stderr,"fp2fputcString: No more memory.\n");
355: return(-1);
356: }
357: for (i=0; i<fp2->writepos; i++) {
358: newwrite[i] = fp2->writeBuf[i];
359: }
360: for (i=0; i<fp2->readsize; i++) {
361: newread[i] = fp2->readBuf[i];
362: }
363: fp2->writeBuf = newwrite;
364: fp2->readBuf = newread;
365: fp2->limit = newsize;
366: return(c);
367: }
368:
369: char *fp2fcloseInString(FILE2 *fp2, int *sizep)
370: {
371: if (fp2->fd == -1) {
372: fp2fputc(0,fp2);
373: *sizep = fp2->writepos-1;
374: return(fp2->writeBuf);
375: }else{
376: fprintf(stderr,"fp2fcloseInString is called for a file stream that is not associated to a string.\n");
377: }
1.8 takayama 378: }
379:
380: int fp2fputs(char *s,FILE2 *fp) {
381: int i,n;
382: n = strlen(s);
383: for (i=0; i<n; i++) {
384: if (fp2fputc(s[i],fp) < 0) return(-1);
385: }
386: return(0);
1.7 takayama 387: }
388:
389: /* Sample program FORSTRING
390: FILE2 *fp2;
391: int c;
392: char *s;
393: int size;
394: fp2 = fp2fopen(-1);
395: while ((c = getchar()) != EOF) {
396: fp2fputc(c,fp2);
397: }
398: s = fp2fcloseInString(fp2,&size);
399:
400: or
401:
402: while ((c = fp2fgetc(fp2)) != EOF) {
403: ....
404: }
405: */
1.12 ! takayama 406:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>