HelenOS sources

root/uspace/lib/posix/src/stdlib.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. putenv
  2. realpath
  3. atof
  4. strtof
  5. strtod
  6. mkstemp
  7. mktemp
  8. bsd_getloadavg

/*
 * Copyright (c) 2011 Petr Koupy
 * Copyright (c) 2011 Jiri Zarevucky
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * - The name of the author may not be used to endorse or promote products
 *   derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/** @addtogroup libposix
 * @{
 */
/** @file Standard library definitions.
 */

#include "internal/common.h"
#include <stdlib.h>

#include <errno.h>
#include <tmpfile.h>

#include <fcntl.h>
#include <limits.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include <qsort.h>
#include <str.h>
#include <vfs/vfs.h>
#include <stats.h>

/**
 *
 * @param name
 * @param resolved
 * @return
 */
int putenv(char *string)
{
        // TODO: low priority, just a compile-time dependency of binutils
        not_implemented();
        return 0;
}

/**
 * Resolve absolute pathname.
 *
 * @param name Pathname to be resolved.
 * @param resolved Either buffer for the resolved absolute pathname or NULL.
 * @return On success, either resolved (if it was not NULL) or pointer to the
 *     newly allocated buffer containing the absolute pathname (if resolved was
 *     NULL). Otherwise NULL.
 *
 */
char *realpath(const char *restrict name, char *restrict resolved)
{
#ifndef PATH_MAX
        assert(resolved == NULL);
#endif

        if (name == NULL) {
                errno = EINVAL;
                return NULL;
        }

        // TODO: symlink resolution

        /*
         * Function absolutize is implemented in libc and declared in vfs.h.
         * No more processing is required as HelenOS doesn't have symlinks
         * so far (as far as I can tell), although this function will need
         * to be updated when that support is implemented.
         */
        char *absolute = vfs_absolutize(name, NULL);

        if (absolute == NULL) {
                /*
                 * POSIX requires some specific errnos to be set
                 * for some cases, but there is no way to find out from
                 * absolutize().
                 */
                errno = EINVAL;
                return NULL;
        }

        if (resolved == NULL) {
                return absolute;
        } else {
#ifdef PATH_MAX
                str_cpy(resolved, PATH_MAX, absolute);
#endif
                free(absolute);
                return resolved;
        }
}

/**
 * Converts a string representation of a floating-point number to
 * its native representation. See strtold().
 *
 * @param nptr String representation of a floating-point number.
 * @return Double-precision number resulting from the string conversion.
 */
double atof(const char *nptr)
{
        return strtod(nptr, NULL);
}

/**
 * Converts a string representation of a floating-point number to
 * its native representation. See strtold().
 *
 * @param nptr String representation of a floating-point number.
 * @param endptr Pointer to the final part of the string which
 *     was not used for conversion.
 * @return Single-precision number resulting from the string conversion.
 */
float strtof(const char *restrict nptr, char **restrict endptr)
{
        return (float) strtold(nptr, endptr);
}

/**
 * Converts a string representation of a floating-point number to
 * its native representation. See strtold().
 *
 * @param nptr String representation of a floating-point number.
 * @param endptr Pointer to the final part of the string which
 *     was not used for conversion.
 * @return Double-precision number resulting from the string conversion.
 */
double strtod(const char *restrict nptr, char **restrict endptr)
{
        return (double) strtold(nptr, endptr);
}

/**
 * Creates and opens an unique temporary file from template.
 *
 * @param tmpl Template. Last six characters must be XXXXXX.
 * @return The opened file descriptor or -1 on error.
 */
int mkstemp(char *tmpl)
{
        int tmpl_len;
        int file;

        tmpl_len = strlen(tmpl);
        if (tmpl_len < 6) {
                errno = EINVAL;
                return -1;
        }

        char *tptr = tmpl + tmpl_len - 6;
        if (strcmp(tptr, "XXXXXX") != 0) {
                errno = EINVAL;
                return -1;
        }

        file = __tmpfile_templ(tmpl, true);
        if (file < 0) {
                errno = EIO; // XXX could be more specific
                return -1;
        }

        return file;
}

/**
 * Creates an unique temporary file name from template.
 *
 * @param tmpl Template. Last six characters must be XXXXXX.
 * @return The value of tmpl. The template is modified in place.
 *    If no temporary file name can be created, template is
 *    reduced to an empty string.
 */
char *mktemp(char *tmpl)
{
        int tmpl_len;
        int rc;

        tmpl_len = strlen(tmpl);
        if (tmpl_len < 6) {
                errno = EINVAL;
                *tmpl = '\0';
                return tmpl;
        }

        char *tptr = tmpl + tmpl_len - 6;
        if (strcmp(tptr, "XXXXXX") != 0) {
                errno = EINVAL;
                *tmpl = '\0';
                return tmpl;
        }

        rc = __tmpfile_templ(tmpl, false);
        if (rc != 0) {
                errno = EIO; // XXX could be more specific
                *tmpl = '\0';
                return tmpl;
        }

        return tmpl;
}

/**
 * Get system load average statistics.
 *
 * @param loadavg Array where the load averages shall be placed.
 * @param nelem Maximum number of elements to be placed into the array.
 * @return Number of elements placed into the array on success, -1 otherwise.
 */
int bsd_getloadavg(double loadavg[], int nelem)
{
        assert(nelem > 0);

        size_t count;
        load_t *loads = stats_get_load(&count);

        if (loads == NULL) {
                return -1;
        }

        if (((size_t) nelem) < count) {
                count = nelem;
        }

        for (size_t i = 0; i < count; ++i) {
                loadavg[i] = (double) loads[i];
        }

        free(loads);
        return count;
}

/** @}
 */

/* [<][>][^][v][top][bottom][index][help] */
HelenOS homepage, sources at GitHub