Пример #1
0
long
uproc_io_getline(char **lineptr, size_t *n, uproc_io_stream *stream)
{
#if defined(_GNU_SOURCE) || _POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
    if (stream->type == UPROC_IO_STDIO) {
        ssize_t res = getline(lineptr, n, stream->s.fp);
        if (res == -1) {
            if (ferror(stream->s.fp)) {
                uproc_error(UPROC_ERRNO);
            }
            else {
                uproc_error(UPROC_SUCCESS);
            }
        }
        return res;
    }
#endif

    char buf[4097];
    size_t len, total = 0;
    do {
        if (!uproc_io_gets(buf, sizeof buf, stream)) {
            if (!total) {
                uproc_error(UPROC_SUCCESS);
                return -1;
            }
            break;
        }
        len = strlen(buf);
        if (!*lineptr || *n < total + len + 1) {
            void *tmp = realloc(*lineptr, total + len + 1);
            if (!tmp) {
                uproc_error(UPROC_ENOMEM);
                return -1;
            }
            *lineptr = tmp;
            *n = total + len + 1;
        }
        memcpy(*lineptr + total, buf, len + 1);
        total += len;
    } while (buf[len - 1] != '\n');
    return total;
}
Пример #2
0
static uproc_io_stream *
io_open(const char *path, const char *mode, enum uproc_io_type type)
{
    uproc_io_stream *stream = malloc(sizeof *stream);
    if (!stream) {
        uproc_error(UPROC_ENOMEM);
        return NULL;
    }
    stream->type = type;
    stream->stdstream = false;
    switch (stream->type) {
        case UPROC_IO_GZIP:
#if HAVE_ZLIB_H
            if (!(stream->s.gz = gzopen(path, mode))) {
                /* gzopen sets errno to 0 if memory allocation failed */
                if (!errno) {
                    uproc_error(UPROC_ENOMEM);
                    goto error;
                }
                goto error_errno;
            }
            (void) gzbuffer(stream->s.gz, GZIP_BUFSZ);
            break;
#endif
        case UPROC_IO_STDIO:
            if (!(stream->s.fp = fopen(path, mode))) {
                goto error_errno;
            }
            break;
        default:
            goto error;
    }
    return stream;
error_errno:
    uproc_error_msg(UPROC_ERRNO, "can't open \"%s\" with mode \"%s\"",
                    path, mode);
error:
    free(stream);
    return NULL;
}
Пример #3
0
/* Reallocate the list data pointer to the given new capacity or at
 * least MIN_CAPACITY. Fails if memory can't be reallocated */
static int list_realloc(struct uproc_list_s *list, long n)
{
    unsigned char *tmp;
    if (n < MIN_CAPACITY) {
        n = MIN_CAPACITY;
    }
    tmp = realloc(list->data, n * list->value_size);
    if (!tmp) {
        return uproc_error(UPROC_ENOMEM);
    }
    list->data = tmp;
    list->capacity = n;
    return 0;
}
Пример #4
0
uproc_list *uproc_list_create(size_t value_size)
{
    struct uproc_list_s *list;
    if (!value_size) {
        uproc_error_msg(UPROC_EINVAL, "value size must be non-zero");
        return NULL;
    }

    list = malloc(sizeof *list);
    if (!list) {
        uproc_error(UPROC_ENOMEM);
        return NULL;
    }
    list->size = list->capacity = 0;
    list->value_size = value_size;
    list->data = NULL;

    if (list_realloc(list, 0)) {
        free(list);
        return NULL;
    }
    return list;
}