static int compressLogFile(const char *name, const struct logInfo *log, const struct stat *sb)
{
    char *compressedName;
    const char **fullCommand;
    int inFile;
    int outFile;
    int i;
    int status;
    int compressPipe[2];
    char buff[4092];
    ssize_t n_read;
    int error_printed = 0;
    char *prevCtx;
    pid_t pid;

    message(MESS_DEBUG, "compressing log with: %s\n", log->compress_prog);
    if (debug)
        return 0;

    fullCommand = alloca(sizeof(*fullCommand) *
            ((unsigned)log->compress_options_count + 2));
    fullCommand[0] = log->compress_prog;
    for (i = 0; i < log->compress_options_count; i++)
        fullCommand[i + 1] = log->compress_options_list[i];
    fullCommand[log->compress_options_count + 1] = NULL;

    compressedName = alloca(strlen(name) + strlen(log->compress_ext) + 2);
    sprintf(compressedName, "%s%s", name, log->compress_ext);

    if ((inFile = open(name, O_RDWR | O_NOFOLLOW)) < 0) {
        message(MESS_ERROR, "unable to open %s for compression: %s\n", name, strerror(errno));
        return 1;
    }

    if (setSecCtx(inFile, name, &prevCtx) != 0) {
        /* error msg already printed */
        close(inFile);
        return 1;
    }

#ifdef WITH_ACL
    if ((prev_acl = acl_get_fd(inFile)) == NULL) {
        if (is_acl_well_supported(errno)) {
            message(MESS_ERROR, "getting file ACL %s: %s\n",
                    name, strerror(errno));
            restoreSecCtx(&prevCtx);
            close(inFile);
            return 1;
        }
    }
#endif

    outFile =
        createOutputFile(compressedName, O_RDWR | O_CREAT, sb, prev_acl, 0);
    restoreSecCtx(&prevCtx);
#ifdef WITH_ACL
    if (prev_acl) {
        acl_free(prev_acl);
        prev_acl = NULL;
    }
#endif
    if (outFile < 0) {
        close(inFile);
        return 1;
    }

    /* pipe used to capture stderr of the compress process */
    if (pipe(compressPipe) < 0) {
        message(MESS_ERROR, "error opening pipe for compress: %s\n",
                strerror(errno));
        close(inFile);
        close(outFile);
        return 1;
    }

    pid = fork();

    if (pid == -1) {
        message(MESS_ERROR, "cannot fork: %s\n", strerror(errno));
        close(inFile);
        close(outFile);
        close(compressPipe[1]);
        close(compressPipe[0]);
        return 1;
    }

    if (pid == 0) {
        char *envInFilename;

        /* close read end of pipe in the child process */
        close(compressPipe[0]);

        movefd(inFile, STDIN_FILENO);
        movefd(outFile, STDOUT_FILENO);

        if (switch_user_permanently(log) != 0) {
            exit(1);
        }

        movefd(compressPipe[1], STDERR_FILENO);

        envInFilename = alloca(strlen("LOGROTATE_COMPRESSED_FILENAME=") + strlen(name) + 2);
        sprintf(envInFilename, "LOGROTATE_COMPRESSED_FILENAME=%s", name);
        putenv(envInFilename);
        execvp(fullCommand[0], (void *) fullCommand);
        exit(1);
    }

    /* close write end of pipe in the parent process */
    close(compressPipe[1]);

    while ((n_read = read(compressPipe[0], buff, sizeof(buff) - 1)) > 0) {
        if (!error_printed) {
            error_printed = 1;
            message(MESS_ERROR, "Compressing program wrote following message "
                    "to stderr when compressing log %s:\n", name);
        }
        buff[n_read] = '\0';
        fprintf(stderr, "%s", buff);
    }
    close(compressPipe[0]);
    wait(&status);

    fsync(outFile);
    close(outFile);

    if (!WIFEXITED(status) || WEXITSTATUS(status)) {
        message(MESS_ERROR, "failed to compress log %s\n", name);
        close(inFile);
        unlink(compressedName);
        return 1;
    }

    setAtimeMtime(compressedName, sb);

    if (shred_file(inFile, name, log)) {
        close(inFile);
        return 1;
    }

    close(inFile);

    return 0;
}