Using Apache Portable Run-Time 
by Ryan Bloom


Listing One
static void setup_shared_mem(pool *p)
{
#ifdef USE_OS2_SCOREBOARD
   ...
   m=(caddr_t) create_shared_heap("\\SHAREMEM\\SCOREBOARD",
#elif defined(USE_POSIX_SCOREBOARD)
   ...
   fd=shm_open(ap_scoreboard_fname, O_RDWR|O_CREAT|S_IRUSR|S_IWUSR);
   ...
#else
   ...
   fd=ap_popenf(p, 
   ap_scoreboard_fname, O_CREAT |O_BINARY|O_RDWR, 0644);
   ...
#endif
}
static void init_scoreboard(pool *p)
{
   if (ap_scoreboard_image == NULL) {
      setup_shared_mem(p);
   }
   ...
}
static void setup_shared_mem(pool *p)
{
   ...
#ifdef APR_HAS_SHMEM
   if (ap_shm_init(&scoreboard_shm, SCOREBOARD_SIZE, fname, p) 
       != APR_SUCCESS) {
      ...
   }
#else
      ...
      /* use a file for shared memory */
      ...
#endif
} 
static void init_scoreboard(pool *p)
{
   if (ap_scoreboard_image == NULL) {
   setup_shared_mem(p);
   }
   ...
}


Listing Two
ap_file_t *fd;
ap_status_t rv;
rv = ap_open_file(&fd, "testfile", APR_WRITE, APR_OS_DEFAULT, pool)
if (rv != APR_SUCCESS) {
   rv = ap_canonical_error(rv);
   switch (rv) {
      case APR_EISDIR:
         /* The file requested is a directory */
      case APR_ACCESS:
         /* The current user doesn't have write access to this file */
      case APR_EMFILE:
         /* The process already has the maximum number of files open */
   }
}


Listing Three
void duplicate_stderr(ap_file_t *error_log)
{
   int errfile;
   ap_get_os_file(&errfile, error_log);
   dup2(errfile, STDERR_FILENO);
}


Listing Four
int open_the_file(char *fname, int permissions, int access)
{
   int fd;
   fd = open(fname, access, permissions);
   if (fd > 0) {
      return fd;
   }
   return errno;
}


Listing Five
void *open_the_file(char *fname, int permissions, int access)
{
   HANDLE fd;
   int *errval;
   fd = CreateFile(fname, access, permissions, NULL, 
                                           createflags, permissions, 0);
   if (fd != INVALID_HANDLE_VALUE)
      return fd;
   }
   *errval = GetLastError();
   return errval;
}

  
Listing Six
ap_status_t open_the_file(char *fname, int permissions, int access, 
                                    ap_pool_t *cont, ap_file_t *newfile);
{
   ap_status_t rv;
   rv = ap_open(&newfile, fname, access, permissions, cont);
   return rv;
}

  
Listing Seven
int create_the_process(char &program_name, char *const args[], 
                    char **env, int pipein, int pipeout, int pipeerr) 
{ 
   int pid; 
   if (((*new)->pid = fork()) < 0) { 
      return errno; 
   } 
      /* Child process */ 
      dup2(pipein, STDIN_FILENO); 
      dup2(pipeout, STDOUT_FILENO); 
      dup2(pipeerr, STDERR_FILENO); 
      execve(progname, args, env); 
   } 
   /* We forked properly, but there is no way to know if execve worked. */ 
   ap_close(pipein); 
   ap_close(pipeout); 
   ap_close(pipeerr); 
   return 0; 
} 
 
Listing Eight
int create_the_process(char *program_name, char *const args[], 
               char **env, HANDLE pipein, HANDLE pipeout, HANDLE pipeerr) 
{ 
   HANDLE pid, hCurrentProcess; 
   STARTUPINFO si; 
   hCurrentProcess = GetCurrentProcess(); 
   si.cb = sizeof(si); 
   si.hStdInput = pipein; 
   si.hStdOutput = pipeout; 
   si.hStdError = pipeerr; 
  if (CreateProcess(NULL, program_name, NULL, NULL, 
                                        TRUE, 0, env, NULL, &si, &pid)) { 
      return 0; 
   } 
   return GetLastError(); 
}
  

Listing Nine
int create_the_process(char *program_name, char *const args[], 
                           char **env, ap_proc_t *proc, ap_pool_t *pool) 
{ 
   ap_proc_attr *attr = NULL; 
   ap_create_procattr(&attr, pool); 
   /* setup pipes to communicate with the child process. The second 
    * argument details how to setup the pipe for child's stdin, the second is for child's 
    * stdout, and the third is for the child's stderr. There are multiple 
    * options for these arguments: 
    *   APR_FULL_BLOCK: Both child and parent block on reads and writes. 
    *   APR_PARENT_BLOCK: Parent blocks and reads and writes, child does not. 
    *   APR_CHILD_BLOCK: Child blocks on reads and writes, parent does not. 
    *   APR_NO_PIPE: No pipe between child and parent for this input/output 
  ap_set_procattr_io(attr, APR_FULL_BLOCK, APR_CHILD_BLOCK, APR_NO_PIPE); 
   return ap_create_process(&proc, program_name, args, NULL, attr, pool); 
}



3


