示例#1
0
int fputc(int c, FAR FILE *stream)
{
  unsigned char buf = (unsigned char)c;
  int ret;

  ret = lib_fwrite(&buf, 1, stream);
  if (ret > 0)
    {
      /* Flush the buffer if a newline is output */

#ifdef CONFIG_STDIO_LINEBUFFER
      if (c == '\n')
        {
          ret = lib_fflush(stream, true);
          if (ret < 0)
            {
              return EOF;
            }
        }
#endif
      return c;
    }
  else
    {
      return EOF;
    }
}
示例#2
0
int fflush(FAR FILE *stream)
{
    int ret;

    /* Is the stream argument NULL? */

    if (!stream)
    {
        /* Yes... then this is a request to flush all streams */

        ret = lib_flushall(sched_getstreams());
    }
    else
    {
        ret = lib_fflush(stream, true);
    }

    /* Check the return value */

    if (ret < 0)
    {
        /* An error occurred during the flush AND/OR we were unable to flush
         * all of the buffered write data. Set the errno value.
         */

        set_errno(-ret);

        /* And return EOF on failure. */

        return EOF;
    }

    return OK;
}
示例#3
0
int lib_flushall(FAR struct streamlist *list)
{
  int lasterrno = OK;
  int ret = OK;

  /* Make sure that there are streams associated with this thread */

  if (list)
    {
       int i;

       /* Process each stream in the thread's stream list */

       stream_semtake(list);
       for (i = 0; i < CONFIG_NFILE_STREAMS; i++)
         {
           FILE *stream = &list->sl_streams[i];

           /* If the stream is open (i.e., assigned a non-negative file
            * descriptor) and opened for writing, then flush all of the pending
            * write data in the stream.
            */

           if (stream->fs_filedes >= 0 && (stream->fs_oflags & O_WROK) != 0)
             {
               /* Flush the writable FILE */

               if (lib_fflush(stream, true) != 0)
                 {
                   /* An error occurred during the flush AND/OR we were unable
                    * to flush all of the buffered write data.  Return EOF on failure.
                    */

                   lasterrno = get_errno();
                   ret = ERROR;
                 }
             }
         }
       stream_semgive(list);
    }

  /* If any flush failed, return that last failed flush */

  if (ret != OK)
    {
      set_errno(lasterrno);
    }
  return ret;
}
示例#4
0
int lib_wrflush(FAR FILE *stream)
{
#if CONFIG_STDIO_BUFFER_SIZE > 0
  /* Verify that we were passed a valid (i.e., non-NULL) stream */

#ifdef CONFIG_DEBUG
  if (!stream)
    {
      return -EINVAL;
    }
#endif

  /* Verify that the stream is opened for writing... lib_fflush will
   * return an error if it is called for a stream that is not opened for
   * writing.  Check that first so that this function will not fail in
   * that case.
   */

  if ((stream->fs_oflags & O_WROK) == 0)
    {
      /* Report that the success was successful if we attempt to flush a
       * read-only stream.
       */

      return OK;
    }

  /* Flush the stream.   Return success if there is no buffered write data
   * -- i.e., that the stream is opened for writing and  that all of the
   * buffered write data was successfully flushed by lib_fflush().
   */

  return lib_fflush(stream, true);
#else
  /* Verify that we were passed a valid (i.e., non-NULL) stream */

#ifdef CONFIG_DEBUG
  if (!stream)
    {
      return -EINVAL;
    }
#endif

  return OK;
#endif
}
示例#5
0
int fputs(FAR const char *s, FAR FILE *stream)
{
  int nput;
  int ret;
  char ch;

  /* Make sure that a string was provided. */

#ifdef CONFIG_DEBUG /* Most parameter checking is disabled if DEBUG is off */
  if (!s)
    {
      set_errno(EINVAL);
      return EOF;
    }
#endif

  /* Write the string.  Loop until the null terminator is encountered */

  for (nput = 0, ch = up_romgetc(s); ch; nput++, s++, ch = up_romgetc(s))
    {
      /* Write the next character to the stream buffer */

      ret = lib_fwrite(&ch, 1, stream);
      if (ret <= 0)
        {
          return EOF;
        }

      /* Flush the buffer if a newline was written to the buffer */

#ifdef CONFIG_STDIO_LINEBUFFER
      if (ch == '\n')
        {
          ret = lib_fflush(stream, true);
          if (ret < 0)
            {
              return EOF;
            }
        }
#endif
    }

  return nput;
}
示例#6
0
文件: lib_puts.c 项目: dagar/NuttX
int puts(FAR const char *s)
{
  FILE *stream = stdout;
  int nwritten;
  int nput = EOF;
  int ret;

  /* Write the string (the next two steps must be atomic) */

  lib_take_semaphore(stream);

  /* Write the string without its trailing '\0' */

  nwritten = fputs(s, stream);
  if (nwritten > 0)
    {
      /* Followed by a newline */

      char newline = '\n';
      ret = lib_fwrite(&newline, 1, stream);
      if (ret > 0)
        {
          nput = nwritten + 1;

          /* Flush the buffer after the newline is output if line buffering
           * is enabled.
           */

          if ((stream->fs_flags & __FS_FLAG_LBF) != 0)
            {
              ret = lib_fflush(stream, true);
              if (ret < 0)
                {
                  nput = EOF;
                }
            }
        }
    }

  lib_give_semaphore(stdout);
  return nput;
}
示例#7
0
int fflush(FAR FILE *stream)
{
  /* Is the stream argument NULL? */

  if (!stream)
    {
      /* Yes... then this is a request to flush all streams */

      return lib_flushall(sched_getstreams());
    }
  else if (lib_fflush(stream, true) != 0)
    {
      /* An error occurred during the flush AND/OR we were unable to flush all
       * of the buffered write data.  Return EOF on failure.
       */

      return EOF;
    }
  return OK;
}
示例#8
0
文件: lib_puts.c 项目: 9DSmart/Flow
int puts(FAR const char *s)
{
  FILE *stream = stdout;
  int nwritten;
  int nput = EOF;
  int ret;

  /* Write the string (the next two steps must be atomic) */

  lib_take_semaphore(stream);

  /* Write the string without its trailing '\0' */

  nwritten = fputs(s, stream);
  if (nwritten > 0)
    {
      /* Followed by a newline */

      char newline = '\n';
      ret = lib_fwrite(&newline, 1, stream);
      if (ret > 0)
        {
          nput = nwritten + 1;

          /* Flush the buffer after the newline is output. */

#ifdef CONFIG_STDIO_LINEBUFFER
          ret = lib_fflush(stream, true);
          if (ret < 0)
            {
              nput = EOF;
            }
#endif
        }
    }

  lib_give_semaphore(stdout);
  return nput;
}
示例#9
0
ssize_t lib_fwrite(FAR const void *ptr, size_t count, FAR FILE *stream)
#if CONFIG_STDIO_BUFFER_SIZE > 0
{
  FAR const unsigned char *start = ptr;
  FAR const unsigned char *src   = ptr;
  ssize_t ret = ERROR;
  unsigned char *dest;

  /* Make sure that writing to this stream is allowed */

  if (stream == NULL)
    {
      set_errno(EBADF);
      return ret;
    }

  if ((stream->fs_oflags & O_WROK) == 0)
    {
      set_errno(EBADF);
      goto errout;
    }

  /* Get exclusive access to the stream */

  lib_take_semaphore(stream);

  /* If the buffer is currently being used for read access, then
   * discard all of the read-ahead data.  We do not support concurrent
   * buffered read/write access.
   */

  if (lib_rdflush(stream) < 0)
    {
      goto errout_with_semaphore;
    }

  /* Loop until all of the bytes have been buffered */

  while (count > 0)
    {
      /* Determine the number of bytes left in the buffer */

      size_t gulp_size = stream->fs_bufend - stream->fs_bufpos;

      /* Will the user data fit into the amount of buffer space
       * that we have left?
       */

      if (gulp_size > count)
        {
          /* Yes, clip the gulp to the size of the user data */

          gulp_size = count;
        }

      /* Adjust the number of bytes remaining to be transferred
       * on the next pass through the loop (might be zero).
       */

      count -= gulp_size;

      /* Transfer the data into the buffer */

      for (dest = stream->fs_bufpos; gulp_size > 0; gulp_size--)
        {
          *dest++ = *src++;
        }

      stream->fs_bufpos = dest;

      /* Is the buffer full? */

      if (dest >= stream->fs_bufend)
        {
          /* Flush the buffered data to the IO stream */

          int bytes_buffered = lib_fflush(stream, false);
          if (bytes_buffered < 0)
            {
              goto errout_with_semaphore;
            }
        }
    }

  /* Return the number of bytes written */

  ret = src - start;

errout_with_semaphore:
  lib_give_semaphore(stream);

errout:
  if (ret < 0)
    {
      stream->fs_flags |= __FS_FLAG_ERROR;
    }

  return ret;
}
示例#10
0
int fclose(FAR FILE *stream)
{
  int err = EINVAL;
  int ret = ERROR;

  /* Verify that a stream was provided. */

  if (stream)
    {
      /* Flush the stream */

      ret = lib_fflush(stream, true);
      err = errno;

      /* Close the underlying file descriptor */

      if (stream->fs_filedes > 0)
        {
          /* Close the file and save the return status */

          int status = close(stream->fs_filedes);

          /* If close() returns an error but flush() did not then make
           * sure that we return the close() error condition.
           */

          if (ret == 0)
            {
              ret = status;
              err = errno;
            }
        }

#if CONFIG_STDIO_BUFFER_SIZE > 0
      /* Destroy the semaphore */

      sem_destroy(&stream->fs_sem);

      /* Release the buffer */

      if (stream->fs_bufstart)
        {
          lib_free(stream->fs_bufstart);
        }

      /* Clear the whole structure */

      memset(stream, 0, sizeof(FILE));
#else
#if CONFIG_NUNGET_CHARS > 0
      /* Reset the number of ungetc characters */

      stream->fs_nungotten = 0;
#endif
      /* Reset the flags */

      stream->fs_oflags = 0;
#endif
      /* Setting the fs_filedescriptor to -1 makes the stream available for reuse */

      stream->fs_filedes = -1;
    }

  /* On an error, reset the errno to the first error encountered and return
   * EOF.
   */

  if (ret != OK)
    {
      set_errno(err);
      return EOF;
    }

  /* Return success */

  return OK;
}