Changes in uspace/lib/c/generic/io/io.c [59f388a:e86a617a] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/io/io.c
r59f388a re86a617a 35 35 #include <stdio.h> 36 36 #include <unistd.h> 37 #include <fcntl.h> 37 38 #include <assert.h> 38 39 #include <str.h> … … 44 45 #include <vfs/vfs.h> 45 46 #include <vfs/vfs_sess.h> 46 #include <vfs/inbox.h>47 47 #include <ipc/loc.h> 48 48 #include <adt/list.h> … … 55 55 static FILE stdin_null = { 56 56 .fd = -1, 57 .pos = 0,58 57 .error = true, 59 58 .eof = true, … … 70 69 static FILE stdout_kio = { 71 70 .fd = -1, 72 .pos = 0,73 71 .error = false, 74 72 .eof = false, … … 85 83 static FILE stderr_kio = { 86 84 .fd = -1, 87 .pos = 0,88 85 .error = false, 89 86 .eof = false, … … 104 101 static LIST_INITIALIZE(files); 105 102 106 void __stdio_init(void) 107 { 108 /* The first three standard file descriptors are assigned for compatibility. 109 * This will probably be removed later. 110 */ 111 112 int infd = inbox_get("stdin"); 113 if (infd >= 0) { 114 int stdinfd = vfs_clone(infd, -1, false); 115 assert(stdinfd == 0); 116 vfs_open(stdinfd, MODE_READ); 117 stdin = fdopen(stdinfd, "r"); 103 void __stdio_init(int filc) 104 { 105 if (filc > 0) { 106 stdin = fdopen(0, "r"); 118 107 } else { 119 108 stdin = &stdin_null; … … 121 110 } 122 111 123 int outfd = inbox_get("stdout"); 124 if (outfd >= 0) { 125 int stdoutfd = vfs_clone(outfd, -1, false); 126 assert(stdoutfd <= 1); 127 while (stdoutfd < 1) 128 stdoutfd = vfs_clone(outfd, -1, false); 129 vfs_open(stdoutfd, MODE_APPEND); 130 stdout = fdopen(stdoutfd, "a"); 112 if (filc > 1) { 113 stdout = fdopen(1, "w"); 131 114 } else { 132 115 stdout = &stdout_kio; … … 134 117 } 135 118 136 int errfd = inbox_get("stderr"); 137 if (errfd >= 0) { 138 int stderrfd = vfs_clone(errfd, -1, false); 139 assert(stderrfd <= 2); 140 while (stderrfd < 2) 141 stderrfd = vfs_clone(errfd, -1, false); 142 vfs_open(stderrfd, MODE_APPEND); 143 stderr = fdopen(stderrfd, "a"); 119 if (filc > 2) { 120 stderr = fdopen(2, "w"); 144 121 } else { 145 122 stderr = &stderr_kio; … … 156 133 } 157 134 158 static bool parse_mode(const char * fmode, int *mode, bool *create, bool *truncate)135 static bool parse_mode(const char *mode, int *flags) 159 136 { 160 137 /* Parse mode except first character. */ 161 const char *mp = fmode;138 const char *mp = mode; 162 139 if (*mp++ == 0) { 163 140 errno = EINVAL; … … 179 156 return false; 180 157 } 181 182 *create = false; 183 *truncate = false; 184 185 /* Parse first character of fmode and determine mode for vfs_open(). */ 186 switch (fmode[0]) { 158 159 /* Parse first character of mode and determine flags for open(). */ 160 switch (mode[0]) { 187 161 case 'r': 188 * mode = plus ? MODE_READ | MODE_WRITE : MODE_READ;162 *flags = plus ? O_RDWR : O_RDONLY; 189 163 break; 190 164 case 'w': 191 *mode = plus ? MODE_READ | MODE_WRITE : MODE_WRITE; 192 *create = true; 193 if (!plus) 194 *truncate = true; 165 *flags = (O_TRUNC | O_CREAT) | (plus ? O_RDWR : O_WRONLY); 195 166 break; 196 167 case 'a': … … 200 171 return false; 201 172 } 202 203 *mode = MODE_APPEND | (plus ? MODE_READ | MODE_WRITE : MODE_WRITE); 204 *create = true; 173 *flags = (O_APPEND | O_CREAT) | (plus ? O_RDWR : O_WRONLY); 205 174 break; 206 175 default: … … 276 245 * 277 246 */ 278 FILE *fopen(const char *path, const char *fmode) 279 { 280 int mode; 281 bool create; 282 bool truncate; 283 284 if (!parse_mode(fmode, &mode, &create, &truncate)) 247 FILE *fopen(const char *path, const char *mode) 248 { 249 int flags; 250 if (!parse_mode(mode, &flags)) 285 251 return NULL; 286 252 … … 291 257 return NULL; 292 258 } 293 294 int flags = WALK_REGULAR; 295 if (create) 296 flags |= WALK_MAY_CREATE; 297 int file = vfs_lookup(path, flags); 298 if (file < 0) { 299 errno = file; 259 260 stream->fd = open(path, flags, 0666); 261 if (stream->fd < 0) { 262 /* errno was set by open() */ 300 263 free(stream); 301 264 return NULL; 302 265 } 303 304 int rc = vfs_open(file, mode); 305 if (rc != EOK) { 306 errno = rc; 307 vfs_put(file); 308 free(stream); 309 return NULL; 310 } 311 312 if (truncate) { 313 rc = vfs_resize(file, 0); 314 if (rc != EOK) { 315 errno = rc; 316 vfs_put(file); 317 free(stream); 318 return NULL; 319 } 320 } 321 322 stream->fd = file; 323 stream->pos = 0; 266 324 267 stream->error = false; 325 268 stream->eof = false; … … 345 288 346 289 stream->fd = fd; 347 stream->pos = 0;348 290 stream->error = false; 349 291 stream->eof = false; … … 370 312 371 313 if (stream->fd >= 0) 372 rc = vfs_put(stream->fd);314 rc = close(stream->fd); 373 315 374 316 list_remove(&stream->link); … … 431 373 static size_t _fread(void *buf, size_t size, size_t nmemb, FILE *stream) 432 374 { 375 size_t left, done; 376 433 377 if (size == 0 || nmemb == 0) 434 378 return 0; 435 379 436 ssize_t rd = vfs_read(stream->fd, &stream->pos, buf, size * nmemb); 437 if (rd < 0) { 438 errno = rd; 439 stream->error = true; 440 rd = 0; 441 } else if (rd == 0) { 442 stream->eof = true; 443 } 444 445 return (rd / size); 380 left = size * nmemb; 381 done = 0; 382 383 while ((left > 0) && (!stream->error) && (!stream->eof)) { 384 ssize_t rd = read(stream->fd, buf + done, left); 385 386 if (rd < 0) { 387 /* errno was set by read() */ 388 stream->error = true; 389 } else if (rd == 0) { 390 stream->eof = true; 391 } else { 392 left -= rd; 393 done += rd; 394 } 395 } 396 397 return (done / size); 446 398 } 447 399 … … 458 410 static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream) 459 411 { 412 size_t left; 413 size_t done; 414 int rc; 415 460 416 if (size == 0 || nmemb == 0) 461 417 return 0; 462 418 463 ssize_t wr; 464 if (stream->kio) { 465 size_t nwritten; 466 wr = kio_write(buf, size * nmemb, &nwritten); 467 if (wr != EOK) { 419 left = size * nmemb; 420 done = 0; 421 422 while ((left > 0) && (!stream->error)) { 423 ssize_t wr; 424 size_t uwr; 425 426 if (stream->kio) { 427 uwr = 0; 428 rc = kio_write(buf + done, left, &uwr); 429 if (rc != EOK) 430 errno = rc; 431 } else { 432 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 } 442 443 if (rc != EOK) { 444 /* errno was set above */ 468 445 stream->error = true; 469 wr = 0;470 446 } else { 471 wr = nwritten; 447 left -= uwr; 448 done += uwr; 472 449 } 473 } else { 474 wr = vfs_write(stream->fd, &stream->pos, buf, size * nmemb); 475 if (wr < 0) { 476 errno = wr; 477 stream->error = true; 478 wr = 0; 479 } 480 } 481 482 if (wr > 0) 450 } 451 452 if (done > 0) 483 453 stream->need_sync = true; 484 454 485 return ( wr/ size);455 return (done / size); 486 456 } 487 457 … … 496 466 stream->buf_head = stream->buf_tail = stream->buf; 497 467 498 rc = vfs_read(stream->fd, &stream->pos, stream->buf, stream->buf_size);468 rc = read(stream->fd, stream->buf, stream->buf_size); 499 469 if (rc < 0) { 500 errno = rc;470 /* errno was set by read() */ 501 471 stream->error = true; 502 472 return; … … 523 493 524 494 /* If buffer has prefetched read data, we need to seek back. */ 525 if (bytes_used > 0 && stream->buf_state == _bs_read) 526 stream->pos -= bytes_used; 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 } 527 504 528 505 /* If buffer has unwritten data, we need to write them out. */ … … 796 773 int fseek(FILE *stream, off64_t offset, int whence) 797 774 { 798 int rc;775 off64_t rc; 799 776 800 777 if (stream->error) 801 return -1;778 return EOF; 802 779 803 780 _fflushbuf(stream); 804 781 if (stream->error) { 805 782 /* errno was set by _fflushbuf() */ 806 return -1;783 return EOF; 807 784 } 808 785 809 786 stream->ungetc_chars = 0; 810 787 811 struct stat st; 812 switch (whence) { 813 case SEEK_SET: 814 stream->pos = offset; 815 break; 816 case SEEK_CUR: 817 stream->pos += offset; 818 break; 819 case SEEK_END: 820 rc = vfs_stat(stream->fd, &st); 821 if (rc != EOK) { 822 errno = rc; 823 stream->error = true; 824 return -1; 825 } 826 stream->pos = st.size + offset; 827 break; 788 rc = lseek(stream->fd, offset, whence); 789 if (rc == (off64_t) (-1)) { 790 /* errno has been set by lseek() */ 791 return EOF; 828 792 } 829 793 … … 834 798 off64_t ftell(FILE *stream) 835 799 { 836 /* The native position is too large for the C99-ish interface. */ 837 if (stream->pos - stream->ungetc_chars > INT64_MAX) 838 return EOF; 839 800 off64_t pos; 801 840 802 if (stream->error) 841 803 return EOF; … … 847 809 } 848 810 849 return stream->pos - stream->ungetc_chars; 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; 850 818 } 851 819 … … 872 840 873 841 if ((stream->fd >= 0) && (stream->need_sync)) { 874 int rc;875 876 842 /** 877 843 * Better than syncing always, but probably still not the … … 879 845 */ 880 846 stream->need_sync = false; 881 rc = vfs_sync(stream->fd); 882 if (rc != EOK) { 883 errno = rc; 847 if (fsync(stream->fd) != 0) { 848 /* errno was set by fsync() */ 884 849 return EOF; 885 850 }
Note:
See TracChangeset
for help on using the changeset viewer.