2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: sfhdr.h /main/3 1995/11/01 18:30:18 rswiston $ */
24 /***************************************************************
26 * AT&T - PROPRIETARY *
28 * THIS IS PROPRIETARY SOURCE CODE LICENSED BY *
31 * Copyright (c) 1995 AT&T Corp. *
32 * All Rights Reserved *
34 * This software is licensed by AT&T Corp. *
35 * under the terms and conditions of the license in *
36 * http://www.research.att.com/orgs/ssr/book/reuse *
38 * This software was created by the *
39 * Software Engineering Research Department *
40 * AT&T Bell Laboratories *
42 * For further information contact *
43 * gsf@research.att.com *
45 ***************************************************************/
49 /* Internal definitions for sfio.
50 ** Written by Kiem-Phong Vo (07/16/90)
51 ** AT&T Bell Laboratories
54 #include "FEATURE/sfio"
57 /* file system info */
60 #if defined(__STDPP__directive) && defined(__STDPP__hide)
61 __STDPP__directive pragma pp:hide ecvt fcvt getpagesize
63 #define ecvt ______ecvt
64 #define fcvt ______fcvt
65 #define getpagesize ______getpagesize
72 #if defined(__STDPP__directive) && defined(__STDPP__hide)
73 __STDPP__directive pragma pp:nohide ecvt fcvt getpagesize
80 #if _mem_st_blksize_stat
81 #define _stat_blksize 1
84 #if _lib_localeconv && _hdr_locale
101 #include <sys/types.h>
107 #include <sys/stat.h>
119 #include <sys/filio.h>
120 #endif /*_sys_filio*/
121 #endif /*_hdr_filio*/
125 #endif /*_PACKAGE_ast*/
127 #if _lib_poll_fd_1 || _lib_poll_fd_2
132 #include <sys/time.h>
147 #include <sys/socket.h>
151 #define Double_t long double
154 #define Double_t double
165 /* NOTE: these flags share the same space with the public flags */
166 #define SF_MMAP 0010000 /* in memory mapping mode */
167 #define SF_PROCESS 0020000 /* this stream is sfpopen */
168 #define SF_BOTH 0040000 /* both read/write */
169 #define SF_HOLE 0100000 /* a hole of zero's was created */
171 /* bits for the mode field, SF_INIT defined in sfio_t.h */
172 #define SF_RC 0000010 /* peeking for a record */
173 #define SF_RV 0000020 /* reserve a block of data without read */
174 #define SF_LOCK 0000040 /* stream is locked for io op */
175 #define SF_PUSH 0000100 /* stream has been pushed */
176 #define SF_POOL 0000200 /* stream is in a pool but not current */
177 #define SF_PEEK 0000400 /* there is a pending peek */
178 #define SF_PKRD 0001000 /* did a peek read */
179 #define SF_GETR 0002000 /* did a getr on this stream */
180 #define SF_SYNCED 0004000 /* stream was synced */
181 #define SF_STDIO 0010000 /* given up the buffer to stdio */
182 #define SF_AVAIL 0020000 /* was closed, available for reuse */
183 #define SF_OPEN 0040000 /* file descriptor was from sfopen() */
184 #define SF_LOCAL 0100000 /* sentinel for a local call */
190 #define ASSERT(p) ((p) ? 0 : (abort(),0) )
196 #define uchar unsigned char
197 #define ulong unsigned long
198 #define uint unsigned int
202 #define SECOND 1000 /* millisecond units */
221 #define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
224 #define S_ISREG(m) (((m)&S_IFMT) == S_IFREG)
227 #define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR)
232 #define S_ISFIFO(m) (((m)&S_IFIFO) == S_IFIFO)
234 #define S_ISFIFO(m) (0)
238 /* set close-on-exec */
242 #endif /*FD_CLOEXEC*/
243 #define SETCLOEXEC(fd) ((void)fcntl((fd),F_SETFD,FD_CLOEXEC))
246 #define SETCLOEXEC(fd) ((void)ioctl((fd),FIOCLEX,0))
248 #define SETCLOEXEC(fd)
252 /* see if we can use memory mapping for io */
258 # include <sys/mman.h>
263 /* function to get the decimal point for local environment */
266 #define GETDECIMAL(dc,lv) \
268 (dc = ((lv = localeconv()) && lv->decimal_point && *lv->decimal_point) ? \
269 *lv->decimal_point : '.' ) )
271 #define GETDECIMAL(dc,lv) ('.')
274 /* stream pool structure. */
275 typedef struct _sfpl_
276 { struct _sfpl_* next;
277 int mode; /* type of pool */
278 int s_sf; /* size of pool array */
279 int n_sf; /* number currently in pool */
280 Sfio_t** sf; /* array of streams */
281 Sfio_t* array[3]; /* start with 3 */
284 /* reserve buffer structure */
285 typedef struct _rsrv_
286 { struct _rsrv_* next; /* link list */
287 Sfio_t* sf; /* stream associated with */
288 int slen; /* last string length */
289 int size; /* buffer size */
290 uchar data[1]; /* data buffer */
293 /* extension structures for sfvprintf/sfvscanf */
294 typedef int(*Argf_s)_ARG_((char,char*,uint));
295 typedef int(*Extf_s)_ARG_((Sfio_t*,int,int,char**));
296 typedef int(*Argf_p)_ARG_((int,char*,char*,int));
297 typedef int(*Extf_p)_ARG_((char*,int,int,char**,int,char*,int));
300 char *form; /* format string */
301 va_list args; /* corresponding arglist */
303 { Argf_s s; /* argf for sfvscanf */
304 Argf_p p; /* argf for sfvprintf */
307 { Extf_s s; /* extf for sfvscanf */
308 Extf_p p; /* extf for sfvprintf */
310 struct _fa_ *next; /* next on the stack */
313 /* memory management for the Fa_t structures */
314 #define FAMALLOC(f) ((f = _Fafree) ? (_Fafree = f->next, f) : \
315 (f = (Fa_t*)malloc(sizeof(Fa_t))))
316 #define FAFREE(f) (f->next = _Fafree, _Fafree = f)
318 /* local variables used across sf-functions */
319 #define _Sfpool (_Sfextern.sf_pool)
320 #define _Sffree (_Sfextern.sf_free)
321 #define _Fafree (_Sfextern.fa_free)
322 #define _Sfpage (_Sfextern.sf_page)
323 #define _Sfpmove (_Sfextern.sf_pmove)
324 #define _Sfstack (_Sfextern.sf_stack)
325 #define _Sfnotify (_Sfextern.sf_notify)
326 #define _Sfstdio (_Sfextern.sf_stdio)
327 #define _Sfudisc (&(_Sfextern.sf_udisc))
328 #define _Sfcleanup (_Sfextern.sf_cleanup)
329 #define _Sfexiting (_Sfextern.sf_exiting)
330 typedef struct _sfext_
336 int(* sf_pmove)_ARG_((Sfio_t*, int));
337 Sfio_t*(* sf_stack)_ARG_((Sfio_t*, Sfio_t*));
338 void(* sf_notify)_ARG_((Sfio_t*, int, int));
339 int(* sf_stdio)_ARG_((Sfio_t*));
341 void(* sf_cleanup)_ARG_((void));
345 /* function to clear an sfio structure */
347 ((f)->next = (f)->endw = (f)->endr = (f)->endb = (f)->data = NIL(uchar*), \
348 (f)->flags = 0, (f)->file = -1, (f)->extent = -1L, (f)->here = 0L, \
349 (f)->getr = 0, (f)->mode = 0, (f)->size = -1, (f)->disc = NIL(Sfdisc_t*), \
350 (f)->pool = NIL(Sfpool_t*), (f)->push = NIL(Sfio_t*))
352 /* get the real value of a byte in a coded long or ulong */
353 #define SFUVALUE(v) (((ulong)(v))&(SF_MORE-1))
354 #define SFSVALUE(v) ((( long)(v))&(SF_SIGN-1))
356 /* amount of precision to get in each iteration during coding of doubles */
357 #define SF_PRECIS (SF_UBITS-1)
359 /* grain size for buffer increment */
360 #define SF_GRAIN 1024
361 #define SF_PAGE (SF_GRAIN*sizeof(int)*2)
363 /* number of pages to memory map at a time */
366 /* the bottomless bit bucket */
367 #define DEVNULL "/dev/null"
368 #define SFSETNULL(f) ((f)->extent = -1, (f)->flags |= SF_HOLE)
369 #define SFISNULL(f) ((f)->extent < 0 && ((f)->flags&SF_HOLE) )
371 /* exception types */
372 #define SF_EDONE 0 /* stop this operation and return */
373 #define SF_EDISC 1 /* discipline says it's ok */
374 #define SF_ESTACK 2 /* stack was popped */
375 #define SF_ECONT 3 /* can continue normally */
377 #define SETLOCAL(f) ((f)->mode |= SF_LOCAL)
378 #define GETLOCAL(f,v) ((v) = ((f)->mode&SF_LOCAL), (f)->mode &= ~SF_LOCAL, (v))
379 #define SFSK(f,a,o,d) (SETLOCAL(f),sfsk(f,(long)a,o,d))
380 #define SFRD(f,b,n,d) (SETLOCAL(f),sfrd(f,(Void_t*)b,n,d))
381 #define SFWR(f,b,n,d) (SETLOCAL(f),sfwr(f,(Void_t*)b,n,d))
382 #define SFSYNC(f) (SETLOCAL(f),sfsync(f))
383 #define SFCLOSE(f) (SETLOCAL(f),sfclose(f))
384 #define SFFLSBUF(f,n) (SETLOCAL(f),_sfflsbuf(f,n))
385 #define SFFILBUF(f,n) (SETLOCAL(f),_sffilbuf(f,n))
386 #define SFSETBUF(f,s,n) (SETLOCAL(f),sfsetbuf(f,s,n))
387 #define SFWRITE(f,s,n) (SETLOCAL(f),sfwrite(f,s,n))
388 #define SFREAD(f,s,n) (SETLOCAL(f),sfread(f,s,n))
389 #define SFSEEK(f,p,t) (SETLOCAL(f),sfseek(f,p,t))
390 #define SFNPUTC(f,c,n) (SETLOCAL(f),sfnputc(f,c,n))
392 /* lock/open a stream */
393 #define SFMODE(f,l) ((f)->mode & ~(SF_RV|SF_RC|((l) ? SF_LOCK : 0)) )
394 #define SFLOCK(f,l) ((f)->mode |= SF_LOCK, (f)->endr = (f)->endw = (f)->data)
395 #define _SFOPEN(f) ((f)->endr=((f)->mode == SF_READ) ? (f)->endb : (f)->data, \
396 (f)->endw=(((f)->mode == SF_WRITE) && !((f)->flags&SF_LINE)) ? \
397 (f)->endb : (f)->data )
398 #define SFOPEN(f,l) ((l) ? 0 : ((f)->mode &= ~(SF_LOCK|SF_RC|SF_RV), _SFOPEN(f), 0) )
400 /* check to see if the stream can be accessed */
401 #define SFFROZEN(f) ((f)->mode&(SF_PUSH|SF_LOCK|SF_PEEK) ? 1 : \
402 ((f)->mode&SF_STDIO) ? (*_Sfstdio)(f) : 0)
405 /* set discipline code */
406 #define SFDISC(f,disc,iof,local) \
409 d = (disc) = (f)->disc; \
410 else d = (local) ? (disc) : ((disc) = (disc)->disc); \
411 while(d && !(d->iof)) d = d->disc; \
415 /* fast peek of a stream */
416 #define _SFAVAIL(f,s,n) ((n) = (f)->endb - ((s) = (f)->next) )
417 #define SFRPEEK(f,s,n) (_SFAVAIL(f,s,n) > 0 ? (n) : \
418 ((n) = SFFILBUF(f,-1), (s) = (f)->next, (n)) )
419 #define SFWPEEK(f,s,n) (_SFAVAIL(f,s,n) > 0 ? (n) : \
420 ((n) = SFFLSBUF(f,-1), (s) = (f)->next, (n)) )
422 /* malloc and free of streams */
423 #define SFFREE(f) (f->push = _Sffree, _Sffree = f)
424 #define SFALLOC(f) ((f = _Sffree) ? (_Sffree = f->push, f) : \
425 (f = (Sfio_t*)malloc(sizeof(Sfio_t))))
427 /* more than this for a line buffer, we might as well flush */
428 #define HIFORLINE 128
430 /* safe closing function */
431 #define CLOSE(f) { while(close(f) < 0 && errno == EINTR) errno = 0; }
433 /* string stream extent */
434 #define SFSTRSIZE(f) { reg long s = (f)->next - (f)->data; \
436 { (f)->here = s; if(s > (f)->extent) (f)->extent = s; } \
439 /* control flags for open() */
440 #ifndef O_CREAT /* research UNIX */
464 #define SF_RADIX 64 /* maximum integer conversion base */
467 #define SF_MAXINT INT_MAX
468 #define SF_MAXLONG LONG_MAX
470 #define SF_MAXINT ((int)(((uint)~0) >> 1))
471 #define SF_MAXLONG ((long)(((ulong)~0L) >> 1))
474 /* floating point to ascii conversion */
475 #define SF_MAXEXP10 6
476 #define SF_MAXPOW10 (1 << SF_MAXEXP10)
478 #define SF_FDIGITS 1024 /* max allowed fractional digits */
479 #define SF_IDIGITS (8*1024) /* max number of digits in int part */
481 #define SF_FDIGITS 256 /* max allowed fractional digits */
482 #define SF_IDIGITS 1024 /* max number of digits in int part */
484 #define SF_MAXDIGITS (((SF_FDIGITS+SF_IDIGITS)/sizeof(int) + 1)*sizeof(int))
486 /* tables for numerical translation */
487 #define _Sfpos10 (_Sftable.sf_pos10)
488 #define _Sfneg10 (_Sftable.sf_neg10)
489 #define _Sfdec (_Sftable.sf_dec)
490 #define _Sfv36 (_Sftable.sf_v36)
491 #define _Sfvmax (_Sftable.sf_vmax)
492 #define _Sfdigits (_Sftable.sf_digits)
493 typedef struct _sftab_
495 Double_t sf_pos10[SF_MAXEXP10]; /* positive powers of 10 */
496 Double_t sf_neg10[SF_MAXEXP10]; /* negative powers of 10 */
497 char sf_dec[200]; /* ascii reps of values < 100 */
498 char sf_v36[128]; /* digit translation for base <= 36 */
499 char sf_vmax[128]; /* digit translation for base > 36 */
500 char* sf_digits; /* digits for non-standard bases */
503 /* sfucvt() converts decimal integers to ASCII */
504 #define SFDIGIT(v,scale,digit) \
509 else { digit = '1'; v -= 1*scale; } \
510 else if(v < 3*scale) \
511 { digit = '2'; v -= 2*scale; } \
512 else if(v < 4*scale) \
513 { digit = '3'; v -= 3*scale; } \
514 else { digit = '4'; v -= 4*scale; } \
515 else if(v < 7*scale) \
517 { digit = '5'; v -= 5*scale; } \
518 else { digit = '6'; v -= 6*scale; } \
519 else if(v < 8*scale) \
520 { digit = '7'; v -= 7*scale; } \
521 else if(v < 9*scale) \
522 { digit = '8'; v -= 8*scale; } \
523 else { digit = '9'; v -= 9*scale; } \
525 #define sfucvt(v,s,n,list) \
527 while((ulong)v >= 10000) \
528 { n = v; v = ((ulong)v)/10000; n = ((ulong)n) - ((ulong)v)*10000; \
529 SFDIGIT(n,1000,s[-4]); \
530 SFDIGIT(n,100,s[-3]); \
531 *--s = list[(n <<= 1)+1]; \
538 SFDIGIT(v,1000,s[-4]); \
541 SFDIGIT(v,100,s[-3]); \
542 *--s = list[(v <<= 1)+1]; \
547 { *--s = list[(v <<= 1)+1]; \
553 /* handy functions */
554 #define min(x,y) ((x) < (y) ? (x) : (y))
555 #define max(x,y) ((x) > (y) ? (x) : (y))
557 /* fast functions for memory copy and memory clear */
559 #define memclear(s,n) memzero(s,n)
563 #define memcpy(to,fr,n) bcopy((fr),(to),(n))
567 #define memclear(s,n) bzero((s),(n))
569 #define memclear(s,n) memset((s),'\0',(n))
571 #endif /*_PACKAGE_ast*/
573 /* note that MEMCPY advances the associated pointers */
574 #define MEMCPY(to,fr,n) \
576 { default : memcpy((Void_t*)to,(Void_t*)fr,n); to += n; fr += n; break; \
577 case 7 : *to++ = *fr++; \
578 case 6 : *to++ = *fr++; \
579 case 5 : *to++ = *fr++; \
580 case 4 : *to++ = *fr++; \
581 case 3 : *to++ = *fr++; \
582 case 2 : *to++ = *fr++; \
583 case 1 : *to++ = *fr++; \
586 #define MEMSET(s,c,n) \
588 { default : memset((char*)s,(char)c,n); s += n; break; \
601 extern Sfext_t _Sfextern;
602 extern Sftab_t _Sftable;
604 extern int _sfpopen _ARG_((Sfio_t*, int, int));
605 extern int _sfpclose _ARG_((Sfio_t*));
606 extern int _sfmode _ARG_((Sfio_t*, int, int));
607 extern int _sftype _ARG_((const char*, int*));
608 extern int _sfexcept _ARG_((Sfio_t*, int, int, Sfdisc_t*));
609 extern Sfrsrv_t* _sfrsrv _ARG_((Sfio_t*, int));
610 extern int _sfsetpool _ARG_((Sfio_t*));
611 extern void _sfswap _ARG_((Sfio_t*, Sfio_t*, int));
612 extern char* _sfcvt _ARG_((Double_t, int, int*, int*, int));
615 extern Double_t _sfstrtod _ARG_((const char*, char**));
616 #define strtod _sfstrtod
622 extern double frexp _ARG_((double, int*));
623 extern double ldexp _ARG_((double,int));
625 extern int getpagesize _ARG_((void));
626 extern Void_t* memccpy _ARG_((Void_t*, const Void_t*, int, size_t));
629 extern void bcopy _ARG_((const Void_t*, Void_t*, int));
630 extern void bzero _ARG_((Void_t*, int));
631 extern Void_t* malloc _ARG_((int));
632 extern Void_t* realloc _ARG_((Void_t*, int));
633 extern void free _ARG_((Void_t*));
634 extern size_t strlen _ARG_((const char*));
635 extern char* strcpy _ARG_((char*, const char*));
637 extern Void_t* memset _ARG_((Void_t*, int, size_t));
638 extern Void_t* memchr _ARG_((const Void_t*, int, size_t));
640 extern Void_t* memcpy _ARG_((Void_t*, const Void_t*, size_t));
644 extern double strtod _ARG_((const char*, char**));
647 extern void _exit _ARG_((int));
648 extern int atexit _ARG_((void(*)(void)));
649 extern int onexit _ARG_((void(*)(void)));
650 extern int on_exit _ARG_((void(*)(void), char*));
652 #if _proto_open && __cplusplus
653 extern int open _ARG_((const char*, int, ...));
656 extern int close _ARG_((int));
657 extern int read _ARG_((int, Void_t*, int));
658 extern int write _ARG_((int, const Void_t*, int));
659 extern long lseek _ARG_((int, long, int));
660 extern int fstat _ARG_((int, struct stat*));
661 extern int dup _ARG_((int));
662 extern int unlink _ARG_((const char*));
663 extern int isatty _ARG_((int));
664 extern int waitpid _ARG_((int,int*,int));
665 extern int wait _ARG_((int*));
666 extern int sleep _ARG_((int));
670 extern int select _ARG_((int, fd_set*, fd_set*, fd_set*, const struct timeval*));
672 extern int select _ARG_((int, fd_set*, fd_set*, fd_set*, struct timeval*));
674 #endif /*_lib_select*/
678 extern int poll _ARG_((struct pollfd*, ulong, int));
680 extern int poll _ARG_((ulong, struct pollfd*, int));
685 extern int ioctl _ARG_((int, int, ...));
686 #endif /*_stream_peek*/
690 extern int recv _ARG_((int, Void_t*, int, int));
692 #endif /*_socket_peek*/
694 #endif /* _PACKAGE_ast */
698 #define SFPOLL(pfd,n,tm) poll((pfd),(ulong)(n),(tm))
700 #define SFPOLL(pfd,n,tm) poll((ulong)(n),(pfd),(tm))