I'm having a problem with apr_proc_create under solaris. Whenever I spawn a new thread, and then try to spawn a process from that thread, reading from the proc gives an end of file. I've attached a small test program that reproduces the problem. This program works fine under linux, but under solaris 8.0 it'll fail (eof in apr_file_gets before actually getting anything) I shipped this up real quick, so forgive me for any errors. I'm not really sure if it's my test here or the code dealing with file inheritance or what. Any ideas anyone? This is driving me crazy. Thanks,

--
jacob lewallen
[EMAIL PROTECTED]
/**
 * This program tries to create a process from a separate thread. Basically,
 * it's a combination of the testthread.c and testproc.c's. We create a new
 * thread, and then from that thread, try and do an apr_proc_create. What
 * happens is, when we try and read from the process's standard output we get
 * an EOF.
 *
 * We try the same thing from the main thread, and things work fine. I'm
 * unsure if it's a problem with my code here, or with the code that's
 * passing around the file descriptors. Notice that this works fine under
 * Linux (Gentoo) and under Solaris 8.0 things break.
 *
 * Compiled with:
 *
 * gcc -o proc_create_solaris proc_create_solaris.c `apr-config --includes 
--cflags --libs --link-ld`
 *
 * jacob lewallen <[EMAIL PROTECTED]>
 */
#include <apr.h>
#include <apr_thread_proc.h>
#include <apr_pools.h>
#include <stdlib.h>

/* Tests an apr_status_t for failures. */
#define TEST_RV(msg, status) \
 if (status != APR_SUCCESS) { \
   char temp[256]; \
   fprintf(stderr, "ERROR! %s: %s[%d] %s\n", msg, __FUNCTION__, __LINE__, \
           apr_strerror(status, temp, sizeof(temp))); \
   abort(); \
 }

static void *
APR_THREAD_FUNC thread_func(apr_thread_t *thread, void *data)
{
  apr_pool_t *pool;
  const char *args[3];
  apr_proc_t proc;
  apr_procattr_t *attr;
  apr_status_t rv;
  apr_size_t length;
  char *buf;

  if (data == NULL)
  {
    rv = apr_pool_create(&pool, NULL);
    TEST_RV("apr_pool_create", rv);
  }
  else
  {
    pool = (apr_pool_t *)data;
  }

  rv = apr_procattr_create(&attr, pool);
  TEST_RV("apr_procattr_create", rv);

  rv = apr_procattr_io_set(attr, APR_FULL_BLOCK, APR_FULL_BLOCK, 
                           APR_NO_PIPE);
  TEST_RV("apr_procattr_io_set", rv);

  rv = apr_procattr_cmdtype_set(attr, APR_PROGRAM);
  TEST_RV("apr_procattr_cmdtype_set", rv);

  args[0] = "cat";
  args[1] = "/etc/passwd";
  args[2] = NULL;
    
  rv = apr_proc_create(&proc, "/bin/cat", args, NULL, 
                       attr, pool);
  TEST_RV("apr_proc_create", rv);

  length = 256;
  buf = apr_pcalloc(pool, length);
  rv = apr_file_read(proc.out, buf, &length);
  TEST_RV("apr_file_read", rv); /* FAILS HERE FROM THREAD */

  if (rv == APR_SUCCESS)
  {
    printf("%s\n", buf);
  }

  if (data == NULL) apr_pool_destroy(pool);
  
  return (NULL);
}

apr_int32_t 
main(apr_int32_t argc, char **argv)
{
  apr_pool_t *pool;
  apr_thread_t *thread;
  apr_status_t rv;
 
  rv = apr_initialize();
  TEST_RV("apr_initialize", rv);

  rv = apr_pool_create(&pool, NULL);
  TEST_RV("apr_pool_create", rv);

  printf("trying from main thread.....\n");
  thread_func(NULL, pool);

  printf("trying from separate thread.....\n");
  rv = apr_thread_create(&thread, NULL, thread_func, NULL, pool);
  TEST_RV("apr_thread_create", rv);

  apr_thread_join(&rv, thread);
  TEST_RV("apr_thread_join", rv);

  apr_pool_destroy(pool);

  return (0);
}

Reply via email to