Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/io/io.c

    r6fa9a99d re86a617a  
    231231        if (stream->buf == NULL) {
    232232                errno = ENOMEM;
    233                 return -1;
     233                return EOF;
    234234        }
    235235       
     
    271271        stream->need_sync = false;
    272272        _setvbuf(stream);
     273        stream->ungetc_chars = 0;
    273274       
    274275        list_append(&stream->link, &files);
     
    293294        stream->need_sync = false;
    294295        _setvbuf(stream);
     296        stream->ungetc_chars = 0;
    295297       
    296298        list_append(&stream->link, &files);
     
    299301}
    300302
    301 int fclose(FILE *stream)
     303
     304static int _fclose_nofree(FILE *stream)
    302305{
    303306        int rc = 0;
     
    312315       
    313316        list_remove(&stream->link);
     317       
     318        if (rc != 0) {
     319                /* errno was set by close() */
     320                return EOF;
     321        }
     322       
     323        return 0;
     324}
     325
     326int fclose(FILE *stream)
     327{
     328        int rc = _fclose_nofree(stream);
    314329       
    315330        if ((stream != &stdin_null)
     
    318333                free(stream);
    319334       
    320         stream = NULL;
    321        
    322         if (rc != 0) {
    323                 /* errno was set by close() */
    324                 return EOF;
    325         }
    326        
    327         return 0;
     335        return rc;
     336}
     337
     338FILE *freopen(const char *path, const char *mode, FILE *stream)
     339{
     340        FILE *nstr;
     341       
     342        if (path == NULL) {
     343                /* Changing mode is not supported */
     344                return NULL;
     345        }
     346       
     347        (void) _fclose_nofree(stream);
     348        nstr = fopen(path, mode);
     349        if (nstr == NULL) {
     350                free(stream);
     351                return NULL;
     352        }
     353       
     354        list_remove(&nstr->link);
     355        *stream = *nstr;
     356        list_append(&stream->link, &files);
     357       
     358        free(nstr);
     359       
     360        return stream;
    328361}
    329362
     
    334367 * @param nmemb  Number of records to read.
    335368 * @param stream Pointer to the stream.
     369 *
     370 * @return Number of elements successfully read. On error this is less than
     371 *         nmemb, stream error indicator is set and errno is set.
    336372 */
    337373static size_t _fread(void *buf, size_t size, size_t nmemb, FILE *stream)
     
    348384                ssize_t rd = read(stream->fd, buf + done, left);
    349385               
    350                 if (rd < 0)
     386                if (rd < 0) {
     387                        /* errno was set by read() */
    351388                        stream->error = true;
    352                 else if (rd == 0)
     389                } else if (rd == 0) {
    353390                        stream->eof = true;
    354                 else {
     391                } else {
    355392                        left -= rd;
    356393                        done += rd;
     
    367404 * @param nmemb  Number of records to write.
    368405 * @param stream Pointer to the stream.
     406 *
     407 * @return Number of elements successfully written. On error this is less than
     408 *         nmemb, stream error indicator is set and errno is set.
    369409 */
    370410static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
     
    372412        size_t left;
    373413        size_t done;
     414        int rc;
    374415
    375416        if (size == 0 || nmemb == 0)
     
    381422        while ((left > 0) && (!stream->error)) {
    382423                ssize_t wr;
     424                size_t uwr;
    383425               
    384                 if (stream->kio)
    385                         wr = kio_write(buf + done, left);
    386                 else
     426                if (stream->kio) {
     427                        uwr = 0;
     428                        rc = kio_write(buf + done, left, &uwr);
     429                        if (rc != EOK)
     430                                errno = rc;
     431                } else {
    387432                        wr = write(stream->fd, buf + done, left);
     433                        if (wr >= 0) {
     434                                uwr = (size_t)wr;
     435                                rc = EOK;
     436                        } else {
     437                                /* errno was set by write */
     438                                uwr = 0;
     439                                rc = errno;
     440                        }
     441                }
    388442               
    389                 if (wr <= 0)
     443                if (rc != EOK) {
     444                        /* errno was set above */
    390445                        stream->error = true;
    391                 else {
    392                         left -= wr;
    393                         done += wr;
     446                } else {
     447                        left -= uwr;
     448                        done += uwr;
    394449                }
    395450        }
     
    401456}
    402457
    403 /** Read some data in stream buffer. */
     458/** Read some data in stream buffer.
     459 *
     460 * On error, stream error indicator is set and errno is set.
     461 */
    404462static void _ffillbuf(FILE *stream)
    405463{
     
    410468        rc = read(stream->fd, stream->buf, stream->buf_size);
    411469        if (rc < 0) {
     470                /* errno was set by read() */
    412471                stream->error = true;
    413472                return;
     
    434493
    435494        /* If buffer has prefetched read data, we need to seek back. */
    436         if (bytes_used > 0 && stream->buf_state == _bs_read)
    437                 lseek(stream->fd, - (ssize_t) bytes_used, SEEK_CUR);
     495        if (bytes_used > 0 && stream->buf_state == _bs_read) {
     496                off64_t rc;
     497                rc = lseek(stream->fd, - (ssize_t) bytes_used, SEEK_CUR);
     498                if (rc == (off64_t)-1) {
     499                        /* errno was set by lseek */
     500                        stream->error = 1;
     501                        return;
     502                }
     503        }
    438504
    439505        /* If buffer has unwritten data, we need to write them out. */
    440         if (bytes_used > 0 && stream->buf_state == _bs_write)
     506        if (bytes_used > 0 && stream->buf_state == _bs_write) {
    441507                (void) _fwrite(stream->buf_tail, 1, bytes_used, stream);
     508                /* On error stream error indicator and errno are set by _fwrite */
     509                if (stream->error)
     510                        return;
     511        }
    442512
    443513        stream->buf_head = stream->buf;
     
    466536                return 0;
    467537
     538        bytes_left = size * nmemb;
     539        total_read = 0;
     540        dp = (uint8_t *) dest;
     541
     542        /* Bytes from ungetc() buffer */
     543        while (stream->ungetc_chars > 0 && bytes_left > 0) {
     544                *dp++ = stream->ungetc_buf[--stream->ungetc_chars];
     545                ++total_read;
     546                --bytes_left;
     547        }
     548
    468549        /* If not buffered stream, read in directly. */
    469550        if (stream->btype == _IONBF) {
    470                 now = _fread(dest, size, nmemb, stream);
    471                 return now;
     551                total_read += _fread(dest, 1, bytes_left, stream);
     552                return total_read / size;
    472553        }
    473554
     
    482563        }
    483564
    484         bytes_left = size * nmemb;
    485         total_read = 0;
    486         dp = (uint8_t *) dest;
    487 
    488565        while ((!stream->error) && (!stream->eof) && (bytes_left > 0)) {
    489566                if (stream->buf_head == stream->buf_tail)
    490567                        _ffillbuf(stream);
    491568
    492                 if (stream->error || stream->eof)
     569                if (stream->error || stream->eof) {
     570                        /* On error errno was set by _ffillbuf() */
    493571                        break;
     572                }
    494573
    495574                data_avail = stream->buf_head - stream->buf_tail;
     
    546625        if (stream->buf_state == _bs_read)
    547626                _fflushbuf(stream);
    548 
    549627
    550628        /* Perform lazy allocation of stream buffer. */
     
    584662                        /* Only need to drain buffer. */
    585663                        _fflushbuf(stream);
    586                         need_flush = false;
     664                        if (!stream->error)
     665                                need_flush = false;
    587666                }
    588667        }
     
    618697int fputs(const char *str, FILE *stream)
    619698{
    620         return fwrite(str, str_size(str), 1, stream);
     699        (void) fwrite(str, str_size(str), 1, stream);
     700        if (ferror(stream))
     701                return EOF;
     702        return 0;
    621703}
    622704
     
    674756}
    675757
     758int ungetc(int c, FILE *stream)
     759{
     760        if (c == EOF)
     761                return EOF;
     762
     763        if (stream->ungetc_chars >= UNGETC_MAX)
     764                return EOF;
     765
     766        stream->ungetc_buf[stream->ungetc_chars++] =
     767            (uint8_t)c;
     768
     769        stream->eof = false;
     770        return (uint8_t)c;
     771}
     772
    676773int fseek(FILE *stream, off64_t offset, int whence)
    677774{
    678775        off64_t rc;
    679776
     777        if (stream->error)
     778                return EOF;
     779
    680780        _fflushbuf(stream);
     781        if (stream->error) {
     782                /* errno was set by _fflushbuf() */
     783                return EOF;
     784        }
     785
     786        stream->ungetc_chars = 0;
    681787
    682788        rc = lseek(stream->fd, offset, whence);
    683789        if (rc == (off64_t) (-1)) {
    684                 /* errno has been set by lseek64. */
    685                 return -1;
     790                /* errno has been set by lseek() */
     791                return EOF;
    686792        }
    687793
     
    692798off64_t ftell(FILE *stream)
    693799{
     800        off64_t pos;
     801       
     802        if (stream->error)
     803                return EOF;
     804       
    694805        _fflushbuf(stream);
    695         return lseek(stream->fd, 0, SEEK_CUR);
     806        if (stream->error) {
     807                /* errno was set by _fflushbuf() */
     808                return EOF;
     809        }
     810
     811        pos = lseek(stream->fd, 0, SEEK_CUR);
     812        if (pos == (off64_t) -1) {
     813                /* errno was set by lseek */
     814                return (off64_t) -1;
     815        }
     816       
     817        return pos - stream->ungetc_chars;
    696818}
    697819
     
    703825int fflush(FILE *stream)
    704826{
     827        if (stream->error)
     828                return EOF;
     829       
    705830        _fflushbuf(stream);
     831        if (stream->error) {
     832                /* errno was set by _fflushbuf() */
     833                return EOF;
     834        }
    706835       
    707836        if (stream->kio) {
    708837                kio_update();
    709                 return EOK;
     838                return 0;
    710839        }
    711840       
     
    716845                 */
    717846                stream->need_sync = false;
    718                 return fsync(stream->fd);
    719         }
    720        
    721         return ENOENT;
     847                if (fsync(stream->fd) != 0) {
     848                        /* errno was set by fsync() */
     849                        return EOF;
     850                }
     851
     852                return 0;
     853        }
     854       
     855        return 0;
    722856}
    723857
     
    742876        if (stream->kio) {
    743877                errno = EBADF;
    744                 return -1;
     878                return EOF;
    745879        }
    746880       
     
    748882}
    749883
    750 async_sess_t *fsession(exch_mgmt_t mgmt, FILE *stream)
     884async_sess_t *vfs_fsession(FILE *stream, iface_t iface)
    751885{
    752886        if (stream->fd >= 0) {
    753887                if (stream->sess == NULL)
    754                         stream->sess = fd_session(mgmt, stream->fd);
     888                        stream->sess = vfs_fd_session(stream->fd, iface);
    755889               
    756890                return stream->sess;
     
    760894}
    761895
    762 int fhandle(FILE *stream, int *handle)
     896int vfs_fhandle(FILE *stream, int *handle)
    763897{
    764898        if (stream->fd >= 0) {
Note: See TracChangeset for help on using the changeset viewer.