apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Curt Arnold <carn...@apache.org>
Subject Newbie: running sed with stdout redirected to a file
Date Thu, 10 Mar 2005 05:34:11 GMT
A utility function used in the log4cxx unit tests  
(http://cvs.apache.org/viewcvs.cgi/logging-log4cxx/tests/src/util/ 
transformer.cpp?rev=1.15&view=markup) successfully does the equivalent  
of:

$> cp temp filtered
$> sed -f temp.sed -i filtered

Unfortunately, the sed distributed with Mac OS X does not support the  
-i option to change a file in place.  I have made a few stabs at  
modifying the code to do the equivalent of:

$> sed -f temp.sed temp > filtered


The following fragment my current failed attempt.  The filtered file is  
created, but is zero length and after several iterations, the  
apr_file_open(&child_out...) will fail.  I'm assuming it is trying to  
output to the same file as a previous iteration which is still locked.   
Could someone point out my glaring newbie mistakes.



         apr_pool_t* pool;
         apr_status_t stat = apr_pool_create(&pool, NULL);
         //
         //   if there are patterns, invoke sed to execute the  
replacements
         //
         //
         apr_procattr_t* attr = NULL;
         stat = apr_procattr_create(&attr, pool);
         assert(stat == APR_SUCCESS);

         stat = apr_procattr_io_set(attr, APR_NO_PIPE, APR_FULL_BLOCK,
                              APR_FULL_BLOCK);
         assert(stat == APR_SUCCESS);

         //
         //   find the program on the path
         //
         stat = apr_procattr_cmdtype_set(attr, APR_PROGRAM_PATH);
         assert(stat == APR_SUCCESS);

         //
         //   build the argument list
         //      using Q as regex separator on s command
         //
         const char** args = (const char**)
           apr_palloc(pool, 5 * sizeof(*args));
         int i = 0;

         //
         //   not well documented
         //     but the first arg is a duplicate of the executable name
         //
         args[i++] = "sed";

         //
         //   write the regex's to a temporary file since they
         //      may get mangled if passed as parameters
         //
         std::string regexName(in.getOSName());
         regexName.append(".sed");

         std::string regexArg("-f");
         regexArg.append(regexName);
         args[i++] = regexArg.c_str();

         //
         //    specify the input file
         args[i++] = out.getOSName().c_str();
         args[i] = NULL;


         apr_file_t* regexFile;
         stat = apr_file_open(&regexFile,
                regexName.c_str(),
                APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE,  
APR_OS_DEFAULT,
                pool);

         std::string tmp;
         for (log4cxx::Filter::PatternList::const_iterator iter =  
patterns.begin();
           iter != patterns.end();
           iter++) {
           tmp = "sQ";
           tmp.append(iter->first);
           tmp.append(1, 'Q');
           tmp.append(iter->second);
           tmp.append("Qg\n");
           apr_file_puts(tmp.c_str(), regexFile);
         }
         apr_file_close(regexFile);


         //
         //    set the output stream to the filtered file
         //
         apr_file_t* child_out;
         apr_int32_t flags = APR_FOPEN_READ | APR_FOPEN_WRITE |
             APR_FOPEN_CREATE | APR_FOPEN_TRUNCATE | APR_FOPEN_EXCL;
         stat = apr_file_open(&child_out, out.getOSName().c_str(),
           flags, APR_OS_DEFAULT, pool);
         assert(stat == APR_SUCCESS);

         stat =  apr_procattr_child_out_set(attr, child_out, NULL);
         assert(stat == APR_SUCCESS);

         //
         //   redirect the child's error stream to this processes' error  
stream
         //
         apr_file_t* child_err;
         stat = apr_file_open_stderr(&child_err, pool);
         assert(stat == 0);
         stat =  apr_procattr_child_err_set(attr, child_err, NULL);
         assert(stat == APR_SUCCESS);



         apr_proc_t pid;
         stat = apr_proc_create(&pid,"sed", args, NULL, attr, pool);
         assert(stat == APR_SUCCESS);

         apr_proc_wait(&pid, NULL, NULL, APR_WAIT);
         stat = apr_file_close(child_out);
         assert(stat == APR_SUCCESS);

         apr_pool_destroy(pool);


Mime
View raw message