Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  2. #include <libc/stubs.h>
  3. #include <stdio.h>
  4. #include <unistd.h>
  5. #include <libc/file.h>
  6. #include <fcntl.h>
  7. #include <libc/dosio.h>
  8.  
  9. long
  10. ftell(FILE *f)
  11. {
  12.   long tres;
  13.   int adjust=0;
  14.   int idx;
  15.  
  16.   if (f->_cnt < 0)
  17.     f->_cnt = 0;
  18.   if (f->_flag&_IOREAD)
  19.   {
  20.     /* When reading files, the file position known by `lseek' is
  21.      at the end of the buffered portion of the file.  So `adjust'
  22.      is negative (current buf position is BEFORE the one returned
  23.      by `lseek') and, for TEXT files, it gets decremented (larger
  24.      in absolute value) for every NL from current pos to the end
  25.      of the buffer, to account for stripped CR characters.  */
  26.     adjust = - f->_cnt;
  27.  
  28.     if (__file_handle_modes[f->_file] & O_TEXT) /* if a text file */
  29.     {
  30.       if (f->_cnt)
  31.       {
  32.         char *cp;
  33.  
  34.         /* For every char in buf AFTER current pos... */
  35.         for (cp=f->_ptr + f->_cnt - 1; cp >= f->_ptr; cp--)
  36.           if (*cp == '\n')      /* ...if it's LF... */
  37.             adjust--;           /* ...there was a CR also */
  38.       }
  39.     }
  40.   }
  41.   else if (f->_flag&(_IOWRT|_IORW))
  42.   {
  43.     /* When writing a file, the current file position known by `lseek'
  44.        is at the beginning of the buffered portion of the file.  We
  45.        have to adjust it by our offset from the beginning of the buffer,
  46.        and account for the CR characters which will be added by `write'.  */
  47.     if (f->_flag&_IOWRT && f->_base && (f->_flag&_IONBF)==0)
  48.     {
  49.       int lastidx = adjust = f->_ptr - f->_base;
  50.  
  51.       if (__file_handle_modes[f->_file] & O_TEXT)
  52.         for (idx=0; idx < lastidx; idx++)
  53.           if (f->_base[idx] == '\n')
  54.             adjust++;
  55.     }
  56.   }
  57.   else
  58.     return -1;
  59.   if(f && f->std_ops && STM_OP(f,seek))
  60.    tres=STM_OP(f,seek)(f,0,1);
  61.   else
  62.    tres = lseek(fileno(f), 0L, 1);
  63.   if (tres<0)
  64.     return tres;
  65.   tres += adjust;
  66.   return tres;
  67. }
  68.