Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/posix/stdio.c

    r2a53f71 rcfbb5d18  
    4444#include "assert.h"
    4545#include "errno.h"
    46 #include "stdlib.h"
    4746#include "string.h"
    4847#include "sys/types.h"
    49 #include "unistd.h"
    5048
    5149#include "libc/io/printf_core.h"
    5250#include "libc/str.h"
    5351#include "libc/malloc.h"
    54 #include "libc/adt/list.h"
    55 #include "libc/sys/stat.h"
    5652
    5753
     
    256252        assert(mode != NULL);
    257253        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 */
    258275       
    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        }
    262281       
    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);
    268285       
    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 */
    306287        stream->link.next->prev = &stream->link;
    307288        stream->link.prev->next = &stream->link;
     
    695676
    696677/**
    697  * Remove a file or directory.
     678 * Remove a file.
    698679 *
    699680 * @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.
    701682 */
    702683int posix_remove(const char *path)
    703684{
    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
    742694 */
    743695char *posix_tmpnam(char *s)
    744696{
    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();
    845699}
    846700
Note: See TracChangeset for help on using the changeset viewer.