Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 11544f4 in mainline


Ignore:
Timestamp:
2011-07-29T17:46:54Z (10 years ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
lfn, master
Children:
2a53f71
Parents:
ffff746
Message:

Implement a few functions for dealing with temporary files.

Location:
uspace/lib/posix
Files:
4 edited

Legend:

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

    rffff746 r11544f4  
    4444#include "assert.h"
    4545#include "errno.h"
     46#include "stdlib.h"
    4647#include "string.h"
    4748#include "sys/types.h"
     49#include "unistd.h"
    4850
    4951#include "libc/io/printf_core.h"
     
    734736
    735737/**
    736  *
    737  * @param s
    738  * @return
     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.
    739742 */
    740743char *posix_tmpnam(char *s)
    741744{
    742         // TODO: low priority, just a compile-time dependency of binutils
    743         not_implemented();
     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 */
     770char *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 */
     833FILE *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+");
    744845}
    745846
  • uspace/lib/posix/stdio.h

    rffff746 r11544f4  
    123123#define L_tmpnam PATH_MAX
    124124extern char *posix_tmpnam(char *s);
     125extern char *posix_tempnam(const char *dir, const char *pfx);
     126extern FILE *posix_tmpfile(void);
    125127
    126128#ifndef LIBPOSIX_INTERNAL
     
    176178
    177179        #define tmpnam posix_tmpnam
     180        #define tempnam posix_tempnam
     181        #define tmpfile posix_tmpfile
    178182#endif
    179183
  • uspace/lib/posix/stdlib.c

    rffff746 r11544f4  
    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"
     
    385389
    386390/**
    387  *
    388  * @param tmpl
    389  * @return
     391 * Creates and opens an unique temporary file from template.
     392 *
     393 * @param tmpl Template. Last six characters must be XXXXXX.
     394 * @return The opened file descriptor or -1 on error.
     395 */
     396int posix_mkstemp(char *tmpl)
     397{
     398        int fd = -1;
     399       
     400        char *tptr = tmpl + posix_strlen(tmpl) - 6;
     401       
     402        while (fd < 0) {
     403                if (*posix_mktemp(tmpl) == '\0') {
     404                        /* Errno set by mktemp(). */
     405                        return -1;
     406                }
     407               
     408                fd = open(tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
     409               
     410                if (fd == -1) {
     411                        /* Restore template to it's original state. */
     412                        snprintf(tptr, 7, "XXXXXX");
     413                }
     414        }
     415       
     416        return fd;
     417}
     418
     419/**
     420 * Creates an unique temporary file name from template.
     421 *
     422 * @param tmpl Template. Last six characters must be XXXXXX.
     423 * @return The value of tmpl. The template is modified in place.
     424 *    If no temporary file name can be created, template is
     425 *    reduced to an empty string.
    390426 */
    391427char *posix_mktemp(char *tmpl)
    392428{
    393         // TODO: low priority, just a compile-time dependency of binutils
    394         not_implemented();
     429        int tmpl_len = posix_strlen(tmpl);
     430        if (tmpl_len < 6) {
     431                errno = EINVAL;
     432                *tmpl = '\0';
     433                return tmpl;
     434        }
     435       
     436        char *tptr = tmpl + tmpl_len - 6;
     437        if (posix_strcmp(tptr, "XXXXXX") != 0) {
     438                errno = EINVAL;
     439                *tmpl = '\0';
     440                return tmpl;
     441        }
     442       
     443        static int seq = 0;
     444       
     445        for (; seq < 1000000; ++seq) {
     446                snprintf(tptr, 7, "%06d", seq);
     447               
     448                int orig_errno = errno;
     449                errno = 0;
     450                /* Check if the file exists. */
     451                if (posix_access(tmpl, F_OK) == -1) {
     452                        if (errno == ENOENT) {
     453                                errno = orig_errno;
     454                                break;
     455                        } else {
     456                                /* errno set by access() */
     457                                *tmpl = '\0';
     458                                return tmpl;
     459                        }
     460                }
     461        }
     462       
     463        if (seq == 10000000) {
     464                errno = EEXIST;
     465                *tmpl = '\0';
     466                return tmpl;
     467        }
     468       
     469        return tmpl;
    395470}
    396471
  • uspace/lib/posix/stdlib.h

    rffff746 r11544f4  
    113113extern void posix_free(void *ptr);
    114114
     115/* Temporary files */
     116extern int posix_mkstemp(char *tmpl);
     117
    115118/* Legacy Declarations */
    116119extern char *posix_mktemp(char *tmpl);
     
    158161        #define free posix_free
    159162
     163        #define mkstemp posix_mkstemp
     164
    160165        #define mktemp posix_mktemp
    161166        #define getloadavg bsd_getloadavg
Note: See TracChangeset for help on using the changeset viewer.