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

VxWorks

开发平台:

C/C++

  1. /* ioLib.c - I/O interface library */
  2. /* Copyright 1984-2002 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 04x,02Aug00,jgn  merge DOT-4 pthreads code +
  8.  add validation of null pointer for name as well as null string
  9. 04w,03oct01,dcb  Fix SPR 20033 side effect --- handle new return code from
  10.                  iosFdSet.  Combine open() and creat() into one function.
  11. 04v,01mar99,yp   SPR 21655 - if iosDevFind() fails open() dosn't free fd
  12. 04u,21feb99,jdi  doc: listed errnos.
  13. 04t,03sep97,dgp  doc: SPR 9023 - correct reference to FIOGETNAME in ioctl()
  14. 04s,10jul97,dgp  doc: fix SPR 6117, rename() not supported on all devices
  15. 04r,20oct95,jdi  doc: addition for rename() (SPR 4167); added bit values
  16.     for open() and creat() flags (SPR 4276).
  17. 04q,10feb95,rhp  added names of stdio fd macros to ioLib man page
  18. 04p,26jul94,dvs  added doc for read/write if no driver routine (SPR #2019/2020).
  19. 04o,30sep93,jmm  resubmitted change originally in scd 10148
  20. 04n,08feb93,smb  changed int to size_t for read and write.
  21. 04m,21jan93,jdi  documentation cleanup for 5.1.
  22. 04l,29jul92,smb  added isatty for use by stdio library.
  23. 04k,22jul92,kdl  Replaced delete() with remove().
  24. 04j,18jul92,smb  Changed errno.h to errnoLib.h.
  25. 04i,04jul92,jcf  scalable/ANSI/cleanup effort.
  26. 04h,26may92,rrr  the tree shuffle
  27. 04g,28feb92,wmd  added bzero() call in ioFullFileNameGet() to init to 0's
  28.  fullPathName[] buffer before it is passed to subordinates.
  29. 04f,05dec91,rrr  made lseek take posix arguments (SEEK_)
  30. 04e,25nov91,llk  ansi stuff.  Modified remove() and rename().
  31.  included stdio.h.
  32. 04d,25nov91,rrr  cleanup of some ansi warings.
  33. 04c,04oct91,rrr  passed through the ansification filter
  34.                   -changed functions to ansi style
  35.   -changed includes to have absolute path from h/
  36.   -changed READ, WRITE and UPDATE to O_RDONLY O_WRONLY and ...
  37.   -changed VOID to void
  38.   -changed copyright notice
  39. 04b,05apr91,jdi  documentation -- removed header parens and x-ref numbers;
  40.  doc review by dnw.
  41. 04a,08feb91,jaa  documentation cleanup.
  42. 03z,15oct90,dnw  made ioFullFileNameGet() be NOMANUAL
  43. 03y,05oct90,dnw  made readv, writev, ioDefDevGet, ioDefDirGet be NOMANUAL
  44.  made ioFullFileNameGet() use pathCat()
  45.  added chdir(), getcwd(), rename() for POSIX compliance
  46.  added remove() for ANSI compliance
  47.  added ioDefPathCat() (NOMANUAL)
  48. 03x,06jun90,rdc  added readv and writev.
  49. 03w,25may90,dnw  changed creat and open to NOT malloc filename before calling
  50.    iosFdSet.  This is now left up to iosFdSet.
  51. 03v,11may90,yao  added missing modification history (03u) for the last checkin.
  52. 03u,09may90,yao  typecasted malloc to (char *).
  53. 03t,01may90,llk  changed call to pathCat().  Now, pathCat() checks if a name
  54.    is too long, and returns ERROR if it is.
  55. 03s,14apr90,jcf  removed tcb extension dependencies.
  56. 03r,01apr90,llk  changed ioFullFileNameGet() and ioDefPathSet() so that only
  57.    filenames of MAX_FILENAME_LENGTH characters or less will
  58.    be accepted.
  59. 03q,14mar90,jdi  documentation cleanup.
  60. 03p,12dec89,dab  documentation.
  61. 03o,15nov89,dab  changed variable name mode to flag in creat().  documentation.
  62.             rdc  added unlink, getwd for unix compatibility.
  63. 03n,02may89,dab  documentation touchup in lseek().
  64. 03m,23mar89,dab  made L_XTND option work in lseek(); fixed L_INCR bug in
  65.  lseek(); documentation touchup in creat().
  66. 03l,23nov88,llk  fixed bug in handling multiple links.
  67.     dnw  changed ioTaskStd{Set,Get} to take taskId arg.
  68. 03k,08oct88,gae  made global standard fd array local.
  69. 03j,07sep88,gae  documentation.
  70. 03i,29aug88,gae  documentation.
  71. 03h,15aug88,jcf  lint.
  72. 03g,15jul88,llk  changed to allocate an fd name before calling iosFdSet or
  73.    iosFdNew.
  74. 03f,30jun88,llk  changed open and create so that they handle links.
  75. 03e,04jun88,llk  uses a default path instead of a default device.
  76.  changed ioDefDev to ioDefPath.
  77.  added ioDefPathPrompt, ioDefPathShow, ioDefPathSet,
  78.     ioDefPathGet, ioDefDirGet.
  79.  rewrote ioDefDevGet.
  80.  removed ioSetDefDev.
  81.  added ioFullFileNameGet.
  82. 03d,30may88,dnw  changed to v4 names.
  83. 03c,28may88,dnw  deleted obsolete create().
  84. 03b,27may88,llk  see change 03e above.
  85. 03a,30mar88,gae  made I/O system, i.e. iosLib, responsible for low-level
  86.    creat,open,read,write,close calls to drivers as
  87.    fdTable & drvTable are now hidden.
  88.                  added parameters to open() for UNIX compatibility.
  89.  made L_INCR option work in lseek().
  90.  added io{G,S}et{Global,Task}Std().
  91. 02u,19apr88,llk  added a parameter to open.  Inspired by NFS and aspirations
  92.    toward UNIX compatibility.
  93. 02t,31dec87,jlf  made creat and open follow links.
  94. 02s,05nov87,jlf  documentation
  95. 02r,30sep87,gae  removed usage of fdTable by using new iosFdSet().
  96.  added FIOGETNAME to ioctl.
  97. 02q,28aug87,dnw  changed creat() and open() to only treat ERROR (-1) as error
  98.    indication from driver routines instead of < 0 to allow
  99.    driver values (i.e. structure pointers) to be in memory
  100.    with high bit set.
  101. 02p,28apr87,gae  close() now returns status; added UNIX compatible creat().
  102. 02o,24mar87,jlf  documentation
  103. 02n,25feb87,ecs  minor documentation.
  104.  added include of strLib.h.
  105. 02m,14feb87,dnw  changed create(), open(), delete() to return ERROR if null
  106.    filename is specified.  However, filename "." is turned
  107.    into null filename before being passed to driver routine.
  108. 02l,20dec86,dnw  fixed ioGetDefDevTail() to require complete match of dev name.
  109.  changed to not get include files from default directories.
  110. 02k,07oct86,gae  added ioGetDefDevTail().
  111. 02j,04sep86,jlf  minor documentation
  112. 02i,01jul86,jlf  minor documentation
  113. 02h,03apr86,llk  fixed syntax error in lseek.
  114. 02g,03mar86,jlf  changed ioctrl calls to ioctl.
  115.  added lseek.
  116. ...deleted pre 86 history - see RCS
  117. */
  118. /*
  119. DESCRIPTION
  120. This library contains the interface to the basic I/O system.
  121. It includes:
  122. .iP "" 4
  123. Interfaces to the seven basic driver-provided functions:
  124. creat(), remove(), open(), close(), read(), write(), and ioctl().
  125. .iP
  126. Interfaces to several file system functions, including
  127. rename() and lseek().
  128. .iP
  129. Routines to set and get the current working directory.
  130. .iP
  131. Routines to assign task and global standard file descriptors.
  132. FILE DESCRIPTORS
  133. At the basic I/O level, files are referred to by a file descriptor.
  134. A file descriptor is a small integer returned by a call to open() or creat().  
  135. The other basic I/O calls take a file descriptor as a parameter to specify 
  136. the intended file.
  137. Three file descriptors are reserved and have special meanings:
  138.     0 (`STD_IN')  - standard input
  139.     1 (`STD_OUT') - standard output
  140.     2 (`STD_ERR') - standard error output
  141. VxWorks allows two levels of redirection.  First, there is a global
  142. assignment of the three standard file descriptors.  By default, new tasks use
  143. this global assignment.  The global assignment of the three standard
  144. file descriptors is controlled by the routines ioGlobalStdSet() and 
  145. ioGlobalStdGet().
  146. Second, individual tasks may override the global assignment of these
  147. file descriptors with their own assignments that apply only to that task.  
  148. The assignment of task-specific standard file descriptors is controlled 
  149. by the routines ioTaskStdSet() and ioTaskStdGet().  
  150. INCLUDE FILES: ioLib.h
  151. SEE ALSO: iosLib, ansiStdio,
  152. .pG "I/O System"
  153. */
  154. /* LINTLIBRARY */
  155. #include "vxWorks.h"
  156. #include "sys/types.h"
  157. #include "memLib.h"
  158. #include "ioLib.h"
  159. #include "iosLib.h"
  160. #include "string.h"
  161. #include "taskLib.h"
  162. #include "net/uio.h"
  163. #include "errnoLib.h"
  164. #include "stdio.h"
  165. #include "fcntl.h"
  166. #include "unistd.h"
  167. #include "pathLib.h"
  168. #include "string.h"
  169. #define __PTHREAD_SRC
  170. #include "pthread.h"
  171. IMPORT char ioDefPath [MAX_FILENAME_LENGTH]; /* current default i/o prefix */
  172. #define STD_VALID(fd) (((fd) >= 0) && ((fd) < 3))
  173. /* globals */
  174. BOOL ioMaxLinkLevels = 20; /* maximum number of symlinks to traverse */
  175. /* forward declarations */
  176. LOCAL int ioCreateOrOpen (const char *name, int flags, int mode, BOOL create);
  177. /* locals */
  178. LOCAL int ioStdFd [3]; /* global standard input/output/error */
  179. /*******************************************************************************
  180. *
  181. * creat - create a file
  182. *
  183. * This routine creates a file called <name> and opens it with a specified
  184. * <flag>.  This routine determines on which device to create the file; 
  185. * it then calls the create routine of the device driver to do most of the work.
  186. * Therefore, much of what transpires is device/driver-dependent.
  187. *
  188. * The parameter <flag> is set to O_RDONLY (0), O_WRONLY (1), or O_RDWR (2)
  189. * for the duration of time the file is open.  To create NFS files with a
  190. * UNIX chmod-type file mode, call open() with the file mode specified in
  191. * the third argument.
  192. *
  193. * INTERNAL
  194. * A driver's create routine will return FOLLOW_LINK if any part of the file name
  195. * contains a link (in the directory path).  In this case, it will also
  196. * have changed the name of the file being opened to incorporate the name of
  197. * the link.  The new file name is then repeatedly resubmitted to the driver's
  198. * open routine until all links are resolved.
  199. *
  200. * NOTE
  201. * For more information about situations when there are no file descriptors
  202. * available, see the manual entry for iosInit().
  203. *
  204. * RETURNS:
  205. * A file descriptor number, or ERROR if a filename is not specified, the
  206. * device does not exist, no file descriptors are available, or the driver
  207. * returns ERROR.
  208. *
  209. * SEE ALSO: open()
  210. *
  211. */
  212. int creat
  213.     (
  214.     const char *name,   /* name of the file to create    */
  215.     int        flag    /* O_RDONLY, O_WRONLY, or O_RDWR */
  216.     )
  217.     {
  218.     return ioCreateOrOpen (name, flag, 0, TRUE);
  219.     }
  220. /*******************************************************************************
  221. *
  222. * open - open a file
  223. *
  224. * This routine opens a file for reading, writing, or updating, and returns
  225. * a file descriptor for that file.  The arguments to open() are the filename 
  226. * and the type of access:
  227. *
  228. * .TS
  229. * tab(|);
  230. * 8l l l.
  231. * O_RDONLY  (0)    |(or READ)   |- open for reading only.
  232. * O_WRONLY  (1)    |(or WRITE)  |- open for writing only.
  233. * O_RDWR  (2)      |(or UPDATE) |- open for reading and writing.
  234. * O_CREAT  (0x0200)|            |- create a file.
  235. * .TE
  236. *
  237. * In general, open() can only open pre-existing devices and files.  However,
  238. * for NFS network devices only, files can also be created with open() by
  239. * performing a logical OR operation with O_CREAT and the <flags> argument.
  240. * In this case, the file is created with a UNIX chmod-style file mode, as
  241. * indicated with <mode>.  For example:
  242. * .CS
  243. *     fd = open ("/usr/myFile", O_CREAT | O_RDWR, 0644);
  244. * .CE
  245. * Only the NFS driver uses the <mode> argument.
  246. *
  247. * INTERNAL
  248. * A driver's open routine will return FOLLOW_LINK if any part of the file name
  249. * contains a link (directory path or file name).  In this case, it will also
  250. * have changed the name of the file being opened to incorporate the name of
  251. * the link.  The new file name is then repeatedly resubmitted to the driver's
  252. * open routine until all links are resolved.
  253. *
  254. * NOTE
  255. * For more information about situations when there are no file descriptors
  256. * available, see the manual entry for iosInit().
  257. *
  258. * RETURNS:
  259. * A file descriptor number, or ERROR if a file name is not specified, the
  260. * device does not exist, no file descriptors are available, or the driver
  261. * returns ERROR.
  262. *
  263. * ERRNO: ELOOP
  264. *
  265. * SEE ALSO: creat()
  266. *
  267. * VARARGS2
  268. *
  269. */
  270. int open
  271.     (
  272.     const char *name,   /* name of the file to open                  */
  273.     int flags,          /* O_RDONLY, O_WRONLY, O_RDWR, or O_CREAT    */
  274.     int mode            /* mode of file to create (UNIX chmod style) */
  275.     )
  276.     {
  277.     return ioCreateOrOpen (name, flags, mode, FALSE);
  278.     }
  279. /*******************************************************************************
  280. *
  281. * ioCreateOrOpen creat() or open() a file
  282. *
  283. * This is the worker function for creat() and for open().  See their
  284. * descriptions.
  285. *
  286. * NOMANUAL
  287. */
  288. LOCAL int ioCreateOrOpen
  289.     (
  290.     const char *name,   /* name of the file to create    */
  291.     int        flags,   /* O_RDONLY, O_WRONLY, O_RDWR or O_CREAT (open call) */
  292.     int        mode,    /* mode of ile to create (if open call) */
  293.     BOOL       create   /* set to TRUE if this is a creat() call */
  294.     )
  295.     {
  296.     DEV_HDR *pDevHdr1;
  297.     DEV_HDR *pDevHdr2 = NULL;
  298.     int     value;
  299.     int     fd = (int)ERROR;
  300.     char    fullFileName [MAX_FILENAME_LENGTH];
  301.     int     error = 0;
  302.     char *pPartFileName;
  303.     int savtype;
  304.     /* don't allow null filename (for user protection) but change
  305.      * "." into what null filename would be if we allowed it */
  306.     if ((name == NULL) || (name[0] == EOS))
  307. {
  308. errnoSet (S_ioLib_NO_FILENAME);
  309. error = 1;
  310. goto handleError;
  311. }
  312.     
  313.     if (_func_pthread_setcanceltype != NULL)
  314.         {
  315.         _func_pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &savtype);
  316.         }
  317.     if (strcmp (name, ".") == 0)
  318. {
  319. /* point to EOS (turn it into null filename) */
  320. ++name;
  321. }
  322.     
  323.     if (ioFullFileNameGet (name, &pDevHdr1, fullFileName) == ERROR)
  324. {
  325. error = 1;
  326. goto handleError;
  327. }
  328.     
  329.     if ((fd = iosFdNew (pDevHdr1, (char *)NULL, 0)) == ERROR)
  330. {
  331. error = 1;
  332. goto handleError;
  333. }
  334.     
  335.     if (create == TRUE)
  336. {
  337. value = iosCreate (pDevHdr1, fullFileName, flags);
  338. }
  339.     else
  340. {
  341. value = iosOpen (pDevHdr1, fullFileName, flags, mode);
  342. }
  343.     
  344.     if (value == ERROR)
  345. {
  346. error = 2;
  347. goto handleError;
  348. }
  349.     
  350.     /* In case the path does not follow the while loop, get the pDevHdr1
  351.        recorded in pDevHdr2 for error handling. */
  352.     pDevHdr2 = pDevHdr1;
  353.     
  354.     while (value == FOLLOW_LINK)
  355. {
  356. int linkCount = 1;
  357. /* if a file name contains a link, the driver's create routine changed
  358.  * fullFileName to incorporate the link's name. Try to create the file
  359.  * that the driver's create routine handed back.
  360.  */
  361. if (linkCount++ > ioMaxLinkLevels)
  362.     {
  363.     errno = ELOOP;
  364.     error = 2;
  365.     goto handleError;
  366.     }
  367. if ((pDevHdr2 = iosDevFind (fullFileName, &pPartFileName)) == NULL)
  368.     {
  369.     error = 2;
  370.     goto handleError;
  371.     }
  372. if (fullFileName != pPartFileName)
  373.     {
  374.     /* link file name starts with a vxWorks device name,
  375.      * possibly a different device from the current one.
  376.      */
  377.     strncpy (fullFileName, pPartFileName, MAX_FILENAME_LENGTH);
  378.     }
  379. else
  380.     {
  381.     /* link file name does not start with a vxWorks device name.
  382.      * create the file on the current device.
  383.      */
  384.     pDevHdr2 = pDevHdr1;
  385.     }
  386. if (create == TRUE)
  387.     {
  388.     value = iosCreate (pDevHdr2, fullFileName, flags);
  389.     }
  390. else
  391.     {
  392.     value = iosOpen (pDevHdr2, fullFileName, flags, mode);
  393.     }
  394. if (value == ERROR)
  395.     {
  396.     error = 2;
  397.     goto handleError;
  398.     }
  399. } /* while */
  400.     
  401.     if ((iosFdSet (fd, pDevHdr1, CHAR_FROM_CONST(name), value)) == ERROR)
  402. {
  403. error = 3;   
  404. goto handleError;
  405. }
  406.     if (_func_pthread_setcanceltype != NULL)
  407.         {
  408.         _func_pthread_setcanceltype(savtype, NULL);
  409.         }
  410.     return (fd);
  411.     
  412. handleError:
  413.     if (_func_pthread_setcanceltype != NULL)
  414. {
  415. _func_pthread_setcanceltype(savtype, NULL);
  416. }
  417.     if (error > 2)
  418. {
  419. iosDelete (pDevHdr2, fullFileName);
  420. }
  421.     if (error > 1)
  422. {
  423. iosFdFree (fd);
  424. }
  425.     if (error > 0)
  426. {
  427. fd = (int)ERROR;
  428. }
  429.     
  430.     return (fd);
  431.     }
  432. /*******************************************************************************
  433. *
  434. * unlink - delete a file (POSIX)
  435. *
  436. * This routine deletes a specified file.  It performs the same function
  437. * as remove() and is provided for POSIX compatibility.
  438. *
  439. * RETURNS:
  440. * OK if there is no delete routine for the device or the driver returns OK;
  441. * ERROR if there is no such device or the driver returns ERROR.
  442. *
  443. * SEE ALSO: remove()
  444. */
  445. STATUS unlink
  446.     (
  447.     char *name          /* name of the file to remove */
  448.     )
  449.     {
  450.     return (remove (name));
  451.     }
  452. /********************************************************************************
  453. * remove - remove a file (ANSI)
  454. *
  455. * This routine deletes a specified file.  It calls the driver for the
  456. * particular device on which the file is located to do the work.
  457. *
  458. * RETURNS:
  459. * OK if there is no delete routine for the device or the driver returns OK;
  460. * ERROR if there is no such device or the driver returns ERROR.
  461. *
  462. * SEE ALSO:
  463. * .I "American National Standard for Information Systems -"
  464. * .I "Programming Language - C, ANSI X3.159-1989: Input/Output (stdio.h),"
  465. */
  466.  
  467. STATUS remove
  468.     (
  469.     const char *name          /* name of the file to remove */
  470.     )
  471.     {
  472.     DEV_HDR *pDevHdr;
  473.     char fullFileName [MAX_FILENAME_LENGTH];
  474.     /* don't allow null filename (for user protection) */
  475.  
  476.     if ((name == NULL) || (name[0] == EOS))
  477.         {
  478.         errnoSet (S_ioLib_NO_FILENAME);
  479.         return (ERROR);
  480.         }
  481.  
  482.     if (ioFullFileNameGet (name, &pDevHdr, fullFileName) == ERROR)
  483.         return (ERROR);
  484.  
  485.     return (iosDelete (pDevHdr, fullFileName));
  486.     }
  487. /*******************************************************************************
  488. *
  489. * close - close a file
  490. *
  491. * This routine closes the specified file and frees the file descriptor.
  492. * It calls the device driver to do the work.
  493. *
  494. * RETURNS:
  495. * The status of the driver close routine, or ERROR if the file descriptor 
  496. * is invalid.
  497. */
  498. STATUS close
  499.     (
  500.     int fd              /* file descriptor to close */
  501.     )
  502.     {
  503.     int ret, savtype;
  504.     if (_func_pthread_setcanceltype != NULL)
  505.         {
  506.         _func_pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &savtype);
  507.         }
  508.     ret = iosClose (fd);
  509.     if (_func_pthread_setcanceltype != NULL)
  510.         {
  511.         _func_pthread_setcanceltype(savtype, NULL);
  512.         }
  513.     return (ret);
  514.     }
  515. /*******************************************************************************
  516. *
  517. * rename - change the name of a file
  518. *
  519. * This routine changes the name of a file from <oldfile> to <newfile>.
  520. *
  521. * NOTE: Only certain devices support rename().  To confirm that your device
  522. * supports it, consult the respective xxDrv or xxFs listings to verify that
  523. * ioctl FIORENAME exists.  For example, dosFs and rt11Fs support rename(),
  524. * but netDrv and nfsDrv do not.
  525. *
  526. * RETURNS: OK, or ERROR if the file could not be opened or renamed.
  527. */
  528. int rename
  529.     (
  530.     const char *oldname, /* name of file to rename         */
  531.     const char *newname /* name with which to rename file */
  532.     )
  533.     {
  534.     int fd;
  535.     int status;
  536.     if ((oldname == NULL) || (newname == NULL) || (newname[0] == EOS))
  537. {
  538. errnoSet (ENOENT);
  539. return (ERROR);
  540. }
  541.     /* try to open file */
  542.     if ((fd = open ((char *) oldname, O_RDONLY, 0)) < OK)
  543. return (ERROR);
  544.     /* rename it */
  545.     status = ioctl (fd, FIORENAME, (int) newname);
  546.     close (fd);
  547.     return (status);
  548.     }
  549. /*******************************************************************************
  550. *
  551. * read - read bytes from a file or device
  552. *
  553. * This routine reads a number of bytes (less than or equal to <maxbytes>)
  554. * from a specified file descriptor and places them in <buffer>.  It calls
  555. * the device driver to do the work.
  556. *
  557. * RETURNS:
  558. * The number of bytes read (between 1 and <maxbytes>, 0 if end of file), or
  559. * ERROR if the file descriptor does not exist, the driver does not have
  560. * a read routines, or the driver returns ERROR. If the driver does not 
  561. * have a read routine, errno is set to ENOTSUP.
  562. */
  563. int read
  564.     (
  565.     int fd,             /* file descriptor from which to read   */
  566.     char *buffer,       /* pointer to buffer to receive bytes   */
  567.     size_t maxbytes     /* max no. of bytes to read into buffer */
  568.     )
  569.     {
  570.     int ret, savtype;
  571.     if (_func_pthread_setcanceltype != NULL)
  572.         {
  573.         _func_pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &savtype);
  574.         }
  575.     ret = iosRead (fd, buffer, (int) maxbytes);
  576.     if (_func_pthread_setcanceltype != NULL)
  577.         {
  578.         _func_pthread_setcanceltype(savtype, NULL);
  579.         }
  580.     return (ret);
  581.     }
  582. /*******************************************************************************
  583. *
  584. * write - write bytes to a file
  585. *
  586. * This routine writes <nbytes> bytes from <buffer> to a specified file
  587. * descriptor <fd>.  It calls the device driver to do the work.
  588. *
  589. * RETURNS:
  590. * The number of bytes written (if not equal to <nbytes>, an error has
  591. * occurred), or ERROR if the file descriptor does not exist, the driver
  592. * does not have a write routine, or the driver returns ERROR. If the driver
  593. * does not have a write routine, errno is set to ENOTSUP.
  594. */
  595. int write
  596.     (
  597.     int fd,             /* file descriptor on which to write     */
  598.     char *buffer,       /* buffer containing bytes to be written */
  599.     size_t nbytes       /* number of bytes to write              */
  600.     )
  601.     {
  602.     int ret, savtype;
  603.     if (_func_pthread_setcanceltype != NULL)
  604.         {
  605.         _func_pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &savtype);
  606.         }
  607.     ret = iosWrite (fd, buffer, (int) nbytes);
  608.     if (_func_pthread_setcanceltype != NULL)
  609.         {
  610.         _func_pthread_setcanceltype(savtype, NULL);
  611.         }
  612.     return (ret);
  613.     }
  614. /*******************************************************************************
  615. *
  616. * ioctl - perform an I/O control function
  617. *
  618. * This routine performs an I/O control function on a device.  The control
  619. * functions used by VxWorks device drivers are defined in the header file
  620. * ioLib.h.  Most requests are passed on to the driver for handling.
  621. * Since the availability of ioctl() functions is driver-specific, these
  622. * functions are discussed separately in tyLib, pipeDrv, nfsDrv, dosFsLib,
  623. * rt11FsLib, and rawFsLib.
  624. *
  625. * The following example renames the file or directory to the string "newname":
  626. *
  627. * .CS
  628. *     ioctl (fd, FIORENAME, "newname");
  629. * .CE
  630. *
  631. * Note that the function FIOGETNAME is handled by the I/O interface level and
  632. * is not passed on to the device driver itself.  Thus this function code value
  633. * should not be used by customer-written drivers.
  634. *
  635. * RETURNS:
  636. * The return value of the driver, or ERROR if the file descriptor does 
  637. * not exist.
  638. *
  639. * SEE ALSO: tyLib, pipeDrv, nfsDrv, dosFsLib, rt11FsLib, rawFsLib,
  640. * .pG "I/O System, Local File Systems"
  641. *
  642. * VARARGS2
  643. */
  644. int ioctl
  645.     (
  646.     int fd,             /* file descriptor    */
  647.     int function,       /* function code      */
  648.     int arg             /* arbitrary argument */
  649.     )
  650.     {
  651.     return (iosIoctl (fd, function, arg));
  652.     }
  653. /*******************************************************************************
  654. *
  655. * lseek - set a file read/write pointer
  656. *
  657. * This routine sets the file read/write pointer of file <fd> 
  658. * to <offset>.
  659. * The argument <whence>, which affects the file position pointer,
  660. * has three values:
  661. * .TS
  662. * tab(|);
  663. * 8l l.
  664. * SEEK_SET  (0) |- set to <offset>
  665. * SEEK_CUR  (1) |- set to current position plus <offset>
  666. * SEEK_END  (2) |- set to the size of the file plus <offset>
  667. * .TE
  668. * This routine calls ioctl() with functions FIOWHERE, FIONREAD, and FIOSEEK.
  669. *
  670. * RETURNS:
  671. * The new offset from the beginning of the file, or ERROR.
  672. *
  673. * ARGSUSED
  674. */
  675. int lseek
  676.     (
  677.     int fd,             /* file descriptor            */
  678.     long offset,        /* new byte offset to seek to */
  679.     int whence          /* relative file position     */
  680.     )
  681.     {
  682.     int where;
  683.     long nBytes;
  684.     switch (whence)
  685. {
  686. case SEEK_SET:
  687.     return ((ioctl (fd, FIOSEEK, offset) == OK) ? offset : ERROR);
  688. case SEEK_CUR:
  689.     if ((where = ioctl (fd, FIOWHERE, 0 /*XXX*/)) == ERROR)
  690. return (ERROR);
  691.     offset += where;
  692.     return ((ioctl (fd, FIOSEEK, offset) == OK) ? offset : ERROR);
  693. case SEEK_END:
  694.     if ((where = ioctl (fd, FIOWHERE, 0 /*XXX*/)) == ERROR)
  695. return (ERROR);
  696.     if (ioctl (fd, FIONREAD, (int) (&nBytes)) == ERROR)
  697. return (ERROR);
  698.     offset += where + nBytes;
  699.     return ((ioctl (fd, FIOSEEK, offset) == OK) ? offset : ERROR);
  700. default:
  701.     return (ERROR);
  702. }
  703.     }
  704. /*******************************************************************************
  705. *
  706. * readv - read data from a device into scattered buffers
  707. *
  708. * readv takes as a parameter a list of buffers (iov) into which it should
  709. * place data read from the specified file descriptor (fd).  iov is a pointer
  710. * to an array of length iovcnt of (struct iovec) structures, which describe
  711. * the location and length of each individual buffer.  readv will always
  712. * completely fill a buffer before moving on to the next buffer in the list.
  713. *
  714. * RETURNS:
  715. * Number of bytes read (0 if end of file), or
  716. * ERROR if the file descriptor does not exist or the driver returns ERROR.
  717. *
  718. * NOMANUAL
  719. */
  720. int readv
  721.     (
  722.     int fd,             /* file descriptor                   */
  723.     struct iovec *iov,  /* buffer list                       */
  724.     int iovcnt          /* number of elements in buffer list */
  725.     )
  726.     {
  727.     int i;
  728.     FAST char *pBuf;
  729.     FAST int bytesToRead;
  730.     FAST int totalBytesRead = 0;
  731.     FAST int bytesRead;
  732.     for (i = 0; i < iovcnt; i++)
  733.         {
  734.         pBuf = (char *) iov[i].iov_base;
  735.         bytesToRead = iov[i].iov_len;
  736.         while (bytesToRead > 0)
  737.             {
  738.             if ((bytesRead = iosRead (fd, pBuf, bytesToRead)) == ERROR)
  739.                 {
  740.                 if (totalBytesRead > 0)
  741.                     return (totalBytesRead);
  742.                 else
  743.                     return (ERROR);
  744.                 }
  745.     if (bytesRead == 0)
  746. return (totalBytesRead);
  747.             totalBytesRead += bytesRead;
  748.             bytesToRead -= bytesRead;
  749.             pBuf += bytesRead;
  750.             }
  751.         }
  752.     return (totalBytesRead);
  753.     }
  754. /*******************************************************************************
  755. *
  756. * writev - write data from scattered buffers to a device
  757. *
  758. * writev takes as a parameter a list of buffers (iov) from which it should
  759. * write data to the specified file descriptor (fd).  iov is a pointer
  760. * to an array of length iovcnt of (struct iovec) structures, which describe
  761. * the location and length of each individual buffer.  writev will always
  762. * completely empty a buffer before moving on to the next buffer in the list.
  763. *
  764. * RETURNS:
  765. * Number of bytes written, or
  766. * ERROR if the file descriptor does not exist or the driver returns ERROR.
  767. *
  768. * NOMANUAL
  769. */
  770. int writev
  771.     (
  772.     int fd,
  773.     register struct iovec *iov,
  774.     int iovcnt
  775.     )
  776.     {
  777.     int i;
  778.     register char *pData;
  779.     register int bytesToWrite;
  780.     register int totalBytesWritten = 0;
  781.     register int bytesWritten;
  782.     for (i = 0; i < iovcnt; i++)
  783.         {
  784.         pData = (char *) iov[i].iov_base;
  785.         bytesToWrite = iov[i].iov_len;
  786.         while (bytesToWrite > 0)
  787.             {
  788.             if ((bytesWritten = iosWrite (fd, pData, bytesToWrite)) == ERROR)
  789.                 {
  790.                 if (totalBytesWritten > 0)
  791.                     return (totalBytesWritten);
  792.                 else
  793.                     return (ERROR);
  794.                 }
  795.             totalBytesWritten += bytesWritten;
  796.             bytesToWrite -= bytesWritten;
  797.             pData += bytesWritten;
  798.             }
  799.         }
  800.     return (totalBytesWritten);
  801.     }
  802. /*******************************************************************************
  803. *
  804. * ioFullFileNameGet - resolve path name to device and full file name
  805. *
  806. * This routine resolves the specified path name into a device and full
  807. * filename on that device.  If the specified path name is not a full,
  808. * absolute path name, then it is concatenated to the current default
  809. * path to derive a full path name.  This full path name is separated
  810. * into the device specification and the remaining filename on that device.
  811. * A pointer to the device header is returned in <ppDevHdr> and the
  812. * filename on that device is returned in <fullFileName>.
  813. *
  814. * RETURNS:
  815. * OK, or
  816. * ERROR if the full filename has more than MAX_FILENAME_LENGTH characters.
  817. *
  818. * NOMANUAL
  819. */
  820. STATUS ioFullFileNameGet
  821.     (
  822.     char * pathName, /* path name */
  823.     DEV_HDR ** ppDevHdr, /* ptr to dev hdr to complete */
  824.     char * fullFileName /* resulting complete filename */
  825.     )
  826.     {
  827.     char *pTail;
  828.     char fullPathName [MAX_FILENAME_LENGTH];
  829.     bzero (fullPathName, MAX_FILENAME_LENGTH);  /* initialize buffer to 0 */
  830.     /* resolve default path plus partial pathname to full path name */
  831.     if (pathCat (ioDefPath, pathName, fullPathName) == ERROR)
  832. return (ERROR);
  833.     /* remove device name from full path name */
  834.     if ((*ppDevHdr = iosDevFind (fullPathName, &pTail)) == NULL)
  835. return (ERROR);
  836.     strncpy (fullFileName, pTail, MAX_FILENAME_LENGTH);
  837.     return (OK);
  838.     }
  839. /*******************************************************************************
  840. *
  841. * ioDefPathSet - set the current default path
  842. *
  843. * This routine sets the default I/O path.  All relative pathnames specified
  844. * to the I/O system will be prepended with this pathname.  This pathname
  845. * must be an absolute pathname, i.e., <name> must begin with an existing
  846. * device name.
  847. *
  848. * RETURNS:
  849. * OK, or ERROR if the first component of the pathname is not an existing
  850. * device.
  851. *
  852. * SEE ALSO: ioDefPathGet(), chdir(), getcwd()
  853. */
  854. STATUS ioDefPathSet
  855.     (
  856.     char *name          /* name of the new default device and path */
  857.     )
  858.     {
  859.     char *pTail = name;
  860.     if (iosDevFind (name, &pTail) == NULL)
  861. return (ERROR);
  862.     if (pTail == name)
  863. {
  864. /* name does not begin with an existing device's name */
  865. errnoSet (S_ioLib_NO_DEVICE_NAME_IN_PATH);
  866. return (ERROR);
  867. }
  868.     if (strlen (name) >= MAX_FILENAME_LENGTH)
  869. {
  870. errnoSet (S_ioLib_NAME_TOO_LONG);
  871. return (ERROR);
  872. }
  873.     strcpy (ioDefPath, name);
  874.     return (OK);
  875.     }
  876. /*******************************************************************************
  877. *
  878. * ioDefPathGet - get the current default path
  879. *
  880. * This routine copies the name of the current default path to <pathname>.
  881. * The parameter <pathname> should be MAX_FILENAME_LENGTH characters long.
  882. *
  883. * RETURNS: N/A
  884. *
  885. * SEE ALSO: ioDefPathSet(), chdir(), getcwd()
  886. */
  887. void ioDefPathGet
  888.     (
  889.     char *pathname              /* where to return the name */
  890.     )
  891.     {
  892.     strcpy (pathname, ioDefPath);
  893.     }
  894. /*******************************************************************************
  895. *
  896. * chdir - set the current default path
  897. *
  898. * This routine sets the default I/O path.  All relative pathnames specified
  899. * to the I/O system will be prepended with this pathname.  This pathname
  900. * must be an absolute pathname, i.e., <name> must begin with an existing
  901. * device name.
  902. *
  903. * RETURNS:
  904. * OK, or ERROR if the first component of the pathname is not an existing device.
  905. *
  906. * SEE ALSO: ioDefPathSet(), ioDefPathGet(), getcwd()
  907. */
  908. STATUS chdir
  909.     (
  910.     char *pathname      /* name of the new default path */
  911.     )
  912.     {
  913.     return (ioDefPathSet (pathname));
  914.     }
  915. /*******************************************************************************
  916. *
  917. * getcwd - get the current default path (POSIX)
  918. *
  919. * This routine copies the name of the current default path to <buffer>.
  920. * It provides the same functionality as ioDefPathGet() and
  921. * is provided for POSIX compatibility.
  922. *
  923. * RETURNS:
  924. * A pointer to the supplied buffer, or NULL if <size> is too small to hold
  925. * the current default path.
  926. *
  927. * SEE ALSO: ioDefPathSet(), ioDefPathGet(), chdir()
  928. */
  929. char *getcwd
  930.     (
  931.     char *buffer,       /* where to return the pathname */
  932.     int  size           /* size in bytes of buffer      */
  933.     )
  934.     {
  935.     if (size <= 0)
  936. {
  937. errnoSet (EINVAL);
  938. return (NULL);
  939. }
  940.     if (size < strlen (ioDefPath) + 1)
  941. {
  942. errnoSet (ERANGE);
  943. return (NULL);
  944. }
  945.     strcpy (buffer, ioDefPath);
  946.     return (buffer);
  947.     }
  948. /*******************************************************************************
  949. *
  950. * getwd - get the current default path
  951. *
  952. * This routine copies the name of the current default path to <pathname>.
  953. * It provides the same functionality as ioDefPathGet() and getcwd().
  954. * It is provided for compatibility with some older UNIX systems.
  955. *
  956. * The parameter <pathname> should be MAX_FILENAME_LENGTH characters long.
  957. *
  958. * RETURNS: A pointer to the resulting path name.
  959. */
  960. char *getwd
  961.     (
  962.     char *pathname      /* where to return the pathname */
  963.     )
  964.     {
  965.     strcpy (pathname, ioDefPath);
  966.     return (pathname);
  967.     }
  968. /*******************************************************************************
  969. *
  970. * ioDefPathCat - concatenate to current default path
  971. *
  972. * This routine changes the current default path to include the specified
  973. * <name>.  If <name> is itself an absolute pathname beginning with
  974. * a device name, then it becomes the new default path.  Otherwise <name>
  975. * is appended to the current default path in accordance with the rules
  976. * of concatenating path names.
  977. *
  978. * RETURNS:
  979. * OK, or
  980. * ERROR if a valid pathname cannot be derived from the specified name.
  981. *
  982. * NOMANUAL
  983. */
  984. STATUS ioDefPathCat
  985.     (
  986.     char *name          /* path to be concatenated to current path */
  987.     )
  988.     {
  989.     char newPath [MAX_FILENAME_LENGTH];
  990.     char *pTail;
  991.     /* interpret specified path in terms of current default path */
  992.     if (pathCat (ioDefPath, name, newPath) == ERROR)
  993. return (ERROR);
  994.     /* make sure that new path starts with a device name */
  995.     iosDevFind (newPath, &pTail);
  996.     if (pTail == newPath)
  997. {
  998. errnoSet (S_ioLib_NO_DEVICE_NAME_IN_PATH);
  999. return (ERROR);
  1000. }
  1001.     pathCondense (newPath); /* resolve ".."s, "."s, etc */
  1002.     strncpy (ioDefPath, newPath, MAX_FILENAME_LENGTH);
  1003.     return (OK);
  1004.     }
  1005. /*******************************************************************************
  1006. *
  1007. * ioDefDevGet - get current default device
  1008. *
  1009. * This routine copies the name of the device associated with the current
  1010. * default pathname to <devName>.
  1011. *
  1012. * NOTE: This routine was public in 4.0.2 but is obsolete.  It is made
  1013. * no-manual in 5.0 and should be removed in the next release.
  1014. *
  1015. * NOMANUAL
  1016. */
  1017. void ioDefDevGet
  1018.     (
  1019.     char *devName               /* where to return the device name */
  1020.     )
  1021.     {
  1022.     DEV_HDR *pDevHdr; /* pointer to device header */
  1023.     char *pTail;
  1024.     /* find the device of the default pathname */
  1025.     if ((pDevHdr = iosDevFind (ioDefPath, &pTail)) == NULL)
  1026. {
  1027. *devName = EOS; /* no default device, return null device name */
  1028. }
  1029.     else
  1030. {
  1031. strcpy (devName, pDevHdr->name); /* return device name */
  1032. }
  1033.     }
  1034. /*******************************************************************************
  1035. *
  1036. * ioDefDirGet - get current default directory
  1037. *
  1038. * This routine copies the current default directory to <dirName>.
  1039. * The current default directory is derived from the current default
  1040. * pathname minus the leading device name.
  1041. *
  1042. * <dirname> should be MAX_FILENAME_LENGTH characters long.
  1043. *
  1044. * NOTE: This routine was public in 4.0.2 but is obsolete.  It is made
  1045. * no-manual in 5.0 and should be removed in the next release.
  1046. *
  1047. * NOMANUAL
  1048. */
  1049. void ioDefDirGet
  1050.     (
  1051.     char *dirName               /* where to return the directory name */
  1052.     )
  1053.     {
  1054.     char *pTail;
  1055.     /* find the directory name in the default path name */
  1056.     if (iosDevFind (ioDefPath, &pTail) == NULL)
  1057. {
  1058. *dirName = EOS; /* no default device, return null directory name */
  1059. }
  1060.     else
  1061. {
  1062. strcpy (dirName, pTail);
  1063. }
  1064.     }
  1065. /*******************************************************************************
  1066. *
  1067. * ioGlobalStdSet - set the file descriptor for global standard input/output/error
  1068. *
  1069. * This routine changes the assignment of a specified global standard file
  1070. * descriptor <stdFd> (0, 1, or, 2) to the specified underlying file
  1071. * descriptor <newFd>.  <newFd> should be a file descriptor open to the
  1072. * desired device or file.  All tasks will use this new assignment when doing
  1073. * I/O to <stdFd>, unless they have specified a task-specific standard file
  1074. * descriptor (see ioTaskStdSet()).  If <stdFd> is not 0, 1, or 2, this
  1075. * routine has no effect.
  1076. *
  1077. * RETURNS: N/A
  1078. *
  1079. * SEE ALSO: ioGlobalStdGet(), ioTaskStdSet()
  1080. */
  1081. void ioGlobalStdSet
  1082.     (
  1083.     int stdFd,  /* std input (0), output (1), or error (2) */
  1084.     int newFd   /* new underlying file descriptor          */
  1085.     )
  1086.     {
  1087.     if (STD_VALID (stdFd))
  1088. ioStdFd [stdFd] = newFd;
  1089.     }
  1090. /*******************************************************************************
  1091. *
  1092. * ioGlobalStdGet - get the file descriptor for global standard input/output/error
  1093. *
  1094. * This routine returns the current underlying file descriptor for global 
  1095. * standard input, output, and error.
  1096. *
  1097. * RETURNS:
  1098. * The underlying global file descriptor, or ERROR if <stdFd> is not 0, 1, or 2.
  1099. *
  1100. * SEE ALSO: ioGlobalStdSet(), ioTaskStdGet()
  1101. */
  1102. int ioGlobalStdGet
  1103.     (
  1104.     int stdFd   /* std input (0), output (1), or error (2) */
  1105.     )
  1106.     {
  1107.     return (STD_VALID (stdFd) ? ioStdFd [stdFd] : ERROR);
  1108.     }
  1109. /*******************************************************************************
  1110. *
  1111. * ioTaskStdSet - set the file descriptor for task standard input/output/error
  1112. *
  1113. * This routine changes the assignment of a specified task-specific standard
  1114. * file descriptor <stdFd> (0, 1, or, 2) to the specified underlying file
  1115. * descriptor<newFd>.  <newFd> should be a file descriptor open to the
  1116. * desired device or file.  The calling task will use this new assignment
  1117. * when doing I/O to <stdFd>, instead of the system-wide global assignment
  1118. * which is used by default.  If <stdFd> is not 0, 1, or 2, this routine has
  1119. * no effect.
  1120. *
  1121. * NOTE: This routine has no effect if it is called at interrupt level.
  1122. *
  1123. * RETURNS: N/A
  1124. *
  1125. * SEE ALSO: ioGlobalStdGet(), ioTaskStdGet()
  1126. */
  1127. void ioTaskStdSet
  1128.     (
  1129.     int taskId, /* task whose std fd is to be set (0 = self) */
  1130.     int stdFd,  /* std input (0), output (1), or error (2)   */
  1131.     int newFd   /* new underlying file descriptor            */
  1132.     )
  1133.     {
  1134.     WIND_TCB *pTcb;
  1135.     if (STD_VALID (stdFd) && (pTcb = taskTcb (taskId)) != NULL)
  1136. pTcb->taskStd [stdFd] = newFd;
  1137.     }
  1138. /*******************************************************************************
  1139. *
  1140. * ioTaskStdGet - get the file descriptor for task standard input/output/error
  1141. *
  1142. * This routine returns the current underlying file descriptor for task-specific
  1143. * standard input, output, and error.
  1144. *
  1145. * RETURNS:
  1146. * The underlying file descriptor, or ERROR if <stdFd> is not 0, 1, or 2, or
  1147. * the routine is called at interrupt level.
  1148. *
  1149. * SEE ALSO: ioGlobalStdGet(), ioTaskStdSet()
  1150. */
  1151. int ioTaskStdGet
  1152.     (
  1153.     int taskId, /* ID of desired task (0 = self)           */
  1154.     int stdFd   /* std input (0), output (1), or error (2) */
  1155.     )
  1156.     {
  1157.     WIND_TCB *pTcb;
  1158.     int taskFd;
  1159.     if (STD_VALID (stdFd) && (pTcb = taskTcb (taskId)) != NULL)
  1160. {
  1161. taskFd = pTcb->taskStd [stdFd];
  1162. if (STD_VALID (taskFd))
  1163.     return (ioStdFd [taskFd]);
  1164. else
  1165.     return (taskFd);
  1166. }
  1167.     return (ERROR);
  1168.     }
  1169. /********************************************************************************
  1170. * isatty - return whether the underlying driver is a tty device
  1171. *
  1172. * This routine simply invokes the ioctl() function FIOISATTY on the
  1173. * specified file descriptor.
  1174. *
  1175. * RETURNS: TRUE, or FALSE if the driver does not indicate a tty device.
  1176. */
  1177. BOOL isatty
  1178.     (
  1179.     int fd      /* file descriptor to check */
  1180.     )
  1181.     {
  1182.     return (ioctl (fd, FIOISATTY, 0 /*XXX*/) == TRUE);
  1183.     }