ASTPtr ASTTableJoin::clone() const
{
	auto res = std::make_shared<ASTTableJoin>(*this);
	res->children.clear();

	CLONE(using_expression_list);
	CLONE(on_expression);

	return res;
}
Example #2
0
/* clone_graph:
 * Create two copies of the argument graph
 * One is a subgraph, the other is an actual copy since we will be
 * adding edges to it.
 */
static Agraph_t*
clone_graph(Agraph_t* ing, Agraph_t** xg)
{
	Agraph_t*  clone;
	Agraph_t*  xclone;
	Agnode_t*  n;
	Agnode_t*  xn;
	Agnode_t*  xh;
	Agedge_t*  e;
	Agedge_t*  xe;
	char       gname[SMALLBUF];
	static int id = 0;

	sprintf (gname, "_clone_%d", id++);
	clone = agsubg(ing, gname);
	sprintf (gname, "_clone_%d", id++);
	xclone = agopen(gname, ing->kind);

	for(n = agfstnode(ing); n; n = agnxtnode(ing, n)) {
		aginsert (clone, n);
		xn = agnode (xclone, n->name);
		CLONE(n) = xn;
	}

	for(n = agfstnode(ing); n; n = agnxtnode(ing, n)) {
		xn = CLONE(n);
		for(e = agfstout(ing, n); e; e = agnxtout(ing, e)) {
			aginsert (clone, e);
			xh = CLONE(e->head); 
			xe = agedge (xclone, xn, xh);
			ORIGE(xe) = e;
			DEGREE(xn) += 1;
			DEGREE(xh) += 1;
		}
	}
	*xg = xclone;
#ifdef OLD
	clone = agopen("clone", root->kind);

	for(n = agfstnode(root); n; n = agnxtnode(root, n)) {
		cn = agnode(clone, n->name);		
		ND_alg(cn) = DATA(n);
		BCDONE(cn) = 0;
	}

	for(n = agfstnode(root); n; n = agnxtnode(root, n)) {
		Agnode_t *t = agnode(clone, n);
		for(e = agfstout(root, n); e; e = agnxtout(root, e)) {
			Agnode_t *h = agnode(clone, e->head->name);
			agedge(clone, t, h);
		}
	}
#endif
	return clone;
}
ASTPtr ASTTablesInSelectQueryElement::clone() const
{
	auto res = std::make_shared<ASTTablesInSelectQueryElement>(*this);
	res->children.clear();

	CLONE(table_join);
	CLONE(table_expression);
	CLONE(array_join);

	return res;
}
Example #4
0
static struct Cookie *dup_cookie(struct Cookie *src)
{
  struct Cookie *d = calloc(sizeof(struct Cookie), 1);
  if(d) {
    CLONE(expirestr);
    CLONE(domain);
    CLONE(path);
    CLONE(spath);
    CLONE(name);
    CLONE(value);
    CLONE(maxage);
    CLONE(version);
    d->expires = src->expires;
    d->tailmatch = src->tailmatch;
    d->secure = src->secure;
    d->livecookie = src->livecookie;
    d->httponly = src->httponly;
    d->creationtime = src->creationtime;
  }
  return d;

  fail:
  freecookie(d);
  return NULL;
}
static int smt___index(lua_State *L ) { 
	lua_pushvalue(L, -1 ); lua_rawget(L, -3 ); 
	if(!lua_isnil(L, -1 ) ) return 1; lua_pop(L, 1 ); 
	LOCKR(); 
	lua_rawgeti(L_S_, LUA_REGISTRYINDEX, 
		(int )__SMT_CLONE_FUNC ); 
	CLONE(L, L_S_, -1 ); 
	lua_pushvalue(L_S_, -1 ); 
	lua_rawget(L_S_, -3 ); lua_remove(L_S_, -3 ); 
	if(lua_isnil(L_S_, -1 ) ) // 没有找到, 全局中查找 
		{ lua_pop(L_S_, 1 ); lua_rawget(L_S_, LUA_GLOBALSINDEX ); } 
	else lua_remove(L_S_, -2 ); 
	CLONE(L_S_, L, lua_gettop(L_S_ ) ); lua_pop(L_S_, 1 ); 
	UNLOCK(); 
	return 1; 
} 
ASTPtr ASTArrayJoin::clone() const
{
	auto res = std::make_shared<ASTArrayJoin>(*this);
	res->children.clear();

	CLONE(expression_list);

	return res;
}
static int smt___newindex(lua_State *L ) { 
	int i; 
	lua_pushvalue(L, -2 ); lua_rawget(L, -4 ); 
	if(!lua_isnil(L, -1 ) ) { lua_pop(L, 1 ); 
		lua_pushvalue(L, -1 ); lua_rawset(L, -4 ); 
		return 0; 
	} lua_pop(L, 1 ); 
	LOCKW(); 
	lua_rawseti(L_S_, LUA_REGISTRYINDEX, 
		(int )__SMT_CLONE_FUNC ); 
	for(i= -2; -1>= i; ++i ) CLONE(L, L_S_, i ); 
	lua_rawset(L_S_, -3 ); lua_pop(L_S_, 1 ); 
	UNLOCK(); 
	return 0; 
} 
PDistribution TConditionalProbabilityEstimator_FromDistribution::operator()(const TValue &condition) const
{ if (condition.varType == TValue::INTVAR)
    return probabilities->operator[](condition);

  else if (condition.varType == TValue::FLOATVAR) {
    if (condition.isSpecial())
      raiseError("undefined attribute value for condition");
    if (probabilities->varType != TValue::FLOATVAR)
      raiseError("invalid attribute value type for condition");

    const float &x = condition.floatV;
    const TDistributionMap *dm = probabilities->continuous;
    TDistributionMap::const_iterator rb = dm->upper_bound(x);
    if (rb==dm->end())
      rb = dm->begin();
    
    TDistribution *result = CLONE(TDistribution, (*rb).second);
    PDistribution wresult = result;

    if ((rb==dm->begin()) && ((*rb).first!=x)) {
      (*result) *= 0;
      return wresult;
    }

    const float &x2 = (*rb).first;
    rb--;
    const float &x1 = (*rb).first;
    const PDistribution &y1 = (*rb).second;

    if (x1 == x2) {
      *result += y1;
      *result *= 0.5;
      return wresult;
    }

    // The normal formula for this is in the function above
    *result -= y1;
    *result *= (x-x1)/(x2-x1);
    *result += y1;
    return wresult;
  }

  raiseError("invalid attribute value for condition");
  return PDistribution();
}
static int sth_run(lua_State *L ) { 
	TH_STATE *th= (TH_STATE * )0; 
	unsigned int i= ~0; 
	
	pthread_mutex_lock(&MUTEX_S_ ); for(;;) { 
		if(LUA_TFUNCTION!= lua_type(L, -1 ) ) break; //参数检测 
		for(i= 0; (TH_MAX> i )&& __th_state[i ]; ++i ); 
		if(TH_MAX== i ) break; //没有空间了 
		__th_state[i ]= (TH_STATE * )malloc(sizeof(*th ) ); 
		th= __th_state[i ]; memset(th, 0, sizeof(*th ) ); break; 
	} pthread_mutex_unlock(&MUTEX_S_ ); 
	if(th ) { th->L= lua_open(); luaL_openlibs(th->L ); 
		//lua_getglobal(L, "_G" ); lua_xmove(L, th->L, 1 ); 
		//lua_setglobal(th->L, "_G" ); 
		LOCKW(); CLONE(L, th->L, -1 ); UNLOCK(); 
		//创建线程, 传入参数 
		pthread_create(&(th->hTh ), NULL, 
			proxy_ThFunc, (void * )i ); 
		//lua 返回线程 ID 
		lua_pushinteger(L, i ); return 1; //返回线程 ID 
	} 
	return 0; 
} 
PDistribution TProbabilityEstimator_FromDistribution::operator()() const
{ return CLONE(TDistribution, probabilities);
}
PContingency TConditionalProbabilityEstimator_FromDistribution::operator()() const
{ return CLONE(TContingency, probabilities); }
PConditionalProbabilityEstimator TConditionalProbabilityEstimatorConstructor_loess::operator()(PContingency frequencies, PDistribution, PExampleGenerator, const long &, const int &) const
{ if (frequencies->varType != TValue::FLOATVAR)
    if (frequencies->outerVariable)
      raiseError("attribute '%s' is not continuous", frequencies->outerVariable->get_name().c_str());
    else
      raiseError("continuous attribute expected for condition");

    if (!frequencies->continuous->size())
      // This is ugly, but: if you change this, you should also change the code which catches it in
      // Bayesian learner
      raiseError("distribution (of attribute values, probably) is empty or has only a single value");

  PContingency cont = CLONE(TContingency, frequencies);
  const TDistributionMap &points = *frequencies->continuous;

/*  if (frequencies->continuous->size() == 1) {
    TDiscDistribution *f = (TDiscDistribution *)(points.begin()->second.getUnwrappedPtr());
    f->normalize();
    f->variances = mlnew TFloatList(f->size(), 0.0);
    return mlnew TConditionalProbabilityEstimator_FromDistribution(cont);
  }
*/
  cont->continuous->clear();

  vector<float> xpoints;
  distributePoints(points, nPoints, xpoints, distributionMethod);

  if (!xpoints.size())
    raiseError("no points for the curve (check 'nPoints')");
    
  if (frequencies->continuous->size() == 1) {
    TDiscDistribution *f = (TDiscDistribution *)(points.begin()->second.getUnwrappedPtr());
    f->normalize();
    f->variances = mlnew TFloatList(f->size(), 0.0);
    const_ITERATE(vector<float>, pi, xpoints)
      (*cont->continuous)[*pi] = f;
    return mlnew TConditionalProbabilityEstimator_FromDistribution(cont);
  }    

  TDistributionMap::const_iterator lowedge = points.begin();
  TDistributionMap::const_iterator highedge = points.end();

  bool needAll;
  map<float, PDistribution>::const_iterator from, to;

  vector<float>::const_iterator pi(xpoints.begin()), pe(xpoints.end());
  float refx = *pi;

  from = lowedge;
  to = highedge; 
  int totalNumOfPoints = frequencies->outerDistribution->abs;

  int needpoints = int(ceil(totalNumOfPoints * windowProportion));
  if (needpoints<3)
    needpoints = 3;


  TSimpleRandomGenerator rgen(frequencies->outerDistribution->cases);

  if ((needpoints<=0) || (needpoints>=totalNumOfPoints)) {  //points.size()
    needAll = true;
    from = lowedge;
    to = highedge;
  }
  else {
    needAll = false;

    /* Find the window */
    from = points.lower_bound(refx);
    to = points.upper_bound(refx);
    if (from==to)
      if (to != highedge)
        to++;
      else
        from --;

    /* Extend the interval; we set from to highedge when it would go beyond lowedge, to indicate that only to can be modified now */
    while (needpoints > 0) {
      if ((to == highedge) || ((from != highedge) && (refx - (*from).first < (*to).first - refx))) {
        if (from == lowedge)
          from = highedge;
        else {
          from--;
          needpoints -= (*from).second->cases;
        }
      }
      else {
        to++;
        if (to!=highedge)
          needpoints -= (*to).second->cases;
        else
          needpoints = 0;
      }

    }
    
    if (from == highedge)
      from = lowedge;
/*    else
      from++;*/
  }

  int numOfOverflowing = 0;
  // This follows http://www-2.cs.cmu.edu/afs/cs/project/jair/pub/volume4/cohn96a-html/node7.html
  for(;;) {
    TDistributionMap::const_iterator tt = to;
    --tt;
    
    if (tt == from) {
      TDistribution *Sy = CLONE(TDistribution, (*tt).second);
      PDistribution wSy = Sy;
      Sy->normalize();
      (*cont->continuous)[refx] = (wSy);
      ((TDiscDistribution *)(Sy)) ->variances = mlnew TFloatList(Sy->variable->noOfValues(), 0.0);
    }
    else {
  
      float h = (refx - (*from).first);
      if ((*tt).first - refx  >  h)
        h = ((*tt).first - refx);

      /* Iterate through the window */

      tt = from;
      const float &x = (*tt).first;
      const PDistribution &y = (*tt).second;
      float cases = y->abs;

      float w = fabs(refx - x) / h;
      w = 1 - w*w*w;
      w = w*w*w;

      const float num = y->abs; // number of instances with this x - value
      float n = w * num;
      float Sww = w * w * num;

      float Sx = w * x * num;
      float Swwx  = w * w * x * num;
      float Swwxx = w * w * x * x * num;
      TDistribution *Sy = CLONE(TDistribution, y);
      PDistribution wSy = Sy;
      *Sy *= w;

      float Sxx = w * x * x * num;
      TDistribution *Syy = CLONE(TDistribution, y);
      PDistribution wSyy = Syy;
      *Syy *= w;

      TDistribution *Sxy = CLONE(TDistribution, y);
      PDistribution wSxy = Sxy;
      *Sxy *= w * x;

      if (tt!=to)
        while (++tt != to) {
          const float &x = (*tt).first;
          const PDistribution &y = (*tt).second;
          cases += y->abs;

          w = fabs(refx - x) / h;
          w = 1 - w*w*w;
          w = w*w*w;

          const float num = y->abs;
          n   += w * num;
          Sww += w * w * num;
          Sx  += w * x * num;
          Swwx += w * w * x * num;
          Swwxx += w * w * x * x * num;
          Sxx += w * x * x * num;

          TDistribution *ty = CLONE(TDistribution, y);
          PDistribution wty = ty;
          *ty *= w;
          *Sy  += wty;
          *Syy += wty;
          *ty *= x;
          *Sxy += wty;

          //*ty *= PDistribution(y);
        }

      float sigma_x2 = n<1e-6 ? 0.0 : (Sxx - Sx * Sx / n)/n;
      if (sigma_x2<1e-10) {
        *Sy *= 0;
        Sy->cases = cases;
        (*cont->continuous)[refx] = (wSy);
      }

      TDistribution *sigma_y2 = CLONE(TDistribution, Sy);
      PDistribution wsigma_y2 = sigma_y2;
      *sigma_y2 *= wsigma_y2;
      *sigma_y2 *= -1/n;
      *sigma_y2 += wSyy;
      *sigma_y2 *= 1/n;

      TDistribution *sigma_xy = CLONE(TDistribution, Sy);
      PDistribution wsigma_xy = sigma_xy;
      *sigma_xy *= -Sx/n;
      *sigma_xy += wSxy; 
      *sigma_xy *= 1/n;

      // This will be sigma_xy / sigma_x2, but we'll multiply it by whatever we need
      TDistribution *sigma_tmp = CLONE(TDistribution, sigma_xy);
      PDistribution wsigma_tmp = sigma_tmp;
      //*sigma_tmp *= wsigma_tmp;
      if (sigma_x2 > 1e-10)
        *sigma_tmp *= 1/sigma_x2;

      const float difx = refx - Sx/n;

      // computation of y
      *sigma_tmp *= difx;
      *Sy *= 1/n;
      *Sy += *sigma_tmp;

      // probabilities that are higher than 0.9 normalize with a logistic function, which produces two positive 
      // effects: prevents overfitting and avoids probabilities that are higher than 1.0. But, on the other hand, this 
      // solution is rather unmathematical. Do the same for probabilities that are lower than 0.1.

      vector<float>::iterator syi(((TDiscDistribution *)(Sy))->distribution.begin()); 
      vector<float>::iterator sye(((TDiscDistribution *)(Sy))->distribution.end()); 
      for (; syi!=sye; syi++) {
        if (*syi > 0.9) {
          Sy->abs -= *syi;
          *syi = 1/(1+exp(-10*((*syi)-0.9)*log(9.0)-log(9.0)));
          Sy->abs += *syi;
        }
        if (*syi < 0.1) {
          Sy->abs -= *syi;
          *syi = 1/(1+exp(10*(0.1-(*syi))*log(9.0)+log(9.0)));
          Sy->abs += *syi;
        }
      }

      Sy->cases = cases;
      Sy->normalize();
      (*cont->continuous)[refx] = (wSy);
   
      // now for the variance
      // restore sigma_tmp and compute the conditional sigma
      if ((fabs(difx) > 1e-10) && (sigma_x2 > 1e-10)) {
        *sigma_tmp *= (1/difx);
        *sigma_tmp *= wsigma_xy;
        *sigma_tmp *= -1; 
        *sigma_tmp += wsigma_y2;
        // fct corresponds to part of (10) in the brackets (see URL above)
     //   float fct = Sww + difx*difx/sigma_x2/sigma_x2 * (Swwxx   - 2/n * Sx*Swwx   +  2/n/n * Sx*Sx*Sww);
        float fct = 1 + difx*difx/sigma_x2; //n + difx*difx/sigma_x2+n*n --- add this product to the overall fct sum if you are estimating error for a single user and not for the line.  
        *sigma_tmp *= fct/n; // fct/n/n;
      }
      ((TDiscDistribution *)(Sy)) ->variances = mlnew TFloatList(((TDiscDistribution *)(sigma_tmp))->distribution);
    }      

    // on to the next point
    pi++;
    if (pi==pe)
      break; 

    refx = *pi;

    // Adjust the window
    while (to!=highedge) {
      float dif = (refx - (*from).first) - ((*to).first - refx);
      if ((dif>0) || (dif==0) && rgen.randbool()) {
        if (numOfOverflowing > 0) {
          from++;
          numOfOverflowing -= (*from).second->cases;
        }
        else {
          to++;
          if (to!=highedge) 
            numOfOverflowing += (*to).second->cases;
        }
      }
	    else
		    break;
    }
  }

  return mlnew TConditionalProbabilityEstimator_FromDistribution(cont);
}
Example #13
0
File: sha.c Project: macssh/macssh
static struct hash_instance *
do_sha_copy(struct hash_instance *s)
{
  return &CLONE(sha_instance, s)->super;
}
PProbabilityEstimator TProbabilityEstimatorConstructor_m::operator()(PDistribution frequencies, PDistribution apriori, PExampleGenerator, const long &weightID, const int &) const
{ TProbabilityEstimator_FromDistribution *pefd = mlnew TProbabilityEstimator_FromDistribution(CLONE(TDistribution, frequencies));
  PProbabilityEstimator estimator = pefd;
  
  TDiscDistribution *ddist = pefd->probabilities.AS(TDiscDistribution);  
  if (ddist && (ddist->cases > 1e-20) && apriori) {
    TDiscDistribution *dapriori = apriori.AS(TDiscDistribution);
    if (!dapriori || (dapriori->abs < 1e-20))
      raiseError("invalid apriori distribution");
    
    float mabs = m/dapriori->abs;
    const float &abs = ddist->abs;
    const float &cases = ddist->cases;
    const float div = cases + m;
    if ((abs==cases) || !renormalize) {
      int i = 0;
      for(TDiscDistribution::iterator di(ddist->begin()), de(ddist->end()), ai(dapriori->begin());
          di != de;
          di++, ai++, i++)
         ddist->setint(i, (*di+*ai*mabs)/div);
    }
    else {
      int i = 0;
      for(TDiscDistribution::iterator di(ddist->begin()), de(ddist->end()), ai(dapriori->begin());
          di != de;
          di++, ai++, i++)
         ddist->setint(i, (*di / abs * cases + *ai*mabs)/div);
    }
  }
  else
    pefd->probabilities->normalize();
    
  return estimator;
}
PProbabilityEstimator TProbabilityEstimatorConstructor_Laplace::operator()(PDistribution frequencies, PDistribution, PExampleGenerator, const long &, const int &) const
{ TProbabilityEstimator_FromDistribution *pefd = mlnew TProbabilityEstimator_FromDistribution(CLONE(TDistribution, frequencies));
  PProbabilityEstimator estimator = pefd;
  
  TDiscDistribution *ddist = pefd->probabilities.AS(TDiscDistribution);
  if (ddist) {
    const float &abs = ddist->abs;
    const float &cases = ddist->cases;
    const float div = cases + l * ddist->noOfElements();
    int i = 0;
    if (div) {
      if ((cases == abs) || !renormalize || (abs<1e-20))
        PITERATE(TDiscDistribution, di, ddist)
          ddist->setint(i++, (*di + l) / div);
      else
        PITERATE(TDiscDistribution, di, ddist)
          ddist->setint(i++, (*di / abs * cases + l) / div);
    }
    else
      pefd->probabilities->normalize();
  }
  else
    pefd->probabilities->normalize();
  
  return estimator;
}
void vidTDeint::reset (void)
{

#define CLONE(x) x=_param->x
CLONE(mode);
CLONE(order);
CLONE(field);
CLONE(mthreshL);
CLONE(mthreshC);
CLONE(map);
CLONE(type);
CLONE(debug);
CLONE(mtnmode);
CLONE(sharp);
CLONE(full);
CLONE(cthresh);
CLONE(blockx);
CLONE(blocky);
CLONE(chroma);
CLONE(MI);
CLONE(tryWeave);
CLONE(link);
CLONE(denoise);
CLONE(AP);
CLONE(APType);

orderS=order;
fieldS=field;
mthreshLS=  mthreshL;
mthreshCS=mthreshC;


         xhalf = blockx >> 1;
        yhalf = blocky >> 1;
        xshift = blockx == 4 ? 2 : blockx == 8 ? 3 : blockx == 16 ? 4 : blockx == 32 ? 5 :
                blockx == 64 ? 6 : blockx == 128 ? 7 : blockx == 256 ? 8 : blockx == 512 ? 9 : 
                blockx == 1024 ? 10 : 11;
        yshift = blocky == 4 ? 2 : blocky == 8 ? 3 : blocky == 16 ? 4 : blocky == 32 ? 5 :
                blocky == 64 ? 6 : blocky == 128 ? 7 : blocky == 256 ? 8 : blocky == 512 ? 9 : 
                blocky == 1024 ? 10 : 11;
        if (((!full && mode == 0) || tryWeave) && mode >= 0)
        {
        int sz;
        
        sz=(((_info.width+xhalf)>>xshift)+1)*(((_info.height+yhalf)>>yshift)+1)*4;
                if(cArray) delete [] cArray;
                cArray = new int[sz];;
                
        }
PProbabilityEstimator TProbabilityEstimatorConstructor_relative::operator()(PDistribution frequencies, PDistribution, PExampleGenerator, const long &, const int &) const
{ TProbabilityEstimator_FromDistribution *pefd = mlnew TProbabilityEstimator_FromDistribution(CLONE(TDistribution, frequencies));
  PProbabilityEstimator estimator = pefd;
  pefd->probabilities->normalize();
  return estimator;
}
Example #18
0
/**
 * Fetch a subset of the values of a field.
 *
 * @param (GPB::Message*) external pointer
 * @param field name or tag number of the field
 * @param index
 */
RPB_FUNCTION_3(SEXP, METHOD(get_field_values), Rcpp::XPtr<GPB::Message> message, SEXP field,
               Rcpp::IntegerVector index) {
    GPB::FieldDescriptor* field_desc = getFieldDescriptor(message, field);
    if (!field_desc->is_repeated()) {
        Rcpp_error("fetch can only be used on repeated fields");
    }

    int n = index.size();
    switch (field_desc->type()) {
        case TYPE_INT32:
        case TYPE_SINT32:
        case TYPE_SFIXED32:
        case TYPE_INT64:
        case TYPE_SINT64:
        case TYPE_SFIXED64:
        case TYPE_UINT32:
        case TYPE_FIXED32:
        case TYPE_UINT64:
        case TYPE_FIXED64:
        case TYPE_ENUM: {
            Rcpp::IntegerVector res(n);
            for (int i = 0; i < n; i++) {
                res[i] = MESSAGE_GET_REPEATED_INT(message, field_desc, index[i]);
            }
            return res;
        }
        case TYPE_DOUBLE:
        case TYPE_FLOAT: {
            Rcpp::NumericVector res(n);
            for (int i = 0; i < n; i++) {
                res[i] = MESSAGE_GET_REPEATED_DOUBLE(message, field_desc, index[i]);
            }
            return res;
        }
        case TYPE_BOOL: {
            Rcpp::LogicalVector res(n);
            for (int i = 0; i < n; i++) {
                res[i] = MESSAGE_GET_REPEATED_DOUBLE(message, field_desc, index[i]);
            }
            return res;
        }
        case TYPE_STRING: {
            const GPB::Reflection* ref = message->GetReflection();
            Rcpp::CharacterVector res(n);
            for (int i = 0; i < n; i++) {
                res[i] = ref->GetRepeatedString(*message, field_desc, index[i]);
            }
            return res;
        }
        case TYPE_BYTES: {
            const GPB::Reflection* ref = message->GetReflection();
            Rcpp::List res(n);
            for (int i = 0; i < n; i++) {
                std::string s = ref->GetRepeatedString(*message, field_desc, index[i]);
                res[i] = std::vector<Rbyte>(s.begin(), s.end());
            }
            return res;
        }
        case TYPE_MESSAGE:
        case TYPE_GROUP: {
            const GPB::Reflection* ref = message->GetReflection();
            Rcpp::List res(n);
            for (int i = 0; i < n; i++) {
                res[i] = S4_Message(CLONE(&ref->GetRepeatedMessage(*message, field_desc, i)));
            }
            return res;
        }
        default:
            throw std::range_error("unknown type");
    }
    return R_NilValue;  // Unreachable.  For -Wall
}
Example #19
0
/* Spawn a new process executing PATH with the attributes describes in *ATTRP.
   Before running the process perform the actions described in FILE-ACTIONS. */
static int
__spawnix (pid_t * pid, const char *file,
	   const posix_spawn_file_actions_t * file_actions,
	   const posix_spawnattr_t * attrp, char *const argv[],
	   char *const envp[], int xflags,
	   int (*exec) (const char *, char *const *, char *const *))
{
  pid_t new_pid;
  struct posix_spawn_args args;
  int ec;

  if (__pipe2 (args.pipe, O_CLOEXEC))
    return errno;

  /* To avoid imposing hard limits on posix_spawn{p} the total number of
     arguments is first calculated to allocate a mmap to hold all possible
     values.  */
  ptrdiff_t argc = 0;
  /* Linux allows at most max (0x7FFFFFFF, 1/4 stack size) arguments
     to be used in a execve call.  We limit to INT_MAX minus one due the
     compatiblity code that may execute a shell script (maybe_script_execute)
     where it will construct another argument list with an additional
     argument.  */
  ptrdiff_t limit = INT_MAX - 1;
  while (argv[argc++] != NULL)
    if (argc == limit)
      {
	errno = E2BIG;
	return errno;
      }

  int prot = (PROT_READ | PROT_WRITE
	     | ((GL (dl_stack_flags) & PF_X) ? PROT_EXEC : 0));

  /* Add a slack area for child's stack.  */
  size_t argv_size = (argc * sizeof (void *)) + 512;
  size_t stack_size = ALIGN_UP (argv_size, GLRO(dl_pagesize));
  void *stack = __mmap (NULL, stack_size, prot,
			MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
  if (__glibc_unlikely (stack == MAP_FAILED))
    {
      close_not_cancel (args.pipe[0]);
      close_not_cancel (args.pipe[1]);
      return errno;
    }

  /* Disable asynchronous cancellation.  */
  int cs = LIBC_CANCEL_ASYNC ();

  args.file = file;
  args.exec = exec;
  args.fa = file_actions;
  args.attr = attrp ? attrp : &(const posix_spawnattr_t) { 0 };
  args.argv = argv;
  args.argc = argc;
  args.envp = envp;
  args.xflags = xflags;

  __sigprocmask (SIG_BLOCK, &SIGALL_SET, &args.oldmask);

  /* The clone flags used will create a new child that will run in the same
     memory space (CLONE_VM) and the execution of calling thread will be
     suspend until the child calls execve or _exit.  These condition as
     signal below either by pipe write (_exit with SPAWN_ERROR) or
     a successful execve.
     Also since the calling thread execution will be suspend, there is not
     need for CLONE_SETTLS.  Although parent and child share the same TLS
     namespace, there will be no concurrent access for TLS variables (errno
     for instance).  */
  new_pid = CLONE (__spawni_child, STACK (stack, stack_size), stack_size,
		   CLONE_VM | CLONE_VFORK | SIGCHLD, &args);

  close_not_cancel (args.pipe[1]);

  if (new_pid > 0)
    {
      if (__read (args.pipe[0], &ec, sizeof ec) != sizeof ec)
	ec = 0;
      else
	__waitpid (new_pid, NULL, 0);
    }
  else
    ec = -new_pid;

  __munmap (stack, stack_size);

  close_not_cancel (args.pipe[0]);

  if (!ec && new_pid)
    *pid = new_pid;

  __sigprocmask (SIG_SETMASK, &args.oldmask, 0);

  LIBC_CANCEL_RESET (cs);

  return ec;
}

/* Spawn a new process executing PATH with the attributes describes in *ATTRP.
   Before running the process perform the actions described in FILE-ACTIONS. */
int
__spawni (pid_t * pid, const char *file,
	  const posix_spawn_file_actions_t * acts,
	  const posix_spawnattr_t * attrp, char *const argv[],
	  char *const envp[], int xflags)
{
  return __spawnix (pid, file, acts, attrp, argv, envp, xflags,
		    xflags & SPAWN_XFLAGS_USE_PATH ? __execvpe : __execve);
}