Changes in uspace/lib/posix/stdio.c [2a53f71:cfbb5d18] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/posix/stdio.c
r2a53f71 rcfbb5d18 44 44 #include "assert.h" 45 45 #include "errno.h" 46 #include "stdlib.h"47 46 #include "string.h" 48 47 #include "sys/types.h" 49 #include "unistd.h"50 48 51 49 #include "libc/io/printf_core.h" 52 50 #include "libc/str.h" 53 51 #include "libc/malloc.h" 54 #include "libc/adt/list.h"55 #include "libc/sys/stat.h"56 52 57 53 … … 256 252 assert(mode != NULL); 257 253 assert(stream != NULL); 254 255 if (filename == NULL) { 256 // TODO 257 258 /* print error to stderr as well, to avoid hard to find problems 259 * with buggy apps that expect this to work 260 */ 261 fprintf(stderr, 262 "ERROR: Application wants to use freopen() to change mode of opened stream.\n" 263 " libposix does not support that yet, the application may function improperly.\n"); 264 errno = ENOTSUP; 265 return NULL; 266 } 267 268 FILE* copy = malloc(sizeof(FILE)); 269 if (copy == NULL) { 270 errno = ENOMEM; 271 return NULL; 272 } 273 memcpy(copy, stream, sizeof(FILE)); 274 fclose(copy); /* copy is now freed */ 258 275 259 /* Retieve the node. */ 260 struct stat st; 261 int rc; 276 copy = fopen(filename, mode); /* open new stream */ 277 if (copy == NULL) { 278 /* fopen() sets errno */ 279 return NULL; 280 } 262 281 263 if (filename == NULL) { 264 rc = fstat(stream->fd, &st); 265 } else { 266 rc = stat(filename, &st); 267 } 282 /* move the new stream to the original location */ 283 memcpy(stream, copy, sizeof (FILE)); 284 free(copy); 268 285 269 if (rc != EOK) { 270 fclose(stream); 271 errno = -rc; 272 return NULL; 273 } 274 275 fdi_node_t node = { 276 .fs_handle = st.fs_handle, 277 .devmap_handle = st.devmap_handle, 278 .index = st.index 279 }; 280 281 /* Open a new stream. */ 282 FILE* new = fopen_node(&node, mode); 283 if (new == NULL) { 284 fclose(stream); 285 /* fopen_node() sets errno. */ 286 return NULL; 287 } 288 289 /* Close the original stream without freeing it (ignoring errors). */ 290 if (stream->buf != NULL) { 291 fflush(stream); 292 } 293 if (stream->sess != NULL) { 294 async_hangup(stream->sess); 295 } 296 if (stream->fd >= 0) { 297 close(stream->fd); 298 } 299 list_remove(&stream->link); 300 301 /* Move the new stream to the original location. */ 302 memcpy(stream, new, sizeof (FILE)); 303 free(new); 304 305 /* Update references in the file list. */ 286 /* update references in the file list */ 306 287 stream->link.next->prev = &stream->link; 307 288 stream->link.prev->next = &stream->link; … … 695 676 696 677 /** 697 * Remove a file or directory.678 * Remove a file. 698 679 * 699 680 * @param path Pathname of the file that shall be removed. 700 * @return Zero on success, -1 (with errno set)otherwise.681 * @return Zero on success, -1 otherwise. 701 682 */ 702 683 int posix_remove(const char *path) 703 684 { 704 struct stat st; 705 int rc = stat(path, &st); 706 707 if (rc != EOK) { 708 errno = -rc; 709 return -1; 710 } 711 712 if (st.is_directory) { 713 rc = rmdir(path); 714 } else { 715 rc = unlink(path); 716 } 717 718 if (rc != EOK) { 719 errno = -rc; 720 return -1; 721 } 722 return 0; 723 } 724 725 /** 726 * Rename a file or directory. 727 * 728 * @param old Old pathname. 729 * @param new New pathname. 730 * @return Zero on success, -1 (with errno set) otherwise. 731 */ 732 int posix_rename(const char *old, const char *new) 733 { 734 return errnify(rename, old, new); 735 } 736 737 /** 738 * Get a unique temporary file name (obsolete). 739 * 740 * @param s Buffer for the file name. Must be at least L_tmpnam bytes long. 741 * @return The value of s on success, NULL on failure. 685 // FIXME: unlink() and rmdir() seem to be equivalent at the moment, 686 // but that does not have to be true forever 687 return unlink(path); 688 } 689 690 /** 691 * 692 * @param s 693 * @return 742 694 */ 743 695 char *posix_tmpnam(char *s) 744 696 { 745 assert(L_tmpnam >= posix_strlen("/tmp/tnXXXXXX")); 746 747 static char buffer[L_tmpnam + 1]; 748 if (s == NULL) { 749 s = buffer; 750 } 751 752 posix_strcpy(s, "/tmp/tnXXXXXX"); 753 posix_mktemp(s); 754 755 if (*s == '\0') { 756 /* Errno set by mktemp(). */ 757 return NULL; 758 } 759 760 return s; 761 } 762 763 /** 764 * Get an unique temporary file name with additional constraints (obsolete). 765 * 766 * @param dir Path to directory, where the file should be created. 767 * @param pfx Optional prefix up to 5 characters long. 768 * @return Newly allocated unique path for temporary file. NULL on failure. 769 */ 770 char *posix_tempnam(const char *dir, const char *pfx) 771 { 772 /* Sequence number of the filename. */ 773 static int seq = 0; 774 775 size_t dir_len = posix_strlen(dir); 776 if (dir[dir_len - 1] == '/') { 777 dir_len--; 778 } 779 780 size_t pfx_len = posix_strlen(pfx); 781 if (pfx_len > 5) { 782 pfx_len = 5; 783 } 784 785 char *result = malloc(dir_len + /* slash*/ 1 + 786 pfx_len + /* three-digit seq */ 3 + /* .tmp */ 4 + /* nul */ 1); 787 788 if (result == NULL) { 789 errno = ENOMEM; 790 return NULL; 791 } 792 793 char *res_ptr = result; 794 posix_strncpy(res_ptr, dir, dir_len); 795 res_ptr += dir_len; 796 posix_strncpy(res_ptr, pfx, pfx_len); 797 res_ptr += pfx_len; 798 799 for (; seq < 1000; ++seq) { 800 snprintf(res_ptr, 8, "%03d.tmp", seq); 801 802 int orig_errno = errno; 803 errno = 0; 804 /* Check if the file exists. */ 805 if (posix_access(result, F_OK) == -1) { 806 if (errno == ENOENT) { 807 errno = orig_errno; 808 break; 809 } else { 810 /* errno set by access() */ 811 return NULL; 812 } 813 } 814 } 815 816 if (seq == 1000) { 817 free(result); 818 errno = EINVAL; 819 return NULL; 820 } 821 822 return result; 823 } 824 825 /** 826 * Create and open an unique temporary file. 827 * The file is automatically removed when the stream is closed. 828 * 829 * @param dir Path to directory, where the file should be created. 830 * @param pfx Optional prefix up to 5 characters long. 831 * @return Newly allocated unique path for temporary file. NULL on failure. 832 */ 833 FILE *posix_tmpfile(void) 834 { 835 char filename[] = "/tmp/tfXXXXXX"; 836 int fd = posix_mkstemp(filename); 837 if (fd == -1) { 838 /* errno set by mkstemp(). */ 839 return NULL; 840 } 841 842 /* Unlink the created file, so that it's removed on close(). */ 843 posix_unlink(filename); 844 return fdopen(fd, "w+"); 697 // TODO: low priority, just a compile-time dependency of binutils 698 not_implemented(); 845 699 } 846 700
Note:
See TracChangeset
for help on using the changeset viewer.