Solaris-Kvm

 view release on metacpan or  search on metacpan

Kvm.xs  view on Meta::CPAN

    switch (name[0 + 2]) {
    case 'B':
	if (!strnEQ(name + 0,"ST", 2))
	    break;
	return constant_STB(name, len, arg);
    case 'T':
	if (!strnEQ(name + 0,"ST", 2))
	    break;
	return constant_STT(name, len, arg);
    case 'V':
	if (!strnEQ(name + 0,"ST", 2))
	    break;
	return constant_STV(name, len, arg);
    }
    errno = EINVAL;
    return 0;

not_there:
    errno = ENOENT;
    return 0;
}

MODULE = Solaris::Kvm		PACKAGE = Solaris::Kvm		

double
constant(sv,arg)
PREINIT:
   STRLEN len;
INPUT:
   SV    *sv;
   char  *s = SvPV(sv, len);
   int    arg;
CODE:
   RETVAL = constant(s,len,arg);
OUTPUT:
   RETVAL

void
new(class,dev=NULL)
   char      *class;
   char      *dev;
PREINIT:
   SV        *ret;
   HV        *stash;
   HV        *hash;
   HV        *tie;
   SV        *dsv;
   SV        *tieref;
   Elf       *elf;
   Elf_Scn   *scn;
   GElf_Shdr  shdr;
   Elf_Data  *data;
   GElf_Sym   sym;
   kvm_dev_t *kd;
   kvm_var_t *kv;
   char      *p;
   char      *n;
   char      *t;
   char       errstr[1024];
   int        i, fd, ii, count;
PPCODE:
   hash   = newHV();
   ret    = (SV*)newRV_noinc((SV*)hash);

   stash  = gv_stashpv(class,TRUE);
   sv_bless(ret,stash);

   stash  = gv_stashpv(class,TRUE);
   sv_bless(ret,stash);

   Newz(0,kd,sizeof(kvm_dev_t),kvm_dev_t);
   kd->kvm_dev_name = strdup(dev ? dev : "/dev/ksyms");
   if ((kd->kvm_sd = kvm_open(0, 0, 0, O_RDONLY, errstr)) == 0)
      croak("kvm_open failed (%s)", strerror(errno));
   
   tie = newHV();
   tieref = newRV_noinc((SV*)tie);
   sv_bless(tieref, gv_stashpv("Solaris::Kvm::Stat", TRUE));
   hv_magic(hash, (GV*)tieref, 'P'); 

   dsv = newSViv((IV)kd);
   sv_magic(SvRV(tieref), dsv, '~', 0, 0);
   SvREFCNT_dec(dsv);

   elf_version(EV_CURRENT);

   fd = open(kd->kvm_dev_name, O_RDONLY);
   if((elf = elf_begin(fd, ELF_C_READ, NULL)) == 0)
      croak("elf_begin failed (%s)", strerror(errno));

   scn = NULL;
   while ((scn = elf_nextscn(elf, scn)) != NULL) {
      gelf_getshdr(scn, &shdr);
      if (shdr.sh_type == SHT_SYMTAB) break;
   }

   if (!scn) croak("no symbol table (%s)", strerror(errno));
   data  = elf_getdata(scn, NULL);
   count = shdr.sh_size / shdr.sh_entsize;

   for (ii=0; ii < count; ++ii) {
      gelf_getsym(data, ii, &sym);
      if (GELF_ST_TYPE(sym.st_info) != STT_OBJECT)
	 continue;
      n = strdup(elf_strptr(elf, shdr.sh_link, sym.st_name));
      Newz(0, kv, sizeof(kvm_var_t), kvm_var_t);
      kv->var_name  = n;
      kv->var_bind  = GELF_ST_BIND(sym.st_info);
      kv->var_type  = GELF_ST_TYPE(sym.st_info);
      kv->var_size  = sym.st_size;
      kv->var_visib = ELF64_ST_VISIBILITY(sym.st_other);
      kv->var_value = (IV)0;
      kv->var_blob  = kv->var_size <= sizeof(IV) ? 0 : 1;
      hv_store(tie, n, strlen(n), newSViv((IV)kv), 0);
   }
   elf_end(elf);
   close(fd);

   EXTEND(SP,1);
   PUSHs(sv_2mortal(ret));

void
rAUTOLOAD(self,prop,...)
   SV           *self;
   SV           *prop;
PREINIT:
   MAGIC        *mg;
   SV           *ref;
   STRLEN        plen;
   char         *pval;
   int           i;
PPCODE:
   mg = mg_find(SvRV(self), 'P');
   if(!mg) { croak("lost P magic"); }
   ref = mg->mg_obj;
   PUSHMARK(SP);
   XPUSHs(ref);
   for(i=2; i<items; i++)
      XPUSHs(ST(i));
   call_method(SvPV(prop,PL_na), G_SCALAR);

void
DESTROY(self)
   SV           *self;
CODE:

MODULE = Solaris::Kvm		PACKAGE = Solaris::Kvm::Stat

void
FETCH(self, key)
   SV           *self;
   SV           *key;
PREINIT:
   SV           *ret;
   HV           *hash;
   char         *k;
   STRLEN        klen;
   MAGIC        *mg;
   SV          **val;
   kvm_dev_t    *kp;
   kvm_var_t    *kv;
   struct nlist *nl;
   char         *t;
   int           i;
PPCODE:
   hash = (HV*)SvRV(self);
   k    = SvPV(key, klen);
   mg   = mg_find(SvRV(self),'~');
   if(!mg) { croak("lost ~ magic"); }
   kp   = (kvm_dev_t*)SvIVX(mg->mg_obj);

   val  = hv_fetch(hash, k, klen, FALSE);
   if (!val) 
      croak("kernel variable %s does not exist", k);
   kv   = (kvm_var_t*)SvIV(*val);
   Newz(0,nl,sizeof(struct nlist)*2,struct nlist);
   nl[0].n_name = k;
   if(kvm_nlist(kp->kvm_sd, nl) < 0) 
      croak("kvm_nlist failed (%s)", strerror(errno));

   if(kv->var_blob && !kv->var_value)
	 Newz(0, (char*)kv->var_value, kv->var_size, char);
   if(kvm_kread(kp->kvm_sd, nl[0].n_value, 
      kv->var_blob ? 
	 (char*)kv->var_value : (char*)&(kv->var_value)+(sizeof(IV)-kv->var_size), 
      kv->var_size) < 0)
      croak("kvm_kread failed (%s)", strerror(errno));

   ret = kv->var_blob ? 
      newSVpv((char*)(kv->var_value),kv->var_size) : 
      newSViv(kv->var_value);
   EXTEND(SP,1);
   PUSHs(sv_2mortal(ret));
   
SV*
STORE(self, key, value)
   SV         *self;
   SV         *key;
   SV         *value;
PREINIT:
   HV         *hash;
   char       *k;
   char       *v;
   STRLEN      klen;
   STRLEN      vlen;
   MAGIC      *mg;
   kvm_dev_t  *kp;
CODE:
   hash = (HV*)SvRV(self);
   k    = SvPV(key, klen);
   croak("STORE function is not implemented");
OUTPUT:
   RETVAL

void
DESTROY(self)
   SV        *self;
PREINIT:
   MAGIC     *mg;
   HV        *hash;
   HE        *hent;
   SV        *val;
   kvm_dev_t *kp;
   kvm_var_t *kv;
   char      *k;
   I32        klen;
CODE:
   mg = mg_find(SvRV(self),'~');
   if(!mg) { croak("lost ~ magic"); }
   kp = (kvm_dev_t*)SvIVX(mg->mg_obj);
   kvm_close(kp->kvm_sd);
   free(kp->kvm_dev_name);
   Safefree(kp);

   hash = (HV*)SvRV(self);
   hv_iterinit(hash);
   while(hent = hv_iternext(hash)) {
      k   = hv_iterkey(hent, &klen);
      val = hv_delete(hash, k, klen, 0);
      kv  = (kvm_var_t*)SvIV(val);
      if(kv->var_blob && kv->var_value)
	 Safefree(kv->var_value);
      free(kv->var_name);
      Safefree(kv);
      kv = (IV)0;
   }


bool
EXISTS(self, key)
   SV   *self;
   SV   *key;
PREINIT:
   HV   *hash;
   char *k;
CODE:
   hash = (HV*)SvRV(self);
   k    = SvPV(key, PL_na);
   RETVAL = hv_exists_ent(hash, key, 0);
OUTPUT:
   RETVAL

SV*
FIRSTKEY(self)
   SV *self;
PREINIT:
   HV *hash;
   HE *he;
PPCODE:
   hash = (HV*)SvRV(self);
   hv_iterinit(hash);
   if (he = hv_iternext(hash)) {
      EXTEND(sp, 1);
      PUSHs(hv_iterkeysv(he));
   }

SV*
NEXTKEY(self, lastkey)
   SV *self;
   SV *lastkey;
PREINIT:
   HV *hash;
   HE *he;
PPCODE:
   hash = (HV*)SvRV(self);
   if (he = hv_iternext(hash)) {
      EXTEND(sp, 1);
      PUSHs(hv_iterkeysv(he));
   }

SV*
DELETE(self, key)
   SV        *self;
   SV        *key;
PREINIT:
   HV *hash;
   HE *he;
CODE:
   hash = (HV*)SvRV(self);
   croak("DELETE functions is not implemented");
OUTPUT:
   RETVAL

void
CLEAR(self)
   SV *self;
PREINIT:
   HV *hash;
CODE:
   hash = (HV*)SvRV(self);
   croak("CLEAR function is not implemented");

void
_lookup(self,prop,...)
   SV     *self;
   SV     *prop;
ALIAS:
   Solaris::Kvm::Stat::size       = F_SIZE
   Solaris::Kvm::Stat::bind       = F_BIND
   Solaris::Kvm::Stat::type       = F_TYPE
   Solaris::Kvm::Stat::visibility = F_VISB
PREINIT:
   HV         *hash;
   SV        **var;
   SV         *ret;
   char       *pval;
   STRLEN      plen;
   kvm_var_t  *kv;
   int i;
PPCODE:
   hash = (HV*)SvRV(self);
   pval = SvPV(prop, plen);
   var  = hv_fetch(hash, pval, plen, FALSE);

   if(var) {
      kv = (kvm_var_t*)SvIV(*var);
      switch(ix) {
      case F_SIZE:
         ret = newSViv(kv->var_size);
	 break;
      case F_BIND:
         ret = newSViv(kv->var_bind);
	 break;
      case F_TYPE:
         ret = newSViv(kv->var_type);
	 break;
      case F_VISB:
         ret = newSViv(kv->var_visib);
	 break;
      }
   } else {
      ret = &PL_sv_undef;
   }
   EXTEND(SP,1);
   PUSHs(sv_2mortal(ret));



( run in 1.270 second using v1.01-cache-2.11-cpan-5511b514fd6 )