#ifdef PROCESSTABLE_THREAD
#define __REENTRANT
#endif
#ifdef __cplusplus
extern
"C"
{
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#ifdef __cplusplus
}
#endif
#ifdef PROCESSTABLE_THREAD
#include <pthread.h>
#endif
#ifndef dTHX
#define dTHX dTHR
#endif
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdarg.h>
void
ppt_warn(
const
char
*, ...);
void
ppt_die(
const
char
*, ...);
void
store_ttydev(HV*, unsigned
long
);
void
bless_into_proc(
char
* ,
char
**, ...);
void
OS_get_table();
char
* OS_initialize();
char
** Fields = NULL;
int
Numfields;
HV* Ttydevs;
AV* Proclist;
void
ppt_warn(
const
char
*pat, ...) {
dTHX;
va_list
args;
va_start
(args, pat);
vwarn(pat, &args);
va_end
(args);
}
void
ppt_croak(
const
char
*pat, ...) {
dTHX;
va_list
args;
va_start
(args, pat);
vcroak(pat, &args);
va_end
(args);
}
void
store_ttydev( HV* myhash, unsigned
long
ttynum ){
SV** ttydev;
char
ttynumbuf[1024];
sprintf
(ttynumbuf,
"%lu"
, ttynum);
if
(
Ttydevs != NULL &&
(ttydev = hv_fetch(Ttydevs, ttynumbuf,
strlen
(ttynumbuf), 0)) != NULL
){
hv_store(myhash,
"ttydev"
,
strlen
(
"ttydev"
), newSVsv(*ttydev), 0);
}
else
{
hv_store(myhash,
"ttydev"
,
strlen
(
"ttydev"
), newSVpv(
""
,0), 0);
}
}
void
bless_into_proc(
char
* format,
char
** fields, ...){
va_list
args;
char
* key;
char
* s_val;
SV *SV_val;
int
i_val;
unsigned u_val;
long
l_val;
unsigned
long
p_val;
long
long
ll_val;
HV* myhash;
SV* ref;
HV* mystash;
SV* blessed;
if
(Fields == NULL){
Fields = fields;
Numfields =
strlen
(format);
}
myhash = newHV();
va_start
(args, fields);
while
( *format ){
key = *fields;
switch
(*format)
{
case
'A'
:
va_arg
(args,
char
*);
va_arg
(args,
int
);
hv_store(myhash, key,
strlen
(key), &PL_sv_undef, 0);
break
;
case
'a'
:
s_val =
va_arg
(args,
char
*);
i_val =
va_arg
(args,
int
);
{
int
len;
char
*s;
AV *av = newAV();
for
(s = s_val; s < (s_val + i_val); s += len + 1) {
len =
strlen
(s);
av_push (av, newSVpvn (s, len));
}
hv_store (myhash, key,
strlen
(key), newRV_noinc((SV *) av), 0);
}
break
;
case
'S'
:
va_arg
(args,
char
*);
hv_store(myhash, key,
strlen
(key), newSV(0), 0);
break
;
case
's'
:
s_val =
va_arg
(args,
char
*);
hv_store(myhash, key,
strlen
(key), newSVpv(s_val,
strlen
(s_val)), 0);
break
;
case
'I'
:
va_arg
(args,
int
);
hv_store(myhash, key,
strlen
(key), newSV(0), 0);
break
;
case
'i'
:
i_val =
va_arg
(args,
int
);
hv_store(myhash, key,
strlen
(key), newSViv(i_val), 0);
if
( !
strcmp
(key,
"ttynum"
) ) store_ttydev( myhash, i_val );
break
;
case
'U'
:
va_arg
(args, unsigned );
hv_store(myhash, key,
strlen
(key), newSV(0), 0);
break
;
case
'u'
:
u_val =
va_arg
(args, unsigned);
hv_store(myhash, key,
strlen
(key), newSVuv(u_val), 0);
break
;
case
'L'
:
va_arg
(args,
long
);
hv_store(myhash, key,
strlen
(key), newSV(0), 0);
break
;
case
'l'
:
l_val =
va_arg
(args,
long
);
hv_store(myhash, key,
strlen
(key), newSVnv(l_val), 0);
if
( !
strcmp
(key,
"ttynum"
) ) store_ttydev( myhash, l_val );
break
;
case
'P'
:
va_arg
(args, unsigned
long
);
hv_store(myhash, key,
strlen
(key), newSV(0), 0);
break
;
case
'p'
:
p_val =
va_arg
(args, unsigned
long
);
hv_store(myhash, key,
strlen
(key), newSVnv(p_val), 0);
break
;
case
'J'
:
va_arg
(args,
long
long
);
hv_store(myhash, key,
strlen
(key), newSV(0), 0);
break
;
case
'j'
:
ll_val =
va_arg
(args,
long
long
);
hv_store(myhash, key,
strlen
(key), newSVnv(ll_val), 0);
break
;
case
'V'
:
SV_val =
va_arg
(args, SV *);
hv_store(myhash, key,
strlen
(key), SV_val, 0);
break
;
default
:
croak(
"Unknown data format type `%c' returned from OS_get_table"
, *format);
va_end
(args);
}
format++;
fields++;
}
ref = newRV_noinc((SV*) myhash);
mystash = gv_stashpv(
"Proc::ProcessTable::Process"
, 1);
blessed = sv_bless(ref, mystash);
av_push(Proclist, blessed);
va_end
(args);
}
static
int
not_here(s)
char
*s;
{
croak(
"%s not implemented on this architecture"
, s);
return
-1;
}
static
double
constant(name, arg)
char
*name;
int
arg;
{
errno
= 0;
switch
(*name) {
}
errno
= EINVAL;
return
0;
not_there:
errno
= ENOENT;
return
0;
}
#ifdef PROCESSTABLE_THREAD
pthread_mutex_t _mutex_table;
pthread_mutex_t _mutex_new;
void
mutex_op(
int
lock, pthread_mutex_t *mutex)
{
if
(lock == 0) {
pthread_mutex_unlock(mutex);
}
else
{
pthread_mutex_lock(mutex);
}
}
#endif
void
mutex_new(
int
lock)
{
#ifdef PROCESSTABLE_THREAD
mutex_op(lock, &_mutex_new);
#endif
}
void
mutex_table(
int
lock)
{
#ifdef PROCESSTABLE_THREAD
mutex_op(lock, &_mutex_table);
#endif
}
MODULE = Proc::ProcessTable PACKAGE = Proc::ProcessTable
PROTOTYPES: DISABLE
BOOT:
#ifdef PROCESSTABLE_THREAD
pthread_mutex_init(&_mutex_table, NULL);
pthread_mutex_init(&_mutex_new, NULL);
#endif
void
mutex_new(lock)
int
lock
void
mutex_table(lock)
int
lock
double
constant(name,arg)
char
* name
int
arg
SV*
table(obj)
SV* obj
CODE:
if
(!obj || !SvOK (obj) || !SvROK (obj) || !sv_isobject (obj)) {
croak(
"Must call table from an initalized object created with new"
);
}
HV* hash;
SV** fetched;
mutex_table(1);
Ttydevs = perl_get_hv(
"Proc::ProcessTable::TTYDEVS"
, FALSE);
hash = (HV*) SvRV(obj);
if
( hv_exists(hash,
"Table"
, 5) ){
fetched = hv_fetch(hash,
"Table"
, 5, 0);
Proclist = (AV*) SvRV(*fetched);
av_clear(Proclist);
}
else
{
Proclist = newAV();
hv_store(hash,
"Table"
, 5, newRV_noinc((SV*)Proclist), 0);
}
OS_get_table();
RETVAL = newRV_inc((SV*) Proclist);
mutex_table(0);
OUTPUT:
RETVAL
void
fields(obj)
SV* obj
PPCODE:
if
(!obj || !SvOK (obj) || !SvROK (obj) || !sv_isobject (obj)) {
croak(
"Must call fields from an initalized object created with new"
);
}
int
i;
SV* my_sv;
if
( Fields == NULL ){
PUSHMARK(SP);
XPUSHs(obj);
PUTBACK;
perl_call_method(
"table"
, G_DISCARD);
}
EXTEND(SP,Numfields);
for
(i=0; i < Numfields; i++ ){
my_sv = newSVpv(Fields[i],0);
PUSHs(sv_2mortal(my_sv));
}
void
_initialize_os(obj)
SV* obj
CODE:
char
* error;
if
( (error = OS_initialize()) != NULL ){
croak(
"%s"
, error);
}