stdioLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:11k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* stdioLib.c - standard I/O library */
  2. /* Copyright 1984-1995 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 02j,10feb97,tam  reclaimed resources from the standard file pointers (SPR #7915)
  8. 02i,11feb95,jdi  doc tweak.
  9. 02h,05mar93,jdi  documentation cleanup for 5.1.
  10. 02g,13nov92,dnw  added __std{in,out,err} (SPR #1770)
  11.  made stdInitStd() be LOCAL.
  12.  changed stdioFp() create FILE if it doesn't already exist.
  13. 02f,20sep92,smb  documentation additions
  14. 02e,29jul92,smb  added stdioFp().
  15.  Modified the documentation for the new stdio library.
  16. 02d,29jul92,jcf  taken from stdioLib.c 
  17. 02c,26may92,rrr  the tree shuffle
  18. 02b,02apr92,jmm  added free() of memory if bad options passed to fdopen()
  19.  SPR # 1396
  20. 02a,27mar92,jmm  changed fopen() to free memory if the open() fails, SPR #1115
  21. 01z,25nov91,rrr  cleanup of some ansi warnings.
  22. 01y,12nov91,rrr  removed VARARG_OK, no longer needed with ansi c.
  23. 01x,07oct91,rrr  junk for r3000 braindamage.
  24. 01w,04oct91,rrr  passed through the ansification filter
  25.                   -changed functions to ansi style
  26.   -changed includes to have absolute path from h/
  27.   -fixed #else and #endif
  28.   -changed VOID to void
  29.   -changed copyright notice
  30. 01v,18may91,gae  fixed varargs for 960 with conditional VARARG_OK,
  31.  namely: fscanf, fprintf, and scanf.
  32. 01u,04apr91,jdi  documentation cleanup; doc review by dnw.
  33. 01t,10aug90,dnw  added forward declaration of stdioExitStd ().
  34. 01s,08aug90,dnw  changed incorrect forward declaration for stdioCreateHook().
  35. 01r,10jun90,dnw  changed to call fioFormatV and fioScanV directly with
  36.    appropriate handling of varargs (removed doscan and doprnt)
  37.  moved all routine implementations of stdio macros to end of
  38.    module so that macros would be used in rest of code
  39.  spr 640: fprintf returns number of chars printed instead of OK
  40.  spr 754: vararg routines no longer limited to 16 args
  41.  fixed coercions to allow void to be defined as void one day.
  42. 01q,26jun90,jcf  lint.
  43. 01p,12mar90,jcf  changed std{in,out,err} to macros to fps in tcbx.
  44. 01o,16feb90,dab  fixed bug in doscan() that wouldn't match characters between
  45.  the input stream and the format specification.
  46. 01n,03aug89,dab  removed call to creat() in fopen().
  47. 01m,08apr89,dnw  changed stdioInit() to call taskVarInit().
  48. 01l,23mar89,dab  changed numerical constants to appropriate defines.
  49.  fixed fseek() to return only OK or ERROR.
  50. 01k,15nov88,dnw  documentation touchup.
  51. 01j,23sep88,gae  documentation touchup.
  52. 01i,13sep88,gae  removed ifdef'd sprintf which got into documentation.
  53. 01h,06sep88,gae  adjusted some argument declarations to please f2cgen.
  54. 01g,20aug88,gae  documentation.
  55. 01f,07jul88,jcf  changed malloc to match new declaration.
  56. 01e,29jun88,gae  documentation.  Added error messages in stioInit().
  57. 01d,22jun88,dnw  name tweaks.
  58. 01c,30may88,dnw  changed to v4 names.
  59. 01b,28may88,dnw  removed routines that had been excluded with "#if FALSE".
  60.  made stdioFlushBuf LOCAL.
  61.  cleaned up stdio{Init,Exit}Task; improved error msgs.
  62. 01a,28mar88,gae  created.
  63. */
  64. /*
  65. DESCRIPTION
  66. This library provides a complete UNIX compatible standard I/O buffering
  67. scheme.  It is beyond the scope of this manual entry to describe all aspects
  68. of the buffering -- see the
  69. .I "VxWorks Programmer's Guide:  I/O System"
  70. and the Kernighan & Ritchie C manual.  This manual entry primarily highlights
  71. the differences between the UNIX and VxWorks standard I/O.
  72. FILE POINTERS
  73. The routine fopen() creates a file pointer.  Use of the file pointer follows
  74. conventional UNIX usage.  In a shared address space, however, and perhaps more
  75. critically, with the VxWorks system symbol table, tasks may not use each
  76. others' file pointers, at least not without some interlocking mechanism.  If it
  77. is necessary to use the same name for a file pointer but have incarnations for
  78. each task, then use task variables; see the manual entry for taskVarLib.
  79. FIOLIB
  80. Several routines normally considered part of standard I/O -- printf(),
  81. sscanf(), and sprintf() -- are not implemented in stdio; they are
  82. instead implemented in fioLib.  They do not use the standard I/O buffering
  83. scheme.  They are self-contained, formatted, but unbuffered I/O
  84. functions.  This allows a limited amount of formatted I/O to be achieved
  85. without the overhead of the stdio library.
  86. TASK TERMINATION
  87. When a task exits, unlike in UNIX, it is the responsibility of the task to
  88. fclose() its file pointers, except `stdin', `stdout', and `stderr'.  If a
  89. task is to be terminated asynchronously, use kill() and arrange for a
  90. signal handler to clean up.
  91. INCLUDE FILES
  92. stdio.h, taskLib.h
  93. All the macros defined in stdio.h are also implemented as real functions so
  94. that they are available from the VxWorks shell.
  95. SEE ALSO
  96. fioLib, ioLib, taskVarLib, sigLib, Kernighan & Ritchie C manual,
  97. .pG "I/O System"
  98. */
  99. #include "vxWorks.h"
  100. #include "stdio.h"
  101. #include "sys/types.h"
  102. #include "ctype.h"
  103. #include "ioLib.h"
  104. #include "stdlib.h"
  105. #include "taskLib.h"
  106. #include "taskHookLib.h"
  107. #include "stdarg.h"
  108. #include "logLib.h"
  109. #include "fcntl.h"
  110. #include "unistd.h"
  111. #include "errnoLib.h"
  112. #include "string.h"
  113. #include "fioLib.h"
  114. #include "classLib.h"
  115. #include "private/objLibP.h"
  116. #include "private/stdioP.h"
  117. #include "private/funcBindP.h"
  118. /* locals */
  119. LOCAL OBJ_CLASS fpClass; /* file object class */
  120. LOCAL BOOL stdioInitialized = FALSE;
  121. LOCAL BOOL      stdioFpCleanupHookDone = FALSE;
  122. /* global variables */
  123. CLASS_ID fpClassId = &fpClass; /* file class id */
  124. /*******************************************************************************
  125. *
  126. * stdioInit - initialize standard I/O support
  127. *
  128. * This routine installs standard I/O support.  It must be called before
  129. * using `stdio' buffering.  If INCLUDE_STDIO is defined in configAll.h, it
  130. * is called automatically by the root task usrRoot() in usrConfig.c.
  131. *
  132. * RETURNS:
  133. * OK, or ERROR if the standard I/O facilities cannot be installed.
  134. */
  135. STATUS stdioInit (void)
  136.     {
  137.     if ((!stdioInitialized) &&
  138. (classInit (fpClassId, sizeof (FILE), OFFSET (FILE, objCore),
  139.     (FUNCPTR) NULL, (FUNCPTR) NULL, (FUNCPTR) NULL) == OK))
  140. {
  141. _func_fclose  = fclose; /* attach fclose vfunc to taskLib */
  142. stdioInitialized = TRUE; /* we've finished the initialization */
  143. }
  144.     return (OK);
  145.     }
  146. /*******************************************************************************
  147. *
  148. * stdioFpCreate - allocate a new FILE structure
  149. *
  150. * RETURNS:
  151. * The pointer to newly created file, or NULL if out of memory.
  152. *
  153. * NOMANUAL
  154. */
  155. FILE *stdioFpCreate (void)
  156.     {
  157.     FAST FILE *fp = NULL;
  158.     if ((stdioInit () == OK) &&
  159.         ((fp = (FILE *)objAlloc (fpClassId)) != NULL))
  160. {
  161. fp->_p = NULL; /* no current pointer */
  162. fp->_r = 0;
  163. fp->_w = 0; /* nothing to read or write */
  164. fp->_flags = 1; /* caller sets real flags */
  165. fp->_file = -1; /* no file */
  166. fp->_bf._base = NULL; /* no buffer */
  167. fp->_bf._size = 0;
  168. fp->_lbfsize = 0; /* not line buffered */
  169. fp->_ub._base = NULL; /* no ungetc buffer */
  170. fp->_ub._size = 0;
  171. fp->_lb._base = NULL; /* no line buffer */
  172. fp->_lb._size = 0;
  173. fp->_blksize = 0;
  174. fp->_offset = 0;
  175. fp->taskId = (int) taskIdCurrent; /* task id might be useful */
  176. objCoreInit (&fp->objCore, fpClassId); /* validate file object */
  177. }
  178.     return (fp);
  179.     }
  180. /*******************************************************************************
  181. *
  182. * stdioFpDestroy - destroy and reclaim resources of specified file pointer
  183. *
  184. * RETURNS:
  185. * OK, or ERROR if file pointer could not be destroyed.
  186. *
  187. * NOMANUAL
  188. */
  189. STATUS stdioFpDestroy
  190.     (
  191.     FILE *fp
  192.     )
  193.     {
  194.     /* fclose() deallocates any buffers associated with the file pointer */
  195.     objCoreTerminate (&fp->objCore); /* invalidate file pointer */
  196.     return (objFree (fpClassId, (char *) fp)); /* deallocate file pointer */
  197.     }
  198. /*******************************************************************************
  199. *
  200. * stdioStdfpCleanup - reclaim resources from the standard file pointers. 
  201. *
  202. * RETURNS: N/A
  203. *
  204. * NOMANUAL
  205. */
  206. LOCAL void stdioStdfpCleanup 
  207.     (
  208.     WIND_TCB *pTcb      /* address of task's TCB */
  209.     )
  210.     {
  211.     int ix;
  212.     /* close standard file pointers (stdin, stdout, stderr) if present */
  213.     for (ix = 0; ix < 3; ++ix)
  214.         if (pTcb->taskStdFp[ix] != NULL)
  215.             fclose (pTcb->taskStdFp[ix]);
  216.     }
  217. /*******************************************************************************
  218. *
  219. * stdioInitStd - initialize use of a standard file
  220. */
  221. LOCAL STATUS stdioInitStd
  222.     (
  223.     int stdFd /* standard file descriptor to initialize (0,1,2) */
  224.     )
  225.     {
  226.     FILE *fp;
  227.     if ((fp = stdioFpCreate ()) == NULL)
  228. return (ERROR);
  229.     switch (stdFd)
  230. {
  231. case STD_IN:  fp->_flags = __SRD;    break; /* read only */
  232. case STD_OUT: fp->_flags = __SWR;    break; /* write only */
  233. case STD_ERR: fp->_flags = __SWRNBF; break; /* write only unbuf'd */
  234. }
  235.     fp->_file = stdFd; /* standard fd */
  236.     taskIdCurrent->taskStdFp[stdFd] = fp; /* init private file pointer */
  237.     /* 
  238.      * need to deallocated stdout, stdin and stderr FILE structures and 
  239.      * ressources when a task exits or is deleted. Ressources are reclaimed
  240.      * via the taskDeleteHook facility.
  241.      */
  242.     if (!stdioFpCleanupHookDone &&
  243.         ((fp == stdout) || (fp == stdin) || (fp == stderr)))
  244.         {
  245.         /* initialize  task hook facility if necessary */
  246.         if (_func_taskDeleteHookAdd == NULL)
  247.             taskHookInit ();
  248.         
  249.         taskDeleteHookAdd ((FUNCPTR) stdioStdfpCleanup);
  250.         stdioFpCleanupHookDone = TRUE;
  251.         }
  252.     return (OK);
  253.     }
  254. /******************************************************************************
  255. *
  256. * stdioFp - return the standard input/output/error FILE of the current task
  257. * This routine returns the specified standard FILE structure address of the
  258. * current task.  It is provided primarily to give access to standard input,
  259. * standard output, and standard error from the shell, where the usual
  260. * `stdin', `stdout', `stderr' macros cannot be used.
  261. *
  262. * INCLUDE FILES: stdio.h 
  263. *
  264. * RETURNS: The standard FILE structure address of the specified file
  265. * descriptor, for the current task.
  266. */
  267. FILE * stdioFp 
  268.     (
  269.     int stdFd /* fd of standard FILE to return (0,1,2) */
  270.     )
  271.     {
  272.     if (taskIdCurrent->taskStdFp [stdFd] == NULL)
  273. stdioInitStd (stdFd);
  274.     return (taskIdCurrent->taskStdFp [stdFd]);
  275.     }
  276. /*******************************************************************************
  277. *
  278. * __stdin - get pointer to current task's stdin
  279. *
  280. * This function returns a pointer to the current task's stdin.  If the
  281. * current task does not have a stdin then one is created.
  282. *
  283. * NOMANUAL
  284. */
  285. FILE ** __stdin (void)
  286.     {
  287.     if (taskIdCurrent->taskStdFp [STD_IN] == NULL)
  288. stdioInitStd (STD_IN);
  289.     return (&taskIdCurrent->taskStdFp [STD_IN]);
  290.     }
  291. /*******************************************************************************
  292. *
  293. * __stdout - get pointer to current task's stdout
  294. *
  295. * This function returns a pointer to the current task's stdout.  If the
  296. * current task does not have a stdout then one is created.
  297. *
  298. * NOMANUAL
  299. */
  300. FILE ** __stdout (void)
  301.     {
  302.     if (taskIdCurrent->taskStdFp [STD_OUT] == NULL)
  303. stdioInitStd (STD_OUT);
  304.     return (&taskIdCurrent->taskStdFp [STD_OUT]);
  305.     }
  306. /*******************************************************************************
  307. *
  308. * __stderr - get pointer to current task's stderr
  309. *
  310. * This function returns a pointer to the current task's stderr.  If the
  311. * current task does not have a stderr then one is created.
  312. *
  313. * NOMANUAL
  314. */
  315. FILE ** __stderr (void)
  316.     {
  317.     if (taskIdCurrent->taskStdFp [STD_ERR] == NULL)
  318. stdioInitStd (STD_ERR);
  319.     return (&taskIdCurrent->taskStdFp [STD_ERR]);
  320.     }