1 //==========================================================================
5 // Fileio IO operations
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 // Copyright (C) 2002 Gary Thomas
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38 // at http://sources.redhat.com/ecos/ecos-license/
39 // -------------------------------------------
40 //####ECOSGPLCOPYRIGHTEND####
41 //==========================================================================
42 //#####DESCRIPTIONBEGIN####
45 // Contributors: nickg
47 // Purpose: Fileio IO operations
48 // Description: These are the functions that operate on open files,
49 // such as read(), write(), fstat() etc.
53 //####DESCRIPTIONEND####
55 //==========================================================================
57 #include <pkgconf/hal.h>
58 #include <pkgconf/io_fileio.h>
60 #include <cyg/infra/cyg_trac.h> // tracing macros
61 #include <cyg/infra/cyg_ass.h> // assertion macros
63 #include <stdarg.h> // for fcntl()
65 #include "fio.h" // Private header
68 //==========================================================================
69 // File object locking
71 #define LOCK_FILE( fp ) cyg_file_lock( fp, fp->f_syncmode )
73 #define UNLOCK_FILE( fp ) cyg_file_unlock( fp, fp->f_syncmode )
75 //==========================================================================
76 // Common wrapper for read/write using an iovec descriptor
77 // 'direction' should be O_RDONLY for readv, O_WRONLY for writev
80 readwritev( int fd, const cyg_iovec *_iov, int iov_len, int direction )
84 CYG_CANCELLATION_POINT;
89 cyg_iovec iov[CYGNUM_FILEIO_IOVEC_MAX];
91 if( iov_len > CYGNUM_FILEIO_IOVEC_MAX )
92 FILEIO_RETURN(EINVAL);
94 // Copy 'iovec' structure since it's supposed to be "const"
95 // and some lower level routines might want to change it.
96 // Also accumulate the length of the total I/O request
98 for (_idx = 0; _idx < iov_len; _idx++) {
99 len += _iov[_idx].iov_len;
100 iov[_idx].iov_base = _iov[_idx].iov_base;
101 iov[_idx].iov_len = _iov[_idx].iov_len;
104 if( len > SSIZE_MAX )
105 FILEIO_RETURN(EINVAL);
107 fp = cyg_fp_get( fd );
110 FILEIO_RETURN(EBADF);
112 if( (fp->f_flag & direction) == 0 )
115 FILEIO_RETURN(EBADF);
119 cyg_fileop_readwrite *op;
122 uio.uio_iovcnt = iov_len;
124 uio.uio_segflg = UIO_USERSPACE;
128 if( direction == O_RDONLY )
129 uio.uio_rw = UIO_READ, op = fp->f_ops->fo_read;
131 uio.uio_rw = UIO_WRITE, op = fp->f_ops->fo_write;
135 ret = op( fp, &uio );
139 cnt -= uio.uio_resid;
143 CYG_CANCELLATION_POINT;
147 if ((ret == EWOULDBLOCK || ret == EAGAIN) && cnt)
148 FILEIO_RETURN_VALUE(cnt);
153 FILEIO_RETURN_VALUE(cnt);
156 //==========================================================================
159 __externC ssize_t read( int fd, void *buf, size_t len )
165 return readwritev(fd, &_iov, 1, O_RDONLY);
168 //==========================================================================
171 __externC ssize_t write( int fd, const void *buf, size_t len )
175 _iov.iov_base = (void *)buf;
177 return readwritev(fd, &_iov, 1, O_WRONLY);
180 //==========================================================================
182 __externC ssize_t readv( int fd, const cyg_iovec *_iov, int iov_len )
184 return readwritev(fd, _iov, iov_len, O_RDONLY);
187 //==========================================================================
188 // Write via an iovec
189 __externC ssize_t writev( int fd, const cyg_iovec *_iov, int iov_len )
191 return readwritev(fd, _iov, iov_len, O_WRONLY);
195 //==========================================================================
198 __externC int close( int fd )
202 CYG_CANCELLATION_POINT;
207 fp = cyg_fp_get( fd );
210 FILEIO_RETURN(EBADF);
214 // The file's fo_close entry may be called as a side
215 // effect of this operation...
216 ret = cyg_fd_free( fd );
218 CYG_CANCELLATION_POINT;
223 //==========================================================================
226 __externC off_t lseek( int fd, off_t pos, int whence )
233 fp = cyg_fp_get( fd );
236 FILEIO_RETURN(EBADF);
240 ret = fp->f_ops->fo_lseek( fp, &pos, whence );
249 FILEIO_RETURN_VALUE(pos);
252 //==========================================================================
255 __externC int ioctl( int fd, CYG_ADDRWORD com, ... )
264 fp = cyg_fp_get( fd );
267 FILEIO_RETURN(EBADF);
270 data = va_arg(ap, CYG_ADDRWORD);
275 ret = fp->f_ops->fo_ioctl( fp, com, data );
284 //==========================================================================
287 __externC int fsync( int fd )
291 CYG_CANCELLATION_POINT;
296 fp = cyg_fp_get( fd );
299 FILEIO_RETURN(EBADF);
303 ret = fp->f_ops->fo_fsync( fp, CYG_FSYNC );
309 CYG_CANCELLATION_POINT;
314 //==========================================================================
317 __externC int fdatasync( int fd )
321 CYG_CANCELLATION_POINT;
326 fp = cyg_fp_get( fd );
329 FILEIO_RETURN(EBADF);
333 ret = fp->f_ops->fo_fsync( fp, CYG_FDATASYNC );
339 CYG_CANCELLATION_POINT;
344 //==========================================================================
347 __externC int fstat( int fd, struct stat *buf )
354 fp = cyg_fp_get( fd );
357 FILEIO_RETURN(EBADF);
361 ret = fp->f_ops->fo_fstat( fp, buf );
370 //==========================================================================
373 __externC long fpathconf( int fd, int name )
380 fp = cyg_fp_get( fd );
383 FILEIO_RETURN(EBADF);
385 struct cyg_pathconf_info info;
392 ret = fp->f_ops->fo_getinfo( fp, FILE_INFO_CONF, (char *)&info, sizeof(info) );
401 FILEIO_RETURN_VALUE(info.value);
404 //==========================================================================
407 __externC int fcntl( int fd, int cmd, ... )
411 CYG_CANCELLATION_POINT;
417 fp = cyg_fp_get( fd );
420 FILEIO_RETURN(EBADF);
428 int fda = va_arg(a, int);
430 if( fda < 0 || fda >= OPEN_MAX )
436 int fd2 = cyg_fd_alloc( fda );
444 cyg_fd_assign( fd2, fp );
458 CYG_CANCELLATION_POINT;
463 //==========================================================================
466 __externC int isatty( int fd )
474 err = fstat( fd, &buf );
476 // Any error and we return zero. If the client wants to
477 // they can always pick up the error code from errno.
479 FILEIO_RETURN_VALUE(0);
481 // For now we assume that all char devices are ttys.
482 // In future we may need to have a special getinfo()
483 // call to decide this more specifically.
485 if( S_ISCHR( buf.st_mode ) )
488 FILEIO_RETURN_VALUE(ret);
491 //==========================================================================
494 __externC int cyg_fs_fgetinfo( int fd, int key, void *buf, int len )
501 fp = cyg_fp_get( fd );
504 FILEIO_RETURN(EBADF);
508 ret = fp->f_ops->fo_getinfo( fp, key, buf, len );
517 //==========================================================================
520 __externC int cyg_fs_fsetinfo( int fd, int key, void *buf, int len )
527 fp = cyg_fp_get( fd );
530 FILEIO_RETURN(EBADF);
534 ret = fp->f_ops->fo_setinfo( fp, key, buf, len );
543 // -------------------------------------------------------------------------