Esempio n. 1
0
void image_pvr_f_encode(INT32 args)
{
  struct object *imgo;
  struct mapping *optm = NULL;
  struct image *alpha = NULL, *img;
  INT32 gbix=0, sz, attr=0;
  int has_gbix=0, twiddle=0, compress = 0;
  struct pike_string *res;
  unsigned char *dst;
  struct gla_state *gla_st = NULL;

  get_all_args("Image.PVR.encode", args, (args>1 && !UNSAFE_IS_ZERO(&sp[1-args])?
					  "%o%m":"%o"), &imgo, &optm);

  if((img=(struct image*)get_storage(imgo, image_program))==NULL)
    Pike_error("Image.PVR.encode: illegal argument 1\n");

  if(optm != NULL) {
    struct svalue *s;
    if((s = simple_mapping_string_lookup(optm, "alpha"))!=NULL && !UNSAFE_IS_ZERO(s))
      if(s->type != T_OBJECT ||
	 (alpha=(struct image*)get_storage(s->u.object, image_program))==NULL)
	Pike_error("Image.PVR.encode: option (arg 2) \"alpha\" has illegal type\n");
    if((s = simple_mapping_string_lookup(optm, "global_index"))!=NULL &&
       !IS_UNDEFINED(s)) {
      if(s->type == T_INT) {
	gbix = s->u.integer;
	has_gbix=1;
      }
      else
	Pike_error("Image.PVR.encode: option (arg 2) \"global_index\" has illegal type\n");
    }
    if((s = simple_mapping_string_lookup(optm, "vq"))!=NULL &&
       !UNSAFE_IS_ZERO(s))
      compress = 1;
  }

  if (!img->img)
    Pike_error("Image.PVR.encode: no image\n");
  if (alpha && !alpha->img)
    Pike_error("Image.PVR.encode: no alpha image\n");

  if (alpha && (alpha->xsize != img->xsize || alpha->ysize != img->ysize))
    Pike_error("Image.PVR.encode: alpha and image size differ\n");

  if(compress)
    sz=8+256*4*2+(img->xsize>>1)*(img->ysize>>1);
  else
Esempio n. 2
0
static void f_create_process( INT32 args ) {
  struct perishables storage;
  struct array *cmd = 0;
  struct mapping *optional = 0;
  struct svalue *tmp;
  int e;
  int stds[3];
  int *fds;
  int num_fds = 3;
  int wanted_gid=0, wanted_uid=0;
  int gid_request=0, uid_request=0;
  char *tmp_cwd = NULL;
  pid_t pid=-2;

  extern char **environ;

  fds = stds;
  storage.env = NULL;
  storage.argv = NULL;
  storage.disabled = 0;
  storage.fds = NULL;
  storage.limits = NULL;

  check_all_args("create_process",args, BIT_ARRAY, BIT_MAPPING | BIT_VOID, 0);

  switch(args)
  {
    default:
      optional=Pike_sp[1-args].u.mapping;
      mapping_fix_type_field(optional);

      if(m_ind_types(optional) & ~BIT_STRING)
        Pike_error("Bad index type in argument 2 to Caudium.create_process()\n");

    case 1: cmd=Pike_sp[-args].u.array;
      if(cmd->size < 1)
        Pike_error("Too few elements in argument array.\n");

      for(e=0; e<cmd->size; e++)
        if(ITEM(cmd)[e].type!=T_STRING)
          Pike_error("Argument is not a string.\n");

      array_fix_type_field(cmd);

      if(cmd->type_field & ~BIT_STRING)
        Pike_error("Bad argument 1 to Caudium.create_process().\n");
  }

  if (optional) {

     if ((tmp = simple_mapping_string_lookup(optional, "gid"))) {
        switch(tmp->type)
	{
	  case T_INT:
	    wanted_gid = tmp->u.integer;
	    gid_request = 1;
	    break;

	  default:
	    Pike_error("Invalid argument for gid.");
	    break;
	}
     } 

     if ((tmp = simple_mapping_string_lookup(optional, "uid"))) {
        switch(tmp->type)
	{
	  case T_INT:
	    wanted_uid = tmp->u.integer;
	    uid_request = 1;
	    break;

	  default:
	    Pike_error("Invalid argument for uid.");
	    break;
	}
     } 

     if((tmp = simple_mapping_string_lookup( optional, "cwd" )) &&
	 tmp->type == T_STRING && !tmp->u.string->size_shift)
       tmp_cwd = tmp->u.string->str;

     if((tmp = simple_mapping_string_lookup( optional, "stdin" )) &&
         tmp->type == T_OBJECT)
     {
        fds[0] = fd_from_object( tmp->u.object );
        if(fds[0] == -1)
          Pike_error("Invalid stdin file\n");
     }

     if((tmp = simple_mapping_string_lookup( optional, "stdout" )) &&
         tmp->type == T_OBJECT)
     {
        fds[1] = fd_from_object( tmp->u.object );
        if(fds[1] == -1)
          Pike_error("Invalid stdout file\n");
     }

     if((tmp = simple_mapping_string_lookup( optional, "stderr" )) &&
         tmp->type == T_OBJECT)
     {
        fds[2] = fd_from_object( tmp->u.object );
        if(fds[2] == -1)
          Pike_error("Invalid stderr file\n");
     }

     if((tmp=simple_mapping_string_lookup(optional, "rlimit"))) {
        struct svalue *tmp2;
        if(tmp->type != T_MAPPING)
          Pike_error("Wrong type of argument for the 'rusage' option. "
		     "Should be mapping.\n");
#define ADD_LIMIT(X,Y,Z) internal_add_limit(&storage,X,Y,Z);
#ifdef RLIMIT_NPROC
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "nproc")))
        ADD_LIMIT( "nproc", RLIMIT_NPROC, tmp2 );
#endif        
#ifdef RLIMIT_MEMLOCK
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "memlock")))
        ADD_LIMIT( "memlock", RLIMIT_MEMLOCK, tmp2 );
#endif        
#ifdef RLIMIT_RSS
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "rss")))
        ADD_LIMIT( "rss", RLIMIT_RSS, tmp2 );
#endif        
#ifdef RLIMIT_CORE
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "core")))
        ADD_LIMIT( "core", RLIMIT_CORE, tmp2 );
#endif        
#ifdef RLIMIT_CPU
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "cpu")))
        ADD_LIMIT( "cpu", RLIMIT_CPU, tmp2 );
#endif        
#ifdef RLIMIT_DATA
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "data")))
        ADD_LIMIT( "data", RLIMIT_DATA, tmp2 );
#endif        
#ifdef RLIMIT_FSIZE
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "fsize")))
        ADD_LIMIT( "fsize", RLIMIT_FSIZE, tmp2 );
#endif        
#ifdef RLIMIT_NOFILE
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "nofile")))
        ADD_LIMIT( "nofile", RLIMIT_NOFILE, tmp2 );
#endif        
#ifdef RLIMIT_STACK
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "stack")))
        ADD_LIMIT( "stack", RLIMIT_STACK, tmp2 );
#endif        
#ifdef RLIMIT_VMEM
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "map_mem"))
         ||(tmp2=simple_mapping_string_lookup(tmp->u.mapping, "vmem")))
        ADD_LIMIT( "map_mem", RLIMIT_VMEM, tmp2 );
#endif        
#ifdef RLIMIT_AS
      if((tmp2=simple_mapping_string_lookup(tmp->u.mapping, "as"))
         ||(tmp2=simple_mapping_string_lookup(tmp->u.mapping, "mem")))
        ADD_LIMIT( "mem", RLIMIT_AS, tmp2 );
#endif
#undef ADD_LIMIT
     }
  }

  if((tmp=simple_mapping_string_lookup(optional, "env"))) {
    if(tmp->type == T_MAPPING) {
      struct mapping *m=tmp->u.mapping;
      struct array *i,*v;
      int ptr=0;
      i=mapping_indices(m);
      v=mapping_values(m);

      storage.env=(char **)xalloc((1+m_sizeof(m)) * sizeof(char *));
      for(e=0;e<i->size;e++)
      {
        if(ITEM(i)[e].type == T_STRING &&
           ITEM(v)[e].type == T_STRING)
        {
          check_stack(3);
          ref_push_string(ITEM(i)[e].u.string);
          push_string(make_shared_string("="));
          ref_push_string(ITEM(v)[e].u.string);
          f_add(3);
          storage.env[ptr++]=Pike_sp[-1].u.string->str;
        }
      }
      storage.env[ptr++]=0;
      free_array(i);
      free_array(v);
    }
  }

  storage.argv = (char **)xalloc((1 + cmd->size) * sizeof(char *));
  for (e = 0; e < cmd->size; e++) storage.argv[e] = ITEM(cmd)[e].u.string->str;
  storage.argv[e] = 0;
  
  th_atfork_prepare();
  
  pid = fork();

  if (pid) {
     th_atfork_parent();
  } else {
     th_atfork_child();
  }

  if (pid == -1) {
     Pike_error("Caudium.create_process() failed.");
  } else if (pid) {
    
    pop_n_elems(args);
    push_int(pid);
    return;

  } else {

    if(storage.limits) {
      struct plimit *l = storage.limits;
      while(l) {
        int tmpres = setrlimit( l->resource, &l->rlp );
        l = l->next;
      }
    }

    if(storage.env) environ = storage.env;

    chdir(tmp_cwd);

    seteuid(0);
    setegid(0);

    setgroups(0, NULL);

    if (gid_request) setgid(wanted_gid);
    if (uid_request) setuid(wanted_uid);
    
    dup2(fds[0], 0);
    dup2(fds[1], 1);
    dup2(fds[2], 2);
	  
    set_close_on_exec(0,0);
    set_close_on_exec(1,0);
    set_close_on_exec(2,0);

    execvp(storage.argv[0],storage.argv);

    exit(99);
  }

  pop_n_elems(args);
  push_int(0);
}