This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Retargeting: Return error from _sys_read()

Dear all,

The below implementation of _sys_read() returns an error code (a negative number, e.g. -7) if the underlaying file system functions indicates an error. The caller of _sys_read() (the C lib) seems not to accept such an error handling and repeatedly calls _sys_read() in order to complete the read operation. This ends up in an infinite loop.

How can I escape the "read loop" in the error case?

int _sys_read (FILEHANDLE fh, unsigned char * buf, unsigned len, int mode)
{
  int ret = EOF;
  struct __FILE * fp = (struct __FILE *)fh;
  if (fp != NULL)
  {
    if (fp->handle == STDIN)
    {
      /* Standard Input device. */
      while (len)
      {
        *buf = ITM_ReceiveChar();
        len --;
        ++buf;
        if('\r' == *buf )
        {
          break;
        }
      }
      ret = len;
    }
#if _RETARGET_USE_FILESYSTEM
    else if (NULL != fp->fd)
    {
# if (_RETARGET_USE_DATAFLASH_FILE && _RETARGET_USE_SD_CARD_FILE)
      if ((fp->handle == DATAFLASH) || (fp->handle == SD_CARD))             // both
# elif _RETARGET_USE_DATAFLASH_FILE
      if (fp->handle == DATAFLASH)                                          // only DATAFLASH
# elif _RETARGET_USE_SD_CARD_FILE
      if (fp->handle == SD_CARD)                                            // only SD_CARD
# endif
      {
        I16 err;
        U32 size = FILESYSTEM_FRead(buf, 1, len, fp->fd);

        // It is in fact very simple if we support case (A):
        // - if not len bytes read, EOF was reached or an error occured
        // - if no error occured len bytes are read and the remaining bytes
        //   is 0, which corresponds FS_ERR_OK
        //
        // -> we can thus return the result of FS_FError()
        err = FILESYSTEM_FError(fp->fd);
        if ((err == FS_ERR_OK) || (err == FS_ERR_EOF))
        {
          ret = len - size;
        }
        else
        {
          ret = err;
        }
      }
    }
#endif // _RETARGET_USE_FILESYSTEM
  }
  return ret;
}