bool RendererComponents::create_pixel_renderer_factory()
{
    const string name = m_params.get_optional<string>("pixel_renderer", "");

    if (name.empty())
    {
        return true;
    }
    else if (name == "uniform")
    {
        if (m_sample_renderer_factory.get() == 0)
        {
            RENDERER_LOG_ERROR("cannot use the uniform pixel renderer without a sample renderer.");
            return false;
        }

        ParamArray params = get_child_and_inherit_globals(m_params, "uniform_pixel_renderer");
        copy_param(params, m_params, "passes");
        m_pixel_renderer_factory.reset(
            new UniformPixelRendererFactory(
                m_sample_renderer_factory.get(),
                params));
        return true;
    }
    else if (name == "adaptive")
    {
        if (m_sample_renderer_factory.get() == 0)
        {
            RENDERER_LOG_ERROR("cannot use the adaptive pixel renderer without a sample renderer.");
            return false;
        }

        m_pixel_renderer_factory.reset(
            new AdaptivePixelRendererFactory(
                m_frame,
                m_sample_renderer_factory.get(),
                get_child_and_inherit_globals(m_params, "adaptive_pixel_renderer")));
        return true;
    }
    else
    {
        RENDERER_LOG_ERROR(
            "invalid value for \"pixel_renderer\" parameter: \"%s\".",
            name.c_str());
        return false;
    }
}
Beispiel #2
0
static struct lp_block *copy_block(struct lp_block *b)
{
  int c;
  struct lp_block *result = calloc(1, sizeof(*result));
  memcpy(result, b, sizeof(struct lp_block));
  result->params = calloc(b->params_len, sizeof(result->params[0]));

  if(b->name) {
    result->name = strdup(b->name);
  }

  for(c = 0; c < b->params_len; c++) {
    if(b->params[c]) {
      result->params[c] = copy_param(b->params[c]);
    }
  }

  return result;
}
Beispiel #3
0
//
//	コマンドラインパラメータ解析処理
//	in: pt .. コマンドラインパラメータ
//
void analyze_args(TCHAR *pt)
{
	TCHAR param[MAX_PATH];
	TCHAR name[MAX_PATH];
	TCHAR exe[MAX_PATH];
	TCHAR option[MAX_PATH];
	TCHAR description[MAX_PATH];
	int autof, desktop, retry, end;
	int no;
	struct {
		TCHAR *name;
		int *flag;
		TCHAR *dst;
	} list[] = {
		{ _T("install"), &install_flag, NULL },
		{ _T("uninstall"), &uninstall_flag, NULL },
		{ _T("ini"), &read_ini_flag, NULL },
		{ _T("name"), NULL, name },
		{ _T("exe"), NULL, exe },
		{ _T("option"), NULL, option },
		{ _T("description"), NULL, description },
		{ _T("desktop"), &desktop, NULL },
		{ _T("auto"), &autof, NULL },
		{ _T("start"), &start_flag, NULL },
		{ _T("no_error"), &no_error_flag, NULL },
		{ _T("ok"), &ok_flag, NULL },
		{ _T("question"), &question_flag, NULL },
		{ _T("retry"), &retry, NULL },
		{ _T("end"), &end, NULL },
		{ NULL, NULL, NULL }
	};

	name[0] = _T('\0');
	exe[0] = _T('\0');
	option[0] = _T('\0');
	description[0] = _T('\0');
	desktop = FALSE;
	autof = FALSE;
	retry = FALSE;
	end = END_SYS_AND_CLOSE;
	while(*pt != _T('\0')) {
		if(*pt== '/' || *pt == '-') {
			pt++;
			for(no = 0 ; list[no].name != NULL ; no++) {
				if(!_tcsnicmp(pt, list[no].name, _tcslen(list[no].name))) {
					pt += _tcslen(list[no].name);
					if(list[no].flag != NULL) {
						if(!_tcsnicmp(list[no].name, _T("end"), _tcslen(list[no].name))) {
							copy_param(param, pt, MAX_PATH);
							if(!_tcsicmp(param, _T("close"))) {
								*list[no].flag = END_CLOSE;
							} else if(!_tcsicmp(param, _T("syscommand"))) {
								*list[no].flag = END_SYSCOMMAND;
							} else if(!_tcsicmp(param, _T("sysandclose"))) {
								*list[no].flag = END_SYS_AND_CLOSE;
							} else if(!_tcsicmp(param, _T("ctrlbreak"))) {
								*list[no].flag = END_CTRL_BREAK;
// 2011/9/1 kimukou.buzz
							} else if(!_tcsicmp(param, _T("ctrlc"))) {
								*list[no].flag = END_CTRL_C;
// 2011/9/1 kimukou.buzz
							} else if(param[0] >= _T('0') && param[0] <= _T('3')) {
								*list[no].flag = param[0] - _T('0');
							}
						} else {
							*list[no].flag = TRUE;
						}
					}
					if(list[no].dst != NULL) {
						pt = copy_param(list[no].dst, pt, MAX_PATH);
					}
				}
			}
		} else {
			pt++;
		}
	}
	if(install_flag || uninstall_flag) {
		// インストールまたはアンインストールする場合
		if(read_ini_flag) {
			// ini ファイルから設定値を読む
			get_inifile();
		} else {
			// パラメータの値を使用する
#if _MSC_VER >= 1400
			_tcscpy_s(service_name, MAX_PATH, name);
			_tcscpy_s(exe_name, MAX_PATH, exe);
			_tcscpy_s(option_name, MAX_PATH, option);
			_tcscpy_s(description_name, MAX_PATH, description);
#else
			_tcscpy(service_name, name);
			_tcscpy(exe_name, exe);
			_tcscpy(option_name, option);
			_tcscpy(description_name, description);
#endif
			auto_flag = autof;
			desktop_flag = desktop;
			retry_flag = retry;
			end_pattern = end;
		}
	} else {
		// 通常起動の場合、ini ファイルから設定値を読む
		get_inifile();
	}
}
Beispiel #4
0
struct generic_section_config *
parse_param(char const *path,
            FILE *f,
            const struct config_section_info *params,
            int quiet_flag,
            int _ncond_var,
            cfg_cond_var_t *_cond_vars,
            int *p_cond_count)
{
  struct generic_section_config  *cfg = NULL;
  struct generic_section_config **psect = &cfg, *sect = NULL;
  const struct config_section_info *cur_info = NULL;

  char           sectname[32];
  char           varname[32];
  char           varvalue[1024];
  int            c, sindex;

  parsecfg_state.ncond_var = _ncond_var;
  parsecfg_state.cond_vars = _cond_vars;
  parsecfg_state.cond_stack = 0;
  parsecfg_state.output_enabled = 1;
  parsecfg_state.lineno = 1;
  if (p_cond_count) *p_cond_count = 0;

  /* found the global section description */
  for (sindex = 0; params[sindex].name; sindex++) {
    if (!strcmp(params[sindex].name, "global")) {
      cur_info = &params[sindex];
      break;
    }
  }
  /*
  if (!cur_info) {
    fprintf(stderr, "Cannot find description of section [global]\n");
    goto cleanup;
  }
  */

  if (!f && !(f = fopen(path, "r"))) {
    fprintf(stderr, "Cannot open configuration file %s\n", path);
    goto cleanup;
  }

  if (cur_info) {
    cfg = (struct generic_section_config*) xcalloc(1, cur_info->size);
    if (cur_info->init_func) cur_info->init_func(cfg);
    cfg->next = NULL;
    psect = &cfg->next;
  }

  while (1) {
    c = read_first_char(f);
    if (c == EOF || c == '[') break;
    if (c == '#' || c== '%' || c == ';') {
      read_comment(f);
      continue;
    }
    if (c == '@') {
      if (handle_conditional(f) < 0) goto cleanup;
      if (p_cond_count) (*p_cond_count)++;
      continue;
    }
    if (!parsecfg_state.output_enabled) {
      read_comment(f);
      continue;
    }
    if (read_variable(f, varname, sizeof(varname),
                      varvalue, sizeof(varvalue)) < 0) goto cleanup;
    if (!quiet_flag) {
      printf("%d: Value: %s = %s\n", parsecfg_state.lineno - 1, varname, varvalue);
    }
    if (!cur_info) {
      fprintf(stderr, "Cannot find description of section [global]\n");
      goto cleanup;
    }
    if (copy_param(cfg, cur_info, varname, varvalue) < 0) goto cleanup;
  }

  while (c != EOF) {
    if (read_section_name(f, sectname, sizeof(sectname)) < 0) goto cleanup;
    if (!quiet_flag) {
      printf("%d: New section %s\n", parsecfg_state.lineno - 1, sectname);
    }
    if (!strcmp(sectname, "global")) {
      fprintf(stderr, "Section global cannot be specified explicitly\n");
      goto cleanup;
    }
    for (sindex = 0; params[sindex].name; sindex++) {
      if (!strcmp(params[sindex].name, sectname)) {
        cur_info = &params[sindex];
        break;
      }
    }
    if (!cur_info) {
      fprintf(stderr, "Cannot find description of section [%s]\n", sectname);
      goto cleanup;
    }
    if (cur_info->pcounter) (*cur_info->pcounter)++;

    sect = (struct generic_section_config*) xcalloc(1, cur_info->size);
    strcpy(sect->name, sectname);
    if (cur_info->init_func) cur_info->init_func(sect);
    sect->next = NULL;
    *psect = sect;
    psect = &sect->next;

    while (1) {
      c = read_first_char(f);
      if (c == EOF || c == '[') break;
      if (c == '#' || c == '%' || c == ';') {
        read_comment(f);
        continue;
      }
      if (c == '@') {
        if (handle_conditional(f) < 0) goto cleanup;
        if (p_cond_count) (*p_cond_count)++;
        continue;
      }
      if (!parsecfg_state.output_enabled) {
        read_comment(f);
        continue;
      }
      if (read_variable(f, varname, sizeof(varname),
                        varvalue, sizeof(varvalue)) < 0) goto cleanup;
      if (!quiet_flag) {
        printf("%d: Value: %s = %s\n", parsecfg_state.lineno - 1, varname, varvalue);
      }
      if (copy_param(sect, cur_info, varname, varvalue) < 0) goto cleanup;
    }
  }

  if (parsecfg_state.cond_stack) {
    fprintf(stderr, "%d: unclosed conditional compilation\n", parsecfg_state.lineno);
    goto cleanup;
  }

  fflush(stdout);

  if (f) fclose(f);
  return cfg;

 cleanup:
  xfree(cfg);
  if (f) fclose(f);
  return NULL;
}
Beispiel #5
0
IRendererController::Status MasterRenderer::initialize_and_render_frame_sequence()
{
    assert(m_project.get_scene());
    assert(m_project.get_frame());

    // Reset the abort switch.
    if (m_abort_switch)
        m_abort_switch->clear();

#ifdef WITH_OSL

    // Create the error handler.
    OIIOErrorHandler error_handler;

    // While debugging, we want all possible outputs.
#ifndef NDEBUG
    error_handler.verbosity(OIIO::ErrorHandler::VERBOSE);
#endif

    const size_t texture_cache_size =
        m_params.get_optional<size_t>("texture_cache_size",  256 * 1024 * 1024);

    // If the texture cache size changes, we have to recreate the texture system.
    if (texture_cache_size != m_texture_cache_size)
    {
        m_texture_cache_size = texture_cache_size;
        m_texture_system.reset();
    }

    // Create the OIIO texture system, if needed.
    if (!m_texture_system)
    {
        m_texture_system.reset(
            OIIO::TextureSystem::create(false),
            bind(&OIIO::TextureSystem::destroy, _1));
    }

    // Set the texture system mem limit.
    m_texture_system->attribute("max_memory_MB", static_cast<float>(m_texture_cache_size / 1024));

    std::string search_paths;

    // Skip search paths for builtin projects.
    if (m_project.search_paths().has_root_path())
    {
        // Setup texture / shader search paths.
        // In OIIO / OSL, the path priorities are the opposite of appleseed,
        // so we copy the paths in reverse order.

        const filesystem::path root_path = m_project.search_paths().get_root_path();

        if (!m_project.search_paths().empty())
        {
            for (size_t i = 0, e = m_project.search_paths().size(); i != e; ++i)
            {
                filesystem::path p(m_project.search_paths()[e - 1 - i]);

                if (p.is_relative())
                   p = root_path / p;

                search_paths.append(p.string());
                search_paths.append(";");
            }
        }

        search_paths.append(root_path.string());
    }

    if (!search_paths.empty())
        m_texture_system->attribute("searchpath", search_paths);

    // TODO: set other texture system options here.

    // Create our renderer services.
    RendererServices services(m_project, *m_texture_system);

    // Create our OSL shading system.
    boost::shared_ptr<OSL::ShadingSystem> shading_system(
        OSL::ShadingSystem::create(
            &services,
            m_texture_system.get(),
            &error_handler),
            bind(&destroy_osl_shading_system, _1, m_texture_system.get()));

    if (!search_paths.empty())
        shading_system->attribute("searchpath:shader", search_paths);

    shading_system->attribute("lockgeom", 1);
    shading_system->attribute("colorspace", "Linear");
    shading_system->attribute("commonspace", "world");

    // This array needs to be kept in sync with the ShadingRay::Type enumeration.
    static const char* ray_type_labels[] =
    {
        "camera",
        "light",
        "shadow",
        "probe",
        "diffuse",
        "glossy",
        "specular"
    };

    shading_system->attribute(
        "raytypes",
        OSL::TypeDesc(
            OSL::TypeDesc::STRING,
            sizeof(ray_type_labels) / sizeof(ray_type_labels[0])),
        ray_type_labels);

#ifndef NDEBUG
    // While debugging, we want all possible outputs.
    shading_system->attribute("debug", 1);
    shading_system->attribute("statistics:level", 1);
    shading_system->attribute("compile_report", 1);
    shading_system->attribute("countlayerexecs", 1);
    shading_system->attribute("clearmemory", 1);
#endif

    register_closures(*shading_system);

#endif  // WITH_OSL

    // We start by binding entities inputs. This must be done before creating/updating the trace context.
    if (!bind_scene_entities_inputs())
        return IRendererController::AbortRendering;

    m_project.create_aov_images();
    m_project.update_trace_context();

    const Scene& scene = *m_project.get_scene();

    Frame& frame = *m_project.get_frame();
    frame.print_settings();

    const TraceContext& trace_context = m_project.get_trace_context();

    // Create the texture store.
    TextureStore texture_store(scene, m_params.child("texture_store"));

    // Create the light sampler.
    LightSampler light_sampler(scene, m_params.child("light_sampler"));

    // Create the shading engine.
    ShadingEngine shading_engine(m_params.child("shading_engine"));

    //
    // Create a lighting engine factory.
    //

    auto_ptr<IPassCallback> pass_callback;
    auto_ptr<ILightingEngineFactory> lighting_engine_factory;
    {
        const string value = m_params.get_required<string>("lighting_engine", "pt");

        if (value == "drt")
        {
            lighting_engine_factory.reset(
                new DRTLightingEngineFactory(
                    light_sampler,
                    m_params.child("drt")));    // todo: change to "drt_lighting_engine" -- or?
        }
        else if (value == "pt")
        {
            lighting_engine_factory.reset(
                new PTLightingEngineFactory(
                    light_sampler,
                    m_params.child("pt")));     // todo: change to "pt_lighting_engine" -- or?
        }
        else if (value == "sppm")
        {
            const SPPMParameters params(m_params.child("sppm"));

            SPPMPassCallback* sppm_pass_callback =
                new SPPMPassCallback(
                    scene,
                    light_sampler,
                    trace_context,
                    texture_store,
#ifdef WITH_OSL
                    *shading_system,
#endif
                    params);
            pass_callback.reset(sppm_pass_callback);

            lighting_engine_factory.reset(
                new SPPMLightingEngineFactory(
                    *sppm_pass_callback,
                    light_sampler,
                    params));
        }
        else
        {
            RENDERER_LOG_ERROR(
                "invalid value for \"lighting_engine\" parameter: \"%s\".",
                value.c_str());

            return IRendererController::AbortRendering;
        }
    }

    //
    // Create a sample renderer factory.
    //

    auto_ptr<ISampleRendererFactory> sample_renderer_factory;
    {
        const string value = m_params.get_required<string>("sample_renderer", "generic");

        if (value == "generic")
        {
            sample_renderer_factory.reset(
                new GenericSampleRendererFactory(
                    scene,
                    frame,
                    trace_context,
                    texture_store,
                    lighting_engine_factory.get(),
                    shading_engine,
#ifdef WITH_OSL
                    *shading_system,
#endif
                    m_params.child("generic_sample_renderer")));
        }
        else if (value == "blank")
        {
            sample_renderer_factory.reset(new BlankSampleRendererFactory());
        }
        else if (value == "debug")
        {
            sample_renderer_factory.reset(new DebugSampleRendererFactory());
        }
        else
        {
            RENDERER_LOG_ERROR(
                "invalid value for \"sample_renderer\" parameter: \"%s\".",
                value.c_str());

            return IRendererController::AbortRendering;
        }
    }

    //
    // Create a sample generator factory.
    //

    auto_ptr<ISampleGeneratorFactory> sample_generator_factory;
    {
        const string value = m_params.get_optional<string>("sample_generator", "");

        if (value == "generic")
        {
            sample_generator_factory.reset(
                new GenericSampleGeneratorFactory(
                    frame,
                    sample_renderer_factory.get()));
        }
        else if (value == "lighttracing")
        {
            sample_generator_factory.reset(
                new LightTracingSampleGeneratorFactory(
                    scene,
                    frame,
                    trace_context,
                    texture_store,
                    light_sampler,
#ifdef WITH_OSL
                    *shading_system,
#endif
                    m_params.child("lighttracing_sample_generator")));
        }
        else if (!value.empty())
        {
            RENDERER_LOG_ERROR(
                "invalid value for \"sample_generator\" parameter: \"%s\".",
                value.c_str());

            return IRendererController::AbortRendering;
        }
    }

    //
    // Create a pixel renderer factory.
    //

    auto_ptr<IPixelRendererFactory> pixel_renderer_factory;
    {
        const string value = m_params.get_optional<string>("pixel_renderer", "");

        if (value == "uniform")
        {
            pixel_renderer_factory.reset(
                new UniformPixelRendererFactory(
                    sample_renderer_factory.get(),
                    m_params.child("uniform_pixel_renderer")));
        }
        else if (value == "adaptive")
        {
            pixel_renderer_factory.reset(
                new AdaptivePixelRendererFactory(
                    frame,
                    sample_renderer_factory.get(),
                    m_params.child("adaptive_pixel_renderer")));
        }
        else if (!value.empty())
        {
            RENDERER_LOG_ERROR(
                "invalid value for \"pixel_renderer\" parameter: \"%s\".",
                value.c_str());

            return IRendererController::AbortRendering;
        }
    }

    //
    // Create a shading result framebuffer factory.
    //

    auto_ptr<IShadingResultFrameBufferFactory> shading_result_framebuffer_factory;
    {
        const string value =
            m_params.get_optional<string>("shading_result_framebuffer", "ephemeral");

        if (value == "ephemeral")
        {
            shading_result_framebuffer_factory.reset(
                new EphemeralShadingResultFrameBufferFactory());
        }
        else if (value == "permanent")
        {
            shading_result_framebuffer_factory.reset(
                new PermanentShadingResultFrameBufferFactory(frame));
        }
        else if (!value.empty())
        {
            RENDERER_LOG_ERROR(
                "invalid value for \"shading_result_framebuffer\" parameter: \"%s\".",
                value.c_str());

            return IRendererController::AbortRendering;
        }
    }

    //
    // Create a tile renderer factory.
    //

    auto_ptr<ITileRendererFactory> tile_renderer_factory;
    {
        const string value = m_params.get_optional<string>("tile_renderer", "");

        if (value == "generic")
        {
            tile_renderer_factory.reset(
                new GenericTileRendererFactory(
                    frame,
                    pixel_renderer_factory.get(),
                    shading_result_framebuffer_factory.get(),
                    m_params.child("generic_tile_renderer")));
        }
        else if (value == "blank")
        {
            tile_renderer_factory.reset(new BlankTileRendererFactory());
        }
        else if (value == "debug")
        {
            tile_renderer_factory.reset(new DebugTileRendererFactory());
        }
        else if (!value.empty())
        {
            RENDERER_LOG_ERROR(
                "invalid value for \"tile_renderer\" parameter: \"%s\".",
                value.c_str());

            return IRendererController::AbortRendering;
        }
    }

    //
    // Create a frame renderer.
    //

    auto_release_ptr<IFrameRenderer> frame_renderer;
    {
        const string value = m_params.get_required<string>("frame_renderer", "generic");

        if (value == "generic")
        {
            ParamArray params = m_params.child("generic_frame_renderer");
            copy_param(params, m_params, "rendering_threads");

            frame_renderer.reset(
                GenericFrameRendererFactory::create(
                    frame,
                    tile_renderer_factory.get(),
                    m_tile_callback_factory,
                    pass_callback.get(),
                    params));
        }
        else if (value == "progressive")
        {
            ParamArray params = m_params.child("progressive_frame_renderer");
            copy_param(params, m_params, "rendering_threads");

            frame_renderer.reset(
                ProgressiveFrameRendererFactory::create(
                    m_project,
                    sample_generator_factory.get(),
                    m_tile_callback_factory,
                    params));
        }
        else
        {
            RENDERER_LOG_ERROR(
                "invalid value for \"frame_renderer\" parameter: \"%s\".",
                value.c_str());

            return IRendererController::AbortRendering;
        }
    }

    // Execute the main rendering loop.
    const IRendererController::Status status =
        render_frame_sequence(
            frame_renderer.get()
#ifdef WITH_OSL
            , *shading_system
#endif
            );

    // Print texture store performance statistics.
    RENDERER_LOG_DEBUG("%s", texture_store.get_statistics().to_string().c_str());

    return status;
}
Beispiel #6
0
int spawnFilter(Connection *Conn,int iomode,int tofil[],int sock,iFUNCP func,PCStr(args))
{	CStr(ein,32);
	int ac;
	const char *av[256]; /**/
	CStr(epath,1024);
	CStr(logtype,64);
	CStr(logtype2,64);
	int fin; /* input at the filter side */
	int fout; /* output at the DeleGate side */
	int pid;
	int wcc;
	int wi;
	int fio[2]; /* a pipe to inherit Conn. */
	FILE *out;
	SpawnArgs spawnArgs;

	iLog("--- spawnFilter sock=%d func=%X args=%X",sock,xp2i(func),p2i(args));
	fin = tofil[0];
	fout = tofil[1];
	pipeX(fio,8*1024);
	out = fdopen(fio[1],"w");
	sprintf(ein,"%d/%d/%d/%d %d/%d",fio[0],fio[1],fin,fout,
		CHILD_SERNO,CHILD_SERNO_MULTI);
	/*
	sprintf(ein,"%d/%d/%d/%d",fio[0],fio[1],fin,fout);
	*/
	/*
	sprintf(ein,"%d/%d",fin,fout);
	*/

	sprintf(epath,"%s=%s",P_EXEC_PATH,EXEC_PATH);
	ac = 0;
	av[ac++] = /*DeleGate1*/ "DeleGate";
	av[ac++] = /*FuncFILTER*/ "(Filter)";
	av[ac++] = ein;
	av[ac++] = epath;

	/*
	sprintf(logtype,"-L0x%x",LOG_type);
	*/
	sprintf(logtype,"-L0x%x/%d",LOG_type,curLogFd());
	av[ac++] = logtype;
	if( LOG_type2 || LOG_bugs ){
		sprintf(logtype2,"-L20x%x/%x",LOG_type2,LOG_bugs);
		av[ac++] = logtype2;
	}
	ac += copy_param("f",elnumof(av)-ac,&av[ac],&main_argv[1]);
	av[ac] = NULL;

	Conn->fi_func = func;
	if( args == NULL )
		Conn->fi_arglen = 0;
	else	Conn->fi_arglen = strlen(args)+1;
	Conn->fi_iomode = iomode;
	Conn->fi_logfd  = curLogFd();

	if( file_isreg(sock) ){
		/* it might be TMPFILE() with CloseOnExec flag set */
		clearCloseOnExec(sock);
	}
	Conn->fi_topeer = sock;
	Conn->fi_dupclsock = 0;
	if( Conn->fi_issock = file_ISSOCK(sock) ){
		setclientsock(sock);
		if( sock == ClientSock
		 || SocketOf(sock) == SocketOf(ClientSock) )
			Conn->fi_dupclsock = 1;
			
	}

	/* might be emulating spawn() on Unix */
	sigsetmask(sigblock(0) & ~sigmask(SIGHUP) );

	pid = Spawnvp("openFilter",EXEC_PATH,av);
	Verbose("## spawnFilter: %d -> %d\n",getpid(),pid);
	if( pid <= 0 ){
		/* 9.6.3 don't freeze in fwrite() to the pipe ... */
		fclose(out);
		close(fio[0]);
		daemonlog("F","spawnFilter: FAILED %d\n",pid);
		porting_dbg("--FATAL: spawnFilter: FAILED spawn %d",pid);
		putpplog("--FATAL: spawnFilter: FAILED spawn %d\n",pid);
		return pid;
	}

/*
	wcc = write(fout,Conn,sizeof(Connection));
	if( Conn->cl_reqbuf )
		write(fout,Conn->cl_reqbuf,Conn->cl_reqbufsize);
	if( args != NULL )
		write(fout,args,strlen(args)+1);
*/
	close(fio[0]); /* close here to get EPIPE on write(fio[1]) */

	if( MountOptions ){
		spawnArgs.sa_mountserno = MountSerno(MountOptions);
		spawnArgs.sa_moptslen = strlen(MountOptions)+1;
	}else{
		spawnArgs.sa_mountserno = 0;
		spawnArgs.sa_moptslen = 0;
	}
	wcc = fwrite(&spawnArgs,1,sizeof(spawnArgs),out);
	wcc = fwrite(Conn,1,sizeof(Connection),out);
	if( Conn->cl_reqbuf )
		fwrite(Conn->cl_reqbuf,1,Conn->cl_reqbufsize,out);
	if( args != NULL )
		fwrite(args,1,strlen(args)+1,out);
	if( MountOptions && spawnArgs.sa_moptslen ){
		fwrite(MountOptions,1,spawnArgs.sa_moptslen,out);
		setMountOptions(FL_ARG,Conn,0);
	}
	fclose(out);

	/* If the iomode == READ then
	 * must wait till the client finish to read the written environment
	 * not to read it by myself.
	 * (in the case of FFROMCL, payload data may be ready, but cannot
	 *  identify whether or not it is env. data or payload data ...)
	 * If the iomode == WRITE and filter is direct system-command then
	 * must wait not to make buffered data be not passed to the filter.
	 */
	/*
	if( iomode == 0 || iomode != 0 && 0 < PollIn(fin,1) ){
		sv1log("## wait the filter finish reading enviroment\n");
		msleep(100);
	}
	*/

	return pid;
}