summaryrefslogtreecommitdiff
path: root/lib/asprintf.c
blob: 248423104d487c1e4bba12e6629f49230c711afa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

#ifdef _WIN32
#include <windows.h>
#endif

int totem_private_asprintf(char **out, const char *fmt, ...)
{
    va_list ap;
    int ret_status = EOF;
    char dir_name[2001];
    char file_name[2000];
    FILE *fp = NULL;
    char *work = NULL;

    va_start(ap, fmt);

    /* Warning: tmpfile() does not work well on Windows (MinGW)
     *          if user does not have write access on the drive where 
     *          working dir is? */
#ifdef _WIN32
    /* file_name = G_tempfile(); */
    GetTempPath ( 2000, dir_name );
    GetTempFileName ( dir_name, "asprintf", 0, file_name );
    fp = fopen ( file_name, "w+" );
#else
    fp = tmpfile(); 
#endif /* _WIN32 */

    if ( fp ) {
        int count;

        count = vfprintf(fp, fmt, ap);
        if (count >= 0) {
            work = calloc(count + 1, sizeof(char));
            if (work != NULL) {
                rewind(fp);
                ret_status = fread(work, sizeof(char), count, fp);
                if (ret_status != count) {
                    ret_status = EOF;
                    free(work);
                    work = NULL;
                }
            }
        }
        fclose(fp);
#ifdef _WIN32
        unlink ( file_name );
#endif /* _WIN32 */
    }
    va_end(ap);
    *out = work;

    return ret_status;
}