Main Page | Alphabetical List | Class List | File List | Class Members | File Members

fcntl_os1.h

Go to the documentation of this file.
00001 /*--------------------------------------------------------
00002  * /
00003  * / apeNEXT fcntl.h for OS1
00004  * /
00005  * / $Id: fcntl_os1.h,v 1.8 2005/10/27 20:04:57 morinl Exp $
00006  * /
00007  * /--------------------------------------------------------*/
00008 #ifndef __ANEXT_OS1_FCNTL_H__
00009 #define __ANEXT_OS1_FCNTL_H__
00010 
00011 #include <nlibc.h>
00012 
00013 #include <stddef.h>
00014 #include <sys/types.h>
00015 #include <sys/stat.h>
00016 #include <os1/defs_os1.h>
00017 #include <errno.h>
00018 
00019 // open/fcntl mode values
00020 // (same as in glibc 2.3)
00021 #define O_RDONLY             00
00022 #define O_WRONLY             01
00023 #define O_RDWR               02
00024 #define O_CREAT            0100
00025 #define O_TRUNC           01000
00026 #define O_APPEND          02000
00027 
00028 typedef int ssize_t;
00029 
00030 /*----------------------------------------------------------------------
00031 | NAME
00032 | 
00033 |  open, creat - open and possibly create a file or device 
00034 | 
00035 | SYNOPSIS
00036 | 
00037 | 
00038 | #include <sys/types.h>
00039 | #include <sys/stat.h>
00040 | #include <fcntl.h>
00041 | 
00042 | int open(const char *pathname, int flags);
00043 | int open(const char *pathname, int flags, mode_t mode);
00044 | int creat(const char *pathname, mode_t mode);
00045 | 
00046 | 
00047 | DESCRIPTION
00048 | 
00049 | The open() system call is used to convert a pathname into a file
00050 | descriptor (a small, non-negative integer for use in subsequent I/O as
00051 | with read, write, etc.). When the call is successful, the file
00052 | descriptor returned will be the lowest file descriptor not currently
00053 | open for the process. This call creates a new open file, not shared
00054 | with any other process. (But shared open files may arise via the
00055 | fork(2) system call.) The file offset is set to the
00056 | beginning of the file. 
00057 | 
00058 | The parameter flags is one of O_RDONLY, O_WRONLY or O_RDWR which
00059 | request opening the file read-only, write-only or read/write,
00060 | respectively. When opening a file for writing, the flag O_APPEND
00061 | will cause the file pointer to be positioned at the end of the
00062 | file.
00063 |
00064 | apeNEXT-specific changes:
00065 | - The flag O_CREAT is silently ignored.
00066 | - The mode parameter is silently ignored.
00067 |
00068 | creat() is equivalent to open with flags equal to 
00069 | O_CREAT|O_WRONLY|O_TRUNC. 
00070 +----------------------------------------------------------------------*/
00071 #ifndef __HAS_MAIN
00072 extern int open(const char *pathname, int flags, ...);
00073 #else
00074 #if !defined(__cflow_processed) || defined(_uses_open_fcntl_os1_h)
00075 int open(const char *pathname, int flags, ...)
00076 {       int modebits = 0, fi, fileno;
00077         #pragma localmem
00078 
00079         asm("\t!! start open()\n");
00080         /* check if number of open files exceeded */
00081         if( __n_files == __NLCC_OS1_MAX_FILES__ ) {
00082                 errno = EMFILE;
00083                 return -1;
00084         }
00085         for( fi=0; fi<__NLCC_OS1_MAX_FILES__; fi++ ) {
00086                 if( __files[fi].fd == 0 ) {
00087                         fileno = __NLCC_BASE_FD + fi;
00088                         break;
00089                 }
00090         }
00091         // unless we miscounted, fi _is_ now < __NLCC_OS1_MAX_FILES__
00092 
00093         // convert mode flags into OS1 mode value
00094         // return -1 for invalid mode
00095         {       int flags3 = (flags & 0x3);
00096                 where( flags3==O_RDONLY )
00097                         asm("\t$io_setmode(%0, $SYS_IOMODE_R)" : "=r" (modebits) );
00098                 where( flags3==O_WRONLY ) {
00099                         where( flags & O_APPEND )  {
00100                                 asm("\t$io_setmode(%0, $SYS_IOMODE_A)" : "=r" (modebits) );
00101                         } else {
00102                                 asm("\t$io_setmode(%0, $SYS_IOMODE_W)" : "=r" (modebits) );
00103                         }
00104                 }
00105                 where( flags3==O_RDWR ) {
00106                         where( flags & O_APPEND ) {
00107                                 asm("\t$io_setmode(%0, $SYS_IOMODE_APLUS)" : "=r" (modebits) );
00108                         } else {
00109                                 asm("\t$io_setmode(%0, $SYS_IOMODE_WPLUS)" : "=r" (modebits) );
00110                         }
00111                 }
00112         }
00113 
00114         if( ! modebits ) {
00115                 errno = EINVAL;
00116                 return (-1);
00117         }
00118 
00119         
00120         asm("\t$io_start\n");
00121         asm("\t$io_fopenp( 0.%0, %1, 0.%2, $SYS_IODEV_MEM , \"\")\n"
00122             : : "r" (fileno), "r" (modebits), "r" (pathname) );
00123         asm("\t$io_end\n");
00124 
00125         // check OS return code and set errno if necessary
00126         {       vector int sys_rval;
00127 
00128                 asm("\tlmtr %0 $MEM_SYS_RVAL\n" : "=r" (sys_rval) );
00129                 asm("\t!! end open()\n");
00130                 if( sys_rval.lo ) {
00131                         errno = sys_rval.hi;
00132                         return (-1);
00133                 } else {
00134                         __n_files++;
00135                         __files[fi].fd = fileno;
00136                         __files[fi].mode = modebits;
00137                         return fileno;
00138                 }
00139         }
00140 }
00141 #endif // open()
00142 #endif
00143 
00144 #if !defined(__cflow_processed) || defined(_uses_creat_fcntl_os1_h)
00145 inline 
00146 int creat(const char *pathname, mode_t mode)
00147 {
00148         return open(pathname, O_CREAT|O_WRONLY|O_TRUNC );
00149 }
00150 #endif // creat()
00151 
00152 /*---------------------------------------------------------------------
00153 | NAME
00154 |        read - read from a file descriptor
00155 | 
00156 | SYNOPSIS
00157 |        #include <unistd.h>
00158 | 
00159 |        ssize_t read(int fd, void *buf, size_t count);
00160 | 
00161 | DESCRIPTION
00162 |        read()  attempts  to  read  up  to  count  bytes from file
00163 |        descriptor fd into the buffer starting at buf.
00164 | 
00165 |        If count is zero, read() returns zero  and  has  no  other
00166 |        results.   If  count is greater than SSIZE_MAX, the result
00167 |        is unspecified.
00168 | 
00169 | 
00170 | RETURN VALUE
00171 |        On success, the number of bytes  read  is  returned  (zero
00172 |        indicates  end of file), and the file position is advanced
00173 |        by this number.  It is not an  error  if  this  number  is
00174 |        smaller  than the number of bytes requested; this may hap-
00175 |        pen for example because fewer bytes are actually available
00176 |        right  now (maybe because we were close to end-of-file, or
00177 |        because we are reading from a pipe, or from  a  terminal),
00178 |        or  because read() was interrupted by a signal.  On error,
00179 |        -1 is returned, and errno is set  appropriately.  In  this
00180 |        case  it is left unspecified whether the file position (if
00181 |        any) changes.
00182 | 
00183 | ERRORS
00184 |        EINTR  The call was interrupted by  a  signal  before  any
00185 |               data was read.
00186 | 
00187 |        EAGAIN Non-blocking I/O has been selected using O_NONBLOCK
00188 |               and no data was immediately available for  reading.
00189 | 
00190 |        EIO    I/O  error.  This  will happen for example when the
00191 |               process is in a background process group, tries  to
00192 |               read  from  its  controlling  tty, and either it is
00193 |               ignoring or blocking SIGTTIN or its  process  group
00194 |               is  orphaned.   It  may  also occur when there is a
00195 |               low-level I/O error while reading from  a  disk  or
00196 |               tape.
00197 | 
00198 |        EISDIR fd refers to a directory.
00199 | 
00200 |        EBADF  fd  is  not  a valid file descriptor or is not open
00201 |               for reading.
00202 | 
00203 |        EINVAL fd is attached to an object which is unsuitable for
00204 |               reading.
00205 | 
00206 |        EFAULT buf is outside your accessible address space.
00207 | 
00208 |        Other  errors may occur, depending on the object connected
00209 |        to fd.  POSIX allows a  read  that  is  interrupted  after
00210 |        reading  some  data to return -1 (with errno set to EINTR)
00211 |        or to return the number of bytes already read.
00212 +----------------------------------------------------------------------*/
00213 #ifndef __HAS_MAIN
00214 extern ssize_t read(int fd, void *buf, size_t count);
00215 #else
00216 #if !defined(__cflow_processed) || defined(_uses_read_fcntl_os1_h)
00217 ssize_t read(int fd, void *buf, size_t count)
00218 {
00219         vector int sys_rval;
00220         ssize_t result;
00221 
00222         asm("\t!! start read()\n");
00223 
00224         asm("\t$io_start\n"
00225             "\t\\equ $cmd   $SYS_IOCMD_BRD\n"
00226             "\t\\equ $fmt   $SYS_IOFMT_BIN\n"
00227             "\t\\equ $sep   $SYS_IOPSEP_NOP\n"
00228             "\t\\equ $rdflg $SYS_IORDFLG_NOP\n"
00229             "\t\\equ $dev   $SYS_IODEV_MEM\n"
00230             "\t\\equ $l     %1>>4\n"
00231             "\t\\equ $bs    $SYS_IOBS_V\n"
00232             "\t$io_fd( 0.%2 )\n"
00233             "\t$io_slice_all\n"
00234             "\t$io_packet($cmd, <$fmt .or. $sep>, $rdflg, $dev, $l, $bs, 0.%3)\n"
00235             "\t$io_end\n"
00236             "\tlmtr %0 $MEM_SYS_RVAL\n"
00237             "\t!! end read()\n"
00238             : "=r" (sys_rval)
00239             : "r" (count), "r" (fd), "r" (buf) );
00240 
00241         result = sys_rval.hi << 4;      // number of bytes
00242         where (sys_rval.lo) {
00243                 errno = sys_rval.hi;
00244                 result = -1;
00245         }
00246 
00247         return result;
00248 }
00249 #endif // read()
00250 #endif // Has Main
00251 /*---------------------------------------------------------------------
00252 | NAME
00253 |        write - write to a file descriptor
00254 | 
00255 | SYNOPSIS
00256 |        #include <unistd.h>
00257 | 
00258 |        ssize_t write(int fd, const void *buf, size_t count);
00259 | 
00260 | DESCRIPTION
00261 |        write  writes  up to count bytes to the file referenced by
00262 |        the file descriptor fd from the buffer  starting  at  buf.
00263 |        POSIX  requires that a read() which can be proved to occur
00264 |        after a write() has returned returns the new  data.   Note
00265 |        that not all file systems are POSIX conforming.
00266 | 
00267 | RETURN VALUE
00268 |        On success, the number of bytes written are returned (zero
00269 |        indicates nothing was written).  On error, -1 is returned,
00270 |        and  errno is set appropriately.  If count is zero and the
00271 |        file descriptor refers  to  a  regular  file,  0  will  be
00272 |        returned  without causing any other effect.  For a special
00273 |        file, the results are not portable.
00274 | 
00275 | ERRORS
00276 |        EBADF  fd is not a valid file descriptor or  is  not  open
00277 |               for writing.
00278 | 
00279 |        EINVAL fd is attached to an object which is unsuitable for
00280 |               writing.
00281 | 
00282 |        EFAULT buf is outside your accessible address space.
00283 | 
00284 |        EPIPE  fd is connected to a pipe or socket  whose  reading
00285 |               end  is closed.  When this happens the writing pro-
00286 |               cess will receive a SIGPIPE signal; if it  catches,
00287 |               blocks or ignores this the error EPIPE is returned.
00288 | 
00289 |        EAGAIN Non-blocking I/O has been selected using O_NONBLOCK
00290 |               and the write would block.
00291 | 
00292 |        EINTR  The  call  was  interrupted  by a signal before any
00293 |               data was written.
00294 | 
00295 |        ENOSPC The device containing the file referred  to  by  fd
00296 |               has no room for the data.
00297 | 
00298 |        EIO    A  low-level I/O error occurred while modifying the
00299 |               inode.
00300 | 
00301 |        Other errors may occur, depending on the object  connected
00302 |        to fd.
00303 +----------------------------------------------------------------------*/
00304 
00305 #ifndef __HAS_MAIN
00306 extern ssize_t write(int fd, void *buf, size_t count);
00307 #else
00308 #if !defined(__cflow_processed) || defined(_uses_write_fcntl_os1_h)
00309 ssize_t write(int fd, void *buf, size_t count)
00310 {
00311         vector int sys_rval;
00312         ssize_t result;
00313 
00314         asm("\t!! start write()\n");
00315 
00316         asm("\t$io_start\n"
00317             "\t\\equ $cmd   $SYS_IOCMD_GWR\n"
00318             "\t\\equ $fmt   $SYS_IOFMT_BIN\n"
00319             "\t\\equ $sep   $SYS_IOPSEP_NOP\n"
00320             "\t\\equ $rdflg $SYS_IORDFLG_NOP\n"
00321             "\t\\equ $dev   $SYS_IODEV_MEM\n"
00322             "\t\\equ $l     %1>>4\n"
00323             "\t\\equ $bs    $SYS_IOBS_V\n"
00324             "\t$io_fd( 0.%2 )\n"
00325             "\t$io_slice_all\n"
00326             "\t$io_packet($cmd, <$fmt .or. $sep>, $rdflg, $dev, $l, $bs, 0.%3)\n"
00327             "\t$io_end\n"
00328             "\tlmtr %0 $MEM_SYS_RVAL\n"
00329             "\t!! end write()\n"
00330             : "=r" (sys_rval)
00331             : "r" (count), "r" (fd), "r" (buf) );
00332 
00333         result = sys_rval.hi << 4;      // number of bytes
00334         where (sys_rval.lo) {
00335                 errno = sys_rval.hi;
00336                 result = -1;
00337         }
00338 
00339         return result;
00340 }
00341 #endif // write()
00342 #endif // Has Main
00343 
00344 
00345 /*----------------------------------------------------------------------
00346 | NAME
00347 |        close - close a file descriptor
00348 | 
00349 | SYNOPSIS
00350 |        #include <unistd.h>
00351 | 
00352 |        int close(int fd);
00353 | 
00354 | DESCRIPTION
00355 |        close  closes  a  file  descriptor,  so  that it no longer
00356 |        refers to any file and may be reused. Any  locks  held  on
00357 |        the file it was associated with, and owned by the process,
00358 |        are removed (regardless of the file  descriptor  that  was
00359 |        used to obtain the lock).
00360 | 
00361 |        If fd is the last copy of a particular file descriptor the
00362 |        resources associated with it are freed; if the  descriptor
00363 |        was  the  last  reference to a file which has been removed
00364 |        using unlink(2) the file is deleted.
00365 | 
00366 | RETURN VALUE
00367 |        close returns zero on success, or -1 if an error occurred.
00368 | 
00369 | ERRORS
00370 |        EBADF  fd isn't a valid open file descriptor.
00371 | 
00372 |        EINTR  The close() call was interrupted by a signal.
00373 | 
00374 |        EIO    An I/O error occurred.
00375 | 
00376 +-----------------------------------------------------------------------*/
00377 #ifndef __HAS_MAIN
00378 extern int close( int fd );
00379 #else
00380 #if !defined(__cflow_processed) || defined(_uses_close_fcntl_os1_h)
00381 int close( int fd ) 
00382 {
00383         int nf;
00384         vector int sys_rval;
00385 
00386         for(nf=0; nf<__NLCC_OS1_MAX_FILES__; nf++ ) { 
00387                 if( __files[nf].fd == fd ) 
00388                         break;
00389         }
00390         if( nf == __NLCC_OS1_MAX_FILES__ ) { 
00391                 errno = EBADF;
00392                 return -1;
00393         }
00394 
00395         asm("\t$io_start\n"
00396             "\t$io_fclose(0.%1)\n"
00397             "\t$io_end\n"
00398             "\tlmtr %0 $MEM_SYS_RVAL\n"
00399             : "=r" (sys_rval) : "r" (fd));
00400 
00401         if (sys_rval.lo) {
00402                 errno = sys_rval.hi;
00403                 return -1;
00404         }
00405 
00406         __files[nf].fd = 0;
00407         return 0;
00408 }
00409 #endif // close()
00410 #endif // Has Main
00411 
00412 /*----------------------------------------------------------------------
00413 | NAME
00414 |        lseek - reposition read/write file offset
00415 | 
00416 | SYNOPSIS
00417 |        #include <sys/types.h>
00418 |        #include <unistd.h>
00419 | 
00420 |        off_t lseek(int fildes, off_t offset, int whence);
00421 | 
00422 | DESCRIPTION
00423 |        The  lseek  function  repositions  the  offset of the file
00424 |        descriptor fildes to the argument offset according to  the
00425 |        directive whence as follows:
00426 | 
00427 |        SEEK_SET
00428 |               The offset is set to offset bytes.
00429 | 
00430 |        SEEK_CUR
00431 |               The offset is set to its current location plus off-
00432 |               set bytes.
00433 | 
00434 |        SEEK_END
00435 |               The offset is set to the size of the file plus off-
00436 |               set bytes.
00437 | 
00438 |        The lseek function allows the file offset to be set beyond
00439 |        the end of the existing end-of-file of the file.  If  data
00440 |        is  later  written  at this point, subsequent reads of the
00441 |        data in the gap return bytes of zeros (until data is actu-
00442 |        ally written into the gap).
00443 | 
00444 | RETURN VALUE
00445 |        Upon  successful  completion,  lseek returns the resulting
00446 |        offset location as measured in bytes from the beginning of
00447 |        the file.  Otherwise, a value of (off_t)-1 is returned and
00448 |        errno is set to indicate the error.
00449 | 
00450 | ERRORS
00451 |        EBADF  Fildes is not an open file descriptor.
00452 | 
00453 |        ESPIPE Fildes is associated with a pipe, socket, or  FIFO.
00454 | 
00455 |        EINVAL Whence is not a proper value.
00456 +----------------------------------------------------------------------*/
00457 // The possibilities for the third argument to `fseek'.
00458 // These values should not be changed.  
00459 #ifndef SEEK_SET
00460 #define SEEK_SET        0       /* Seek from beginning of file.  */
00461 #define SEEK_CUR        1       /* Seek from current position.  */
00462 #define SEEK_END        2       /* Seek from end of file.  */
00463 #endif
00464 
00465 #if !defined(__cflow_processed) || defined(_uses_lseek_fcntl_os1_h)
00466 inline off_t lseek(int fildes, off_t offset, int whence)
00467 {
00468         int sys_whence;
00469         vector int sys_rval;
00470         off_t result;
00471 
00472         asm("\t!! begin lseek()\n");
00473 
00474         if (fildes < 0 || fildes > __NLCC_OS1_MAX_FILES__+40) {
00475                 errno = EBADF;
00476                 return (off_t) -1;
00477         }
00478 
00479         sys_whence = -2;
00480         where (whence == SEEK_SET)
00481                 asm("$sys_setwhence(%0, $SYS_FSE_SET)\n" : "=r" (sys_whence) );
00482         where (whence == SEEK_CUR)
00483                 asm("$sys_setwhence(%0, $SYS_FSE_CUR)\n" : "=r" (sys_whence) );
00484         where (whence == SEEK_END)
00485                 asm("$sys_setwhence(%0, $SYS_FSE_END)\n" : "=r" (sys_whence) );
00486         if (sys_whence < 0) {
00487                 errno = EINVAL;
00488                 return (off_t) -1;
00489         }
00490         
00491         asm("\t$sys_fseek( 0.%0, 0.%1, %2 )\n"
00492             : : "r" (fildes), "r" (offset), "r" (sys_whence));
00493         asm("\tlmtr %0 $MEM_SYS_RVAL\n" : "=r" (sys_rval));
00494         asm("\t!! end lseek()\n");
00495 
00496         result = sys_rval.hi;
00497         where ( sys_rval.lo ) {
00498                 errno = sys_rval.hi;
00499                 result = (off_t) -1;
00500         }
00501 
00502         return result;
00503 }
00504 #endif // lseek()
00505 
00506 
00507 
00508 #endif // __ANEXT_OS1_FCNTL_H__

Generated on Fri Jul 14 10:51:31 2006 for nlibc by doxygen 1.3.5