File: eperl_sys.c

package info (click to toggle)
eperl 2.2.16-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 608 kB
  • sloc: ansic: 1,692; perl: 252; makefile: 139; sh: 10
file content (128 lines) | stat: -rw-r--r-- 3,422 bytes parent folder | download | duplicates (2)
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/* SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-2.0-only
**  Copyright (c) 1996,1997,1998 Ralf S. Engelschall <rse@engelschall.com>
*/

#include "eperl.h"
#include <errno.h>
#include <fcntl.h>


void putenvf(const char *fmt, ...)
{
    char *cp;
    va_list ap;
    va_start(ap, fmt);
    vasprintf(&cp, fmt, ap);
    va_end(ap);
    putenv(cp);
}


/*
**  I/O handle redirection
*/
#define IO_REDIRECT_STD(outerr, num)          \
static int IO_redirected_std##outerr = -1;    \
void IO_redirect_std##outerr(int fd)          \
{                                             \
    IO_redirected_std##outerr = fcntl(num, F_DUPFD_CLOEXEC, 0); \
    dup2(fd, num);                            \
}                                             \
void IO_restore_std##outerr(void)             \
{                                             \
    if (IO_redirected_std##outerr != -1) {    \
        dup2(IO_redirected_std##outerr, num); \
        close(IO_redirected_std##outerr);     \
        IO_redirected_std##outerr = -1;       \
    }                                         \
}
IO_REDIRECT_STD(out, 1)
IO_REDIRECT_STD(err, 2)


/*
**  Temporary filename support
*/
static char *mytmpfiles[tmpfile_cnt];
struct tmpfile mytmpfile(enum tmpfile_id id)
{
    asprintf(&mytmpfiles[id], "%s/%cPerl.XXXXXXXXXX", getenv("TMPDIR") ?: "/tmp", 'e' + id);
    int fd = mkostemp(mytmpfiles[id], O_CLOEXEC);
    if (fd == -1)
        mytmpfiles[id] = NULL;
    return (struct tmpfile){mytmpfiles[id], fd};
}

void remove_mytmpfiles(void)
{
    for (size_t i = 0; i != tmpfile_cnt; ++i)
        if (mytmpfiles[i])
            unlink(mytmpfiles[i]);
}


bool ePerl_CopyFILE(FILE *from, FILE *to)
{
    char buf[64 * 1024];
    for (size_t rd = sizeof(buf); rd == sizeof(buf); ) {
        rd = fread(buf, 1, sizeof(buf), from);
        fwrite(buf, 1, rd, to);
    }
    return !ferror(from);
}

/*
**  read source file into internal buffer
*/
bool ePerl_ReadSourceFile(const char *filename, char **cpBufC, size_t *nBufC)
{
    bool rc = true;
    FILE *fp = fopen(filename, "r"), *out = NULL;
    if (fp == NULL) {
        ePerl_SetError("Cannot open source file %s for reading", filename);
        CU(false);
    }

    out = open_memstream(cpBufC, nBufC);
    if (!ePerl_CopyFILE(fp, out)) {
        ePerl_SetError("Cannot read from file %s", filename);
        CU(false);
    }

CUS:
    if (fp)
        fclose(fp);
    if (out)
        if (fclose(out)) {
            ePerl_SetError("Cannot allocate for %s: %s", filename, strerror(errno));
            rc = false;
        }
    return rc;
}

/*
**  read an error file to internal buffer and substitute the filename
*/
void ePerl_SubstErrorLog(char **cpBuf, size_t *nBuf, const char *replace, const char *with)
{
    size_t replace_len = strlen(replace);
    size_t with_len    = strlen(with);
    ++*nBuf;
    for (size_t cur = 0; ;) {
        char *path = memmem(*cpBuf + cur, *nBuf - cur, replace, replace_len);
        if (!path)
            break;
        cur = path - *cpBuf;

        char *newBuf = with_len > replace_len ? realloc(*cpBuf, *nBuf + with_len - replace_len) : *cpBuf;
        if (!newBuf)
            break;
        memmove(newBuf + cur + with_len, newBuf + cur + replace_len, *nBuf - cur - replace_len);
        *cpBuf = newBuf;
        *nBuf += with_len - replace_len;

        memcpy(*cpBuf + cur, with, with_len);
        cur += with_len;
    }
    --*nBuf;
}