Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/posix/src/stdlib.c

    r7c3fb9b r4e6a610  
    3838
    3939#include <errno.h>
     40#include <tmpfile.h>
    4041
    4142#include "posix/fcntl.h"
     
    5253/**
    5354 *
    54  * @param array
    55  * @param count
    56  * @param size
    57  * @param compare
    58  */
    59 int atexit(void (*func)(void))
    60 {
    61         // TODO: low priority, just a compile-time dependency of binutils
    62         not_implemented();
    63         return 0;
    64 }
    65 
    66 /**
    67  * Integer absolute value.
    68  *
    69  * @param i Input value.
    70  * @return Absolute value of the parameter.
    71  */
    72 int abs(int i)
    73 {
    74         return i < 0 ? -i : i;
    75 }
    76 
    77 /**
    78  * Long integer absolute value.
    79  *
    80  * @param i Input value.
    81  * @return Absolute value of the parameter.
    82  */
    83 long labs(long i)
    84 {
    85         return i < 0 ? -i : i;
    86 }
    87 
    88 /**
    89  * Long long integer absolute value.
    90  *
    91  * @param i Input value.
    92  * @return Absolute value of the parameter.
    93  */
    94 long long llabs(long long i)
    95 {
    96         return i < 0 ? -i : i;
    97 }
    98 
    99 /**
    100  * Compute the quotient and remainder of an integer division.
    101  *
    102  * @param numer Numerator.
    103  * @param denom Denominator.
    104  * @return Quotient and remainder packed into structure.
    105  */
    106 div_t div(int numer, int denom)
    107 {
    108         return (div_t) { .quot = numer / denom, .rem = numer % denom };
    109 }
    110 
    111 /**
    112  * Compute the quotient and remainder of a long integer division.
    113  *
    114  * @param numer Numerator.
    115  * @param denom Denominator.
    116  * @return Quotient and remainder packed into structure.
    117  */
    118 ldiv_t ldiv(long numer, long denom)
    119 {
    120         return (ldiv_t) { .quot = numer / denom, .rem = numer % denom };
    121 }
    122 
    123 /**
    124  * Compute the quotient and remainder of a long long integer division.
    125  *
    126  * @param numer Numerator.
    127  * @param denom Denominator.
    128  * @return Quotient and remainder packed into structure.
    129  */
    130 lldiv_t lldiv(long long numer, long long denom)
    131 {
    132         return (lldiv_t) { .quot = numer / denom, .rem = numer % denom };
    133 }
    134 
    135 /**
    136  * Binary search in a sorted array.
    137  *
    138  * @param key Object to search for.
    139  * @param base Pointer to the first element of the array.
    140  * @param nmemb Number of elements in the array.
    141  * @param size Size of each array element.
    142  * @param compar Comparison function.
    143  * @return Pointer to a matching element, or NULL if none can be found.
    144  */
    145 void *bsearch(const void *key, const void *base,
    146     size_t nmemb, size_t size, int (*compar)(const void *, const void *))
    147 {
    148         while (nmemb > 0) {
    149                 const void *middle = base + (nmemb / 2) * size;
    150                 int cmp = compar(key, middle);
    151                 if (cmp == 0) {
    152                         return (void *) middle;
    153                 }
    154                 if (middle == base) {
    155                         /*
    156                          * There is just one member left to check and it
    157                          * didn't match the key. Avoid infinite loop.
    158                          */
    159                         break;
    160                 }
    161                 if (cmp < 0) {
    162                         nmemb = nmemb / 2;
    163                 } else if (cmp > 0) {
    164                         nmemb = nmemb - (nmemb / 2);
    165                         base = middle;
    166                 }
    167         }
    168 
    169         return NULL;
    170 }
    171 
    172 /**
    173  * Retrieve a value of the given environment variable.
    174  *
    175  * Since HelenOS doesn't support env variables at the moment,
    176  * this function always returns NULL.
    177  *
    178  * @param name Name of the variable.
    179  * @return Value of the variable or NULL if such variable does not exist.
    180  */
    181 char *getenv(const char *name)
    182 {
    183         return NULL;
    184 }
    185 
    186 /**
    187  *
    18855 * @param name
    18956 * @param resolved
     
    19360{
    19461        // TODO: low priority, just a compile-time dependency of binutils
    195         not_implemented();
    196         return 0;
    197 }
    198 
    199 /**
    200  * Issue a command.
    201  *
    202  * @param string String to be passed to a command interpreter or NULL.
    203  * @return Termination status of the command if the command is not NULL,
    204  *     otherwise indicate whether there is a command interpreter (non-zero)
    205  *     or not (zero).
    206  */
    207 int system(const char *string)
    208 {
    209         // TODO: does nothing at the moment
    21062        not_implemented();
    21163        return 0;
     
    312164int mkstemp(char *tmpl)
    313165{
    314         int fd = -1;
    315 
    316         char *tptr = tmpl + strlen(tmpl) - 6;
    317 
    318         while (fd < 0) {
    319                 if (*mktemp(tmpl) == '\0') {
    320                         /* Errno set by mktemp(). */
    321                         return -1;
    322                 }
    323 
    324                 fd = open(tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
    325 
    326                 if (fd == -1) {
    327                         /* Restore template to it's original state. */
    328                         snprintf(tptr, 7, "XXXXXX");
    329                 }
    330         }
    331 
    332         return fd;
     166        int tmpl_len;
     167        int file;
     168
     169        tmpl_len = strlen(tmpl);
     170        if (tmpl_len < 6) {
     171                errno = EINVAL;
     172                return -1;
     173        }
     174
     175        char *tptr = tmpl + tmpl_len - 6;
     176        if (strcmp(tptr, "XXXXXX") != 0) {
     177                errno = EINVAL;
     178                return -1;
     179        }
     180
     181        file = __tmpfile_templ(tmpl, true);
     182        if (file < 0) {
     183                errno = EIO; // XXX could be more specific
     184                return -1;
     185        }
     186
     187        return file;
    333188}
    334189
     
    343198char *mktemp(char *tmpl)
    344199{
    345         int tmpl_len = strlen(tmpl);
     200        int tmpl_len;
     201        int rc;
     202
     203        tmpl_len = strlen(tmpl);
    346204        if (tmpl_len < 6) {
    347205                errno = EINVAL;
     
    357215        }
    358216
    359         static int seq = 0;
    360 
    361         for (; seq < 1000000; ++seq) {
    362                 snprintf(tptr, 7, "%06d", seq);
    363 
    364                 int orig_errno = errno;
    365                 errno = 0;
    366                 /* Check if the file exists. */
    367                 if (access(tmpl, F_OK) == -1) {
    368                         if (errno == ENOENT) {
    369                                 errno = orig_errno;
    370                                 break;
    371                         } else {
    372                                 /* errno set by access() */
    373                                 *tmpl = '\0';
    374                                 return tmpl;
    375                         }
    376                 }
    377         }
    378 
    379         if (seq == 10000000) {
    380                 errno = EEXIST;
     217        rc = __tmpfile_templ(tmpl, false);
     218        if (rc != 0) {
     219                errno = EIO; // XXX could be more specific
    381220                *tmpl = '\0';
    382221                return tmpl;
Note: See TracChangeset for help on using the changeset viewer.