Changeset 3e01316f in mainline for uspace/lib/posix/stdlib.c


Ignore:
Timestamp:
2011-08-17T18:04:50Z (13 years ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0cf27ee
Parents:
e898296d (diff), e6165be (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 libposix.

File:
1 edited

Legend:

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

    re898296d r3e01316f  
    4040
    4141#include "errno.h"
     42#include "fcntl.h"
    4243#include "limits.h"
     44#include "string.h"
     45#include "sys/stat.h"
     46#include "unistd.h"
    4347
    4448#include "libc/sort.h"
    4549#include "libc/str.h"
    4650#include "libc/vfs/vfs.h"
     51#include "libc/stats.h"
    4752
    4853/**
     
    385390
    386391/**
    387  *
    388  * @param tmpl
    389  * @return
     392 * Creates and opens an unique temporary file from template.
     393 *
     394 * @param tmpl Template. Last six characters must be XXXXXX.
     395 * @return The opened file descriptor or -1 on error.
     396 */
     397int posix_mkstemp(char *tmpl)
     398{
     399        int fd = -1;
     400       
     401        char *tptr = tmpl + posix_strlen(tmpl) - 6;
     402       
     403        while (fd < 0) {
     404                if (*posix_mktemp(tmpl) == '\0') {
     405                        /* Errno set by mktemp(). */
     406                        return -1;
     407                }
     408               
     409                fd = open(tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
     410               
     411                if (fd == -1) {
     412                        /* Restore template to it's original state. */
     413                        snprintf(tptr, 7, "XXXXXX");
     414                }
     415        }
     416       
     417        return fd;
     418}
     419
     420/**
     421 * Creates an unique temporary file name from template.
     422 *
     423 * @param tmpl Template. Last six characters must be XXXXXX.
     424 * @return The value of tmpl. The template is modified in place.
     425 *    If no temporary file name can be created, template is
     426 *    reduced to an empty string.
    390427 */
    391428char *posix_mktemp(char *tmpl)
    392429{
    393         // TODO: low priority, just a compile-time dependency of binutils
    394         not_implemented();
     430        int tmpl_len = posix_strlen(tmpl);
     431        if (tmpl_len < 6) {
     432                errno = EINVAL;
     433                *tmpl = '\0';
     434                return tmpl;
     435        }
     436       
     437        char *tptr = tmpl + tmpl_len - 6;
     438        if (posix_strcmp(tptr, "XXXXXX") != 0) {
     439                errno = EINVAL;
     440                *tmpl = '\0';
     441                return tmpl;
     442        }
     443       
     444        static int seq = 0;
     445       
     446        for (; seq < 1000000; ++seq) {
     447                snprintf(tptr, 7, "%06d", seq);
     448               
     449                int orig_errno = errno;
     450                errno = 0;
     451                /* Check if the file exists. */
     452                if (posix_access(tmpl, F_OK) == -1) {
     453                        if (errno == ENOENT) {
     454                                errno = orig_errno;
     455                                break;
     456                        } else {
     457                                /* errno set by access() */
     458                                *tmpl = '\0';
     459                                return tmpl;
     460                        }
     461                }
     462        }
     463       
     464        if (seq == 10000000) {
     465                errno = EEXIST;
     466                *tmpl = '\0';
     467                return tmpl;
     468        }
     469       
     470        return tmpl;
    395471}
    396472
    397473/**
    398474 * Get system load average statistics.
    399  *
    400  * Not supported. Always returns -1.
    401475 *
    402476 * @param loadavg Array where the load averages shall be placed.
     
    406480int bsd_getloadavg(double loadavg[], int nelem)
    407481{
    408         return -1;
     482        assert(nelem > 0);
     483       
     484        size_t count;
     485        load_t *loads = stats_get_load(&count);
     486       
     487        if (loads == NULL) {
     488                return -1;
     489        }
     490       
     491        if (((size_t) nelem) < count) {
     492                count = nelem;
     493        }
     494       
     495        for (size_t i = 0; i < count; ++i) {
     496                loadavg[i] = (double) loads[i];
     497        }
     498       
     499        free(loads);
     500        return count;
    409501}
    410502
Note: See TracChangeset for help on using the changeset viewer.