Changeset ff381a7 in mainline for uspace/lib/c/generic/io/io.c


Ignore:
Timestamp:
2015-11-02T20:54:19Z (8 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d8513177
Parents:
3feeab2 (diff), 5265eea4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

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

    r3feeab2 rff381a7  
    231231        if (stream->buf == NULL) {
    232232                errno = ENOMEM;
    233                 return -1;
     233                return EOF;
    234234        }
    235235       
     
    299299}
    300300
    301 int fclose(FILE *stream)
     301
     302static int _fclose_nofree(FILE *stream)
    302303{
    303304        int rc = 0;
     
    312313       
    313314        list_remove(&stream->link);
     315       
     316        if (rc != 0) {
     317                /* errno was set by close() */
     318                return EOF;
     319        }
     320       
     321        return 0;
     322}
     323
     324int fclose(FILE *stream)
     325{
     326        int rc = _fclose_nofree(stream);
    314327       
    315328        if ((stream != &stdin_null)
     
    318331                free(stream);
    319332       
    320         stream = NULL;
    321        
    322         if (rc != 0) {
    323                 /* errno was set by close() */
    324                 return EOF;
    325         }
    326        
    327         return 0;
     333        return rc;
     334}
     335
     336FILE *freopen(const char *path, const char *mode, FILE *stream)
     337{
     338        FILE *nstr;
     339       
     340        if (path == NULL) {
     341                /* Changing mode is not supported */
     342                return NULL;
     343        }
     344       
     345        (void) _fclose_nofree(stream);
     346        nstr = fopen(path, mode);
     347        if (nstr == NULL) {
     348                free(stream);
     349                return NULL;
     350        }
     351       
     352        list_remove(&nstr->link);
     353        *stream = *nstr;
     354        list_append(&stream->link, &files);
     355       
     356        free(nstr);
     357       
     358        return stream;
    328359}
    329360
     
    334365 * @param nmemb  Number of records to read.
    335366 * @param stream Pointer to the stream.
     367 *
     368 * @return Number of elements successfully read. On error this is less than
     369 *         nmemb, stream error indicator is set and errno is set.
    336370 */
    337371static size_t _fread(void *buf, size_t size, size_t nmemb, FILE *stream)
     
    348382                ssize_t rd = read(stream->fd, buf + done, left);
    349383               
    350                 if (rd < 0)
     384                if (rd < 0) {
     385                        /* errno was set by read() */
    351386                        stream->error = true;
    352                 else if (rd == 0)
     387                } else if (rd == 0) {
    353388                        stream->eof = true;
    354                 else {
     389                } else {
    355390                        left -= rd;
    356391                        done += rd;
     
    367402 * @param nmemb  Number of records to write.
    368403 * @param stream Pointer to the stream.
     404 *
     405 * @return Number of elements successfully written. On error this is less than
     406 *         nmemb, stream error indicator is set and errno is set.
    369407 */
    370408static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
     
    372410        size_t left;
    373411        size_t done;
     412        int rc;
    374413
    375414        if (size == 0 || nmemb == 0)
     
    381420        while ((left > 0) && (!stream->error)) {
    382421                ssize_t wr;
     422                size_t uwr;
    383423               
    384                 if (stream->kio)
    385                         wr = kio_write(buf + done, left);
    386                 else
     424                if (stream->kio) {
     425                        uwr = 0;
     426                        rc = kio_write(buf + done, left, &uwr);
     427                        if (rc != EOK)
     428                                errno = rc;
     429                } else {
    387430                        wr = write(stream->fd, buf + done, left);
     431                        if (wr >= 0) {
     432                                uwr = (size_t)wr;
     433                                rc = EOK;
     434                        } else {
     435                                /* errno was set by write */
     436                                uwr = 0;
     437                                rc = errno;
     438                        }
     439                }
    388440               
    389                 if (wr <= 0)
     441                if (rc != EOK) {
     442                        /* errno was set above */
    390443                        stream->error = true;
    391                 else {
    392                         left -= wr;
    393                         done += wr;
     444                } else {
     445                        left -= uwr;
     446                        done += uwr;
    394447                }
    395448        }
     
    401454}
    402455
    403 /** Read some data in stream buffer. */
     456/** Read some data in stream buffer.
     457 *
     458 * On error, stream error indicator is set and errno is set.
     459 */
    404460static void _ffillbuf(FILE *stream)
    405461{
     
    410466        rc = read(stream->fd, stream->buf, stream->buf_size);
    411467        if (rc < 0) {
     468                /* errno was set by read() */
    412469                stream->error = true;
    413470                return;
     
    434491
    435492        /* 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);
     493        if (bytes_used > 0 && stream->buf_state == _bs_read) {
     494                off64_t rc;
     495                rc = lseek(stream->fd, - (ssize_t) bytes_used, SEEK_CUR);
     496                if (rc == (off64_t)-1) {
     497                        /* errno was set by lseek */
     498                        stream->error = 1;
     499                        return;
     500                }
     501        }
    438502
    439503        /* If buffer has unwritten data, we need to write them out. */
    440         if (bytes_used > 0 && stream->buf_state == _bs_write)
     504        if (bytes_used > 0 && stream->buf_state == _bs_write) {
    441505                (void) _fwrite(stream->buf_tail, 1, bytes_used, stream);
     506                /* On error stream error indicator and errno are set by _fwrite */
     507                if (stream->error)
     508                        return;
     509        }
    442510
    443511        stream->buf_head = stream->buf;
     
    466534                return 0;
    467535
     536        bytes_left = size * nmemb;
     537        total_read = 0;
     538        dp = (uint8_t *) dest;
     539
     540        /* Bytes from ungetc() buffer */
     541        while (stream->ungetc_chars > 0 && bytes_left > 0) {
     542                *dp++ = stream->ungetc_buf[--stream->ungetc_chars];
     543                ++total_read;
     544                --bytes_left;
     545        }
     546
    468547        /* If not buffered stream, read in directly. */
    469548        if (stream->btype == _IONBF) {
    470                 now = _fread(dest, size, nmemb, stream);
    471                 return now;
     549                total_read += _fread(dest, 1, bytes_left, stream);
     550                return total_read / size;
    472551        }
    473552
     
    482561        }
    483562
    484         bytes_left = size * nmemb;
    485         total_read = 0;
    486         dp = (uint8_t *) dest;
    487 
    488563        while ((!stream->error) && (!stream->eof) && (bytes_left > 0)) {
    489564                if (stream->buf_head == stream->buf_tail)
    490565                        _ffillbuf(stream);
    491566
    492                 if (stream->error || stream->eof)
     567                if (stream->error || stream->eof) {
     568                        /* On error errno was set by _ffillbuf() */
    493569                        break;
     570                }
    494571
    495572                data_avail = stream->buf_head - stream->buf_tail;
     
    546623        if (stream->buf_state == _bs_read)
    547624                _fflushbuf(stream);
    548 
    549625
    550626        /* Perform lazy allocation of stream buffer. */
     
    584660                        /* Only need to drain buffer. */
    585661                        _fflushbuf(stream);
    586                         need_flush = false;
     662                        if (!stream->error)
     663                                need_flush = false;
    587664                }
    588665        }
     
    618695int fputs(const char *str, FILE *stream)
    619696{
    620         return fwrite(str, str_size(str), 1, stream);
     697        (void) fwrite(str, str_size(str), 1, stream);
     698        if (ferror(stream))
     699                return EOF;
     700        return 0;
    621701}
    622702
     
    674754}
    675755
     756int ungetc(int c, FILE *stream)
     757{
     758        if (c == EOF)
     759                return EOF;
     760
     761        if (stream->ungetc_chars >= UNGETC_MAX)
     762                return EOF;
     763
     764        stream->ungetc_buf[stream->ungetc_chars++] =
     765            (uint8_t)c;
     766
     767        stream->eof = false;
     768        return (uint8_t)c;
     769}
     770
    676771int fseek(FILE *stream, off64_t offset, int whence)
    677772{
    678773        off64_t rc;
    679774
     775        if (stream->error)
     776                return EOF;
     777
    680778        _fflushbuf(stream);
     779        if (stream->error) {
     780                /* errno was set by _fflushbuf() */
     781                return EOF;
     782        }
     783
     784        stream->ungetc_chars = 0;
    681785
    682786        rc = lseek(stream->fd, offset, whence);
    683787        if (rc == (off64_t) (-1)) {
    684                 /* errno has been set by lseek64. */
    685                 return -1;
     788                /* errno has been set by lseek() */
     789                return EOF;
    686790        }
    687791
     
    692796off64_t ftell(FILE *stream)
    693797{
     798        off64_t pos;
     799       
     800        if (stream->error)
     801                return EOF;
     802       
    694803        _fflushbuf(stream);
    695         return lseek(stream->fd, 0, SEEK_CUR);
     804        if (stream->error) {
     805                /* errno was set by _fflushbuf() */
     806                return EOF;
     807        }
     808
     809        pos = lseek(stream->fd, 0, SEEK_CUR);
     810        if (pos == (off64_t) -1) {
     811                /* errno was set by lseek */
     812                return (off64_t) -1;
     813        }
     814       
     815        return pos - stream->ungetc_chars;
    696816}
    697817
     
    703823int fflush(FILE *stream)
    704824{
     825        if (stream->error)
     826                return EOF;
     827       
    705828        _fflushbuf(stream);
     829        if (stream->error) {
     830                /* errno was set by _fflushbuf() */
     831                return EOF;
     832        }
    706833       
    707834        if (stream->kio) {
    708835                kio_update();
    709                 return EOK;
     836                return 0;
    710837        }
    711838       
     
    716843                 */
    717844                stream->need_sync = false;
    718                 return fsync(stream->fd);
    719         }
    720        
    721         return ENOENT;
     845                if (fsync(stream->fd) != 0) {
     846                        /* errno was set by fsync() */
     847                        return EOF;
     848                }
     849
     850                return 0;
     851        }
     852       
     853        return 0;
    722854}
    723855
     
    742874        if (stream->kio) {
    743875                errno = EBADF;
    744                 return -1;
     876                return EOF;
    745877        }
    746878       
     
    748880}
    749881
    750 async_sess_t *fsession(exch_mgmt_t mgmt, FILE *stream)
     882async_sess_t *vfs_fsession(FILE *stream, iface_t iface)
    751883{
    752884        if (stream->fd >= 0) {
    753885                if (stream->sess == NULL)
    754                         stream->sess = fd_session(mgmt, stream->fd);
     886                        stream->sess = vfs_fd_session(stream->fd, iface);
    755887               
    756888                return stream->sess;
     
    760892}
    761893
    762 int fhandle(FILE *stream, int *handle)
     894int vfs_fhandle(FILE *stream, int *handle)
    763895{
    764896        if (stream->fd >= 0) {
Note: See TracChangeset for help on using the changeset viewer.