2012-05-08 3 views
3

Вопрос довольно прост: как я могу захватить и перенаправить файл в файл stderr/stdout, созданный дочерней программой, запущенный в новом процессе, созданный с использованием Apache Portable Runtime apr_proc_create.Как записать вывод stdout/stderr из программы, запущенной в новом процессе, используя apr?

Конечной задачей является запуск внешней команды с некоторыми аргументами в отдельном процессе (желательно, но не обязательно) и перенаправление его вывода в файл.

До сих пор у меня есть следующий код (удаленные чеки для ясности):

apr_procattr_t *attr; 
apr_proc_t newproc; 

const char *progname; 
const char *args[100]; 

// progname and args are populated with data here 

apr_procattr_create(&attr, p); 
apr_procattr_io_set(attr, APR_CHILD_BLOCK, APR_CHILD_BLOCK, APR_CHILD_BLOCK); 
apr_procattr_cmdtype_set(attr, APR_PROGRAM_PATH); 
apr_proc_create(&newproc, progname, args, NULL, attr, p); 

Используя этот код, выход дочернего процесса подавляются (по крайней мере, я не вижу в консоли), но он не перенаправлен в файл. Использование APR_NO_PIPE вместо APR_CHILD_BLOCK приводит к удалению вывода ребенка в родительский stdout/stderr

У APR, похоже, очень мало рецептов поваренной книги, поэтому я не смог его обработать.

Любые советы или предложения? Решения, не поддерживающие APR, приветствуются, если они так же просты и понятны, как и код, который я опубликовал.

P.S. работает на Debian 6 (Linux 2.6.32-5-686), gcc 4.4.5, но я думаю, что это не имеет значения. :)

ответ

2

test cases for APR содержит много полезных примеров. В вашем случае, вы должны смотреть в testproc.c:

Уведомление об авторских правах: Этот код защищен APL 2.0

/* Licensed to the Apache Software Foundation (ASF) under one or more 
* contributor license agreements. See the NOTICE file distributed with 
* this work for additional information regarding copyright ownership. 
* The ASF licenses this file to You under the Apache License, Version 2.0 
* (the "License"); you may not use this file except in compliance with 
* the License. You may obtain a copy of the License at 
* 
*  http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 

static void test_file_redir(abts_case *tc, void *data) 
{ 
    apr_file_t *testout = NULL; 
    apr_file_t *testerr = NULL; 
    apr_off_t offset; 
    apr_status_t rv; 
    const char *args[2]; 
    apr_procattr_t *attr; 
    apr_file_t *testfile = NULL; 
    apr_size_t length; 
    char *buf; 

    testfile = NULL; 
    rv = apr_file_open(&testfile, "data/stdin", 
         APR_FOPEN_READ | APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_EXCL, 
         APR_OS_DEFAULT, p); 
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 
    rv = apr_file_open(&testout, "data/stdout", 
         APR_FOPEN_READ | APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_EXCL, 
         APR_OS_DEFAULT, p); 
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 
    rv = apr_file_open(&testerr, "data/stderr", 
         APR_FOPEN_READ | APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_EXCL, 
         APR_OS_DEFAULT, p); 
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 

    length = strlen(TESTSTR); 
    apr_file_write(testfile, TESTSTR, &length); 
    offset = 0; 
    rv = apr_file_seek(testfile, APR_SET, &offset); 
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 
    ABTS_ASSERT(tc, "File position mismatch, expected 0", offset == 0); 

    rv = apr_procattr_create(&attr, p); 
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 
    rv = apr_procattr_child_in_set(attr, testfile, NULL); 
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 
    rv = apr_procattr_child_out_set(attr, testout, NULL); 
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 
    rv = apr_procattr_child_err_set(attr, testerr, NULL); 
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 
    rv = apr_procattr_dir_set(attr, "data"); 
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 
    rv = apr_procattr_cmdtype_set(attr, APR_PROGRAM_ENV); 
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 

    args[0] = "proc_child"; 
    args[1] = NULL; 

    rv = apr_proc_create(&newproc, proc_child, args, NULL, 
         attr, p); 
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 

    rv = apr_proc_wait(&newproc, NULL, NULL, APR_WAIT); 
    ABTS_INT_EQUAL(tc, APR_CHILD_DONE, rv); 

    offset = 0; 
    rv = apr_file_seek(testout, APR_SET, &offset); 
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 

    length = 256; 
    buf = apr_pcalloc(p, length); 
    rv = apr_file_read(testout, buf, &length); 
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 
    ABTS_STR_EQUAL(tc, TESTSTR, buf); 


    apr_file_close(testfile); 
    apr_file_close(testout); 
    apr_file_close(testerr); 

    rv = apr_file_remove("data/stdin", p);; 
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 
    rv = apr_file_remove("data/stdout", p);; 
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 
    rv = apr_file_remove("data/stderr", p);; 
    ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 
} 
+0

Похоже, что это все, hovewer я не могу проверить это прямо сейчас. В любом случае, спасибо, я проверю это и обновит/приму, как только смогу. – J0HN

Смежные вопросы