Exemplo n.º 1
0
/*
 * returns true if have a disk
 */
static
havedisk()
{
	int i, cnt;
	long  xfer[DK_NDRIVE];

	nlist("/vmunix", nl);
	if (nl[X_DKXFER].n_value == 0) {
		fprintf(stderr, "rstat: Variables missing from namelist\n");
		exit (1);
	}
	if ((kmem = open("/dev/kmem", 0)) < 0) {
		fprintf(stderr, "rstat: can't open kmem\n");
		exit(1);
	}
	if (lseek(kmem, (long)nl[X_DKXFER].n_value, 0) == -1) {
		fprintf(stderr, "rstat: can't seek in kmem\n");
		exit(1);
	}
	if (read(kmem, (char *)xfer, sizeof xfer)!= sizeof xfer) {
		fprintf(stderr, "rstat: can't read kmem\n");
		exit(1);
	}
	cnt = 0;
	for (i=0; i < DK_NDRIVE; i++)
		cnt += xfer[i];
	return (cnt != 0);
}
Exemplo n.º 2
0
/*
 * Write the parameters stored in sym_list into the in-memory copy of
 * the prototype biosboot (proto), ready for it to be written to disk.
 */
static void
pbr_set_symbols(char *fname, char *proto, struct sym_data *sym_list)
{
	struct sym_data *sym;
	struct nlist	*nl;
	char		*vp;
	u_int32_t	*lp;
	u_int16_t	*wp;
	u_int8_t	*bp;

	for (sym = sym_list; sym->sym_name != NULL; sym++) {
		if (!sym->sym_set)
			errx(1, "%s not set", sym->sym_name);

		/* Allocate space for 2; second is null-terminator for list. */
		nl = calloc(2, sizeof(struct nlist));
		if (nl == NULL)
			err(1, NULL);

		nl->n_un.n_name = sym->sym_name;

		if (nlist(fname, nl) != 0)
			errx(1, "%s: symbol %s not found",
			    fname, sym->sym_name);

		if (nl->n_type != (N_TEXT))
			errx(1, "%s: %s: wrong type (%x)",
			    fname, sym->sym_name, nl->n_type);

		/* Get a pointer to where the symbol's value needs to go. */
		vp = proto + nl->n_value;

		switch (sym->sym_size) {
		case 4:					/* u_int32_t */
			lp = (u_int32_t *) vp;
			*lp = sym->sym_value;
			break;
		case 2:					/* u_int16_t */
			if (sym->sym_value >= 0x10000)	/* out of range */
				errx(1, "%s: symbol out of range (%u)",
				    sym->sym_name, sym->sym_value);
			wp = (u_int16_t *) vp;
			*wp = (u_int16_t) sym->sym_value;
			break;
		case 1:					/* u_int16_t */
			if (sym->sym_value >= 0x100)	/* out of range */
				errx(1, "%s: symbol out of range (%u)",
				    sym->sym_name, sym->sym_value);
			bp = (u_int8_t *) vp;
			*bp = (u_int8_t) sym->sym_value;
			break;
		default:
			errx(1, "%s: bad symbol size %d",
			    sym->sym_name, sym->sym_size);
			/* NOTREACHED */
		}

		free(nl);
	}
}
Exemplo n.º 3
0
void InitLoadPoint()				/* SYSV386 version */
{
    int i;

    nlist( KERNEL_FILE, namelist);

    for (i=0; namelist[i].n_name; i++)
        if (namelist[i].n_value == 0)
            xload_error("cannot get name list from", KERNEL_FILE);

    if ((kmem = open(KMEM_FILE, O_RDONLY)) < 0)
        xload_error("cannot open", KMEM_FILE);

    if (lseek(kmem, namelist[0].n_value, 0) == -1)
        xload_error("cannot seek", VAR_NAME);

    if (read(kmem, &v, sizeof(v)) != sizeof(v))
        xload_error("cannot read", VAR_NAME);

    if ((p=(struct proc *)malloc(v.v_proc*sizeof(*p))) == NULL)
        xload_error("cannot allocat space for", PROC_NAME);

    first_buf = (XtPointer) namelist[2].n_value;
    last_buf  = (char *)first_buf + v.v_buf * sizeof(struct buf);
}
Exemplo n.º 4
0
MemoryUtils::MemoryUtils()
{
#ifdef PLATFORM_APPLE

	Gestalt(gestaltSystemVersionMajor, &m_OSXMajor);
	Gestalt(gestaltSystemVersionMinor, &m_OSXMinor);

	/* Get pointer to struct that describes all loaded mach-o images in process */
	if ((m_OSXMajor == 10 && m_OSXMinor >= 6) || m_OSXMajor > 10)
	{
		task_dyld_info_data_t dyld_info;
		mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
		task_info(mach_task_self(), TASK_DYLD_INFO, (task_info_t)&dyld_info, &count);
		m_ImageList = (struct dyld_all_image_infos *)dyld_info.all_image_info_addr;
	}
	else
	{
		struct nlist list[2];
		memset(list, 0, sizeof(list));
		list[0].n_un.n_name = (char *)"_dyld_all_image_infos";
		nlist("/usr/lib/dyld", list);
		m_ImageList = (struct dyld_all_image_infos *)list[0].n_value;
	}

#endif
}
Exemplo n.º 5
0
int
InitClockRate(void)
{
	if ((kmem = open("/dev/kmem", O_RDWR)) == -1) {
		msyslog(LOG_ERR, "open(/dev/kmem): %m");
		perror("adjtimed: open(/dev/kmem)");
		return (-1);
	}

	nlist("/hp-ux", nl);

	if (nl[0].n_type == 0) {
		fputs("adjtimed: /hp-ux has no symbol table\n", stderr);
		msyslog(LOG_ERR, "/hp-ux has no symbol table");
		return (-1);
	}
	/*
	 * Set the default to the system's original value
	 */
	default_rate = GetClockRate();
	if (default_rate == UNKNOWN_RATE) default_rate = DEFAULT_RATE;
	tick_rate = (MILLION / default_rate);
	slew_rate = TICK_ADJ * tick_rate;
	fprintf(stderr,"default_rate=%ld, tick_rate=%ld, slew_rate=%ld\n",default_rate,tick_rate,slew_rate);

	return (0);
} /* InitClockRate */
Exemplo n.º 6
0
int
machine_init(struct statics * statics)

{
	ulong		ptr;

	if ((kmem = open(KMEM, O_RDONLY)) == -1)
	{
		perror(KMEM);
		return -1;
	}
	if ((mem = open(MEM, O_RDONLY)) == -1)
	{
		perror(MEM);
		return -1;
	}

	/* get the list of symbols we want to access in the kernel */
	if (nlist(VMUNIX, nlst) == -1)
	{
		fprintf(stderr, "pg_top: nlist failed\n");
		return -1;
	}
	/* make sure they were all found */

	/*
	 * ZZ if (check_nlist(nlst) > 0) return -1;
	 */

	proca = nlst[X_PROC].n_value;

	/* get the symbol values out of kmem */
	(void) getkval(nlst[X_CUR_CPU].n_value, (int *) (&cur_cpu), sizeof(cur_cpu),
				   nlst[X_CUR_CPU].n_name);
	(void) getkval(nlst[X_HZ].n_value, (int *) (&Hz), sizeof(Hz),
				   nlst[X_HZ].n_name);
	(void) getkval(nlst[X_V].n_value, (int *) (&v), sizeof(v),
				   nlst[X_V].n_name);

	/* this is used in calculating WCPU -- calculate it ahead of time */
	logcpu = log(fabs(loaddouble(cur_cpu)));

	/* allocate space for proc structure array and array of pointers */
	bytes = v.v_proc * sizeof(struct proc);
	pbase = (struct proc *) malloc(bytes);
	pref = (struct proc **) malloc(v.v_proc * sizeof(struct proc *));
	if (pbase == (struct proc *) NULL || pref == (struct proc **) NULL)
	{
		fprintf(stderr, "pg_top: cannot allocate sufficient memory\n");
		return -1;
	}

	/* fill in the statics information */
	statics->procstate_names = procstatenames;
	statics->cpustate_names = cpustatenames;
	statics->memory_names = memorynames;
	statics->order_names = ordernames;	/* hops */

	return 0;
}
Exemplo n.º 7
0
/*
 *  Determine ppa number that specifies ifname
 */
static int
get_dlpi_ppa(register int fd, register const char *ifname, register int unit,
    register char *ebuf)
{
    register const char *cp;
    register int kd;
    void *addr;
    struct ifnet ifnet;
    char if_name[sizeof(ifnet.if_name)], tifname[32];

    cp = strrchr(ifname, '/');
    if (cp != NULL)
    {
        ifname = cp + 1;
    }
    if (nlist(path_vmunix, &nl) < 0)
    {
        sprintf(ebuf, "nlist %s failed", path_vmunix);
        return (-1);
    }

    if (nl[NL_IFNET].n_value == 0)
    {
        sprintf(ebuf, "could't find %s kernel symbol", nl[NL_IFNET].n_name);
        return (-1);
    }

    kd = open("/dev/kmem", O_RDONLY);
    if (kd < 0)
    {
        sprintf(ebuf, "kmem open: %s", strerror(errno));
        return (-1);
    }

    if (dlpi_kread(kd, nl[NL_IFNET].n_value, &addr, sizeof(addr), ebuf) < 0)
    {
        close(kd);
        return (-1);
    }
    for (; addr != NULL; addr = ifnet.if_next)
    {
        if (dlpi_kread(kd, (off_t)addr, &ifnet, sizeof(ifnet), ebuf) < 0 ||
            dlpi_kread(kd, (off_t)ifnet.if_name,
            if_name, sizeof(if_name), ebuf) < 0)
            {
                close(kd);
                return (-1);
            }
            sprintf(tifname, "%.*s%d",
                (int)sizeof(if_name), if_name, ifnet.if_unit);
            if (strcmp(tifname, ifname) == 0)
            {
                return (ifnet.if_index);
            }
    }

    sprintf(ebuf, "Can't find %s", ifname);
    return (-1);
}
Exemplo n.º 8
0
/*
 * Returns boottime in centiseconds(!).
 *      Caches this for future use.
 */
long
get_boottime(void)
{
    static long     boottime_csecs = 0;
#if defined(hpux10) || defined(hpux11)
    struct pst_static pst_buf;
#else
    struct timeval  boottime;
#ifdef	NETSNMP_CAN_USE_SYSCTL
    int             mib[2];
    size_t          len;
#elif defined(NETSNMP_CAN_USE_NLIST)
    int             kmem;
    static struct nlist nl[] = {
#if !defined(hpux)
        {(char *) "_boottime"},
#else
        {(char *) "boottime"},
#endif
        {(char *) ""}
    };
#endif                          /* NETSNMP_CAN_USE_SYSCTL */
#endif                          /* hpux10 || hpux 11 */


    if (boottime_csecs != 0)
        return (boottime_csecs);

#if defined(hpux10) || defined(hpux11)
    pstat_getstatic(&pst_buf, sizeof(struct pst_static), 1, 0);
    boottime_csecs = pst_buf.boot_time * 100;
#elif NETSNMP_CAN_USE_SYSCTL
    mib[0] = CTL_KERN;
    mib[1] = KERN_BOOTTIME;

    len = sizeof(boottime);

    sysctl(mib, 2, &boottime, &len, NULL, 0);
    boottime_csecs = (boottime.tv_sec * 100) + (boottime.tv_usec / 10000);
#elif defined(NETSNMP_CAN_USE_NLIST)
    if ((kmem = open("/dev/kmem", 0)) < 0)
        return 0;
    nlist(KERNEL_LOC, nl);
    if (nl[0].n_type == 0) {
        close(kmem);
        return 0;
    }

    lseek(kmem, (long) nl[0].n_value, L_SET);
    read(kmem, &boottime, sizeof(boottime));
    close(kmem);
    boottime_csecs = (boottime.tv_sec * 100) + (boottime.tv_usec / 10000);
#else
    return 0;
#endif                          /* hpux10 || hpux 11 */

    return (boottime_csecs);
}
Exemplo n.º 9
0
/* read the value of the u area from the hp-ux kernel */
void
_initialize_hp300ux_nat ()
{
#ifndef HPUX_VERSION_5
    nlist ("/hp-ux", nl);
    kernel_u_addr = nl[0].n_value;
#else /* HPUX version 5.  */
    kernel_u_addr = (CORE_ADDR) 0x0097900;
#endif
}
Exemplo n.º 10
0
Arquivo: hpux9.c Projeto: rra/lbcd
/*
 * Sets up for later queries.  Open the kernel memory file and find the
 * address of the necessary variable.  Exits on error.
 */
static int
kernel_open(void)
{
    kernel_fd = open(C_KMEM, O_RDONLY);
    if (kernel_fd < 0)
        sysdie("cannot open %s", C_KMEM);
    if (nlist(C_VMUNIX, nl) < 0)
        sysdie("no namelist for %s", C_VMUNIX);
    kernel_init = 1;
    return 0;
}
Exemplo n.º 11
0
/*
**  Get the current load average as an integer.
*/
int
GetLoadAverage()
{
    int		fd;
    int		oerrno;
#if	defined(FSCALE)
    long	avenrun[3];
#else
    double	avenrun[3];
#endif	/* defined(FSCALE) */

    fd = open("/dev/kmem", 0, 0);
    if (fd < 0)
	return -1;

#if	defined(HPUX)
    (void)nlist("/hp-ux", NameList);
#else
#if	defined(SUNOS5)
    (void)nlist("/dev/ksyms", NameList);
#else
    (void)nlist("/vmunix", NameList);
#endif	/* defined(SUNOS5) */
#endif	/* !defined(HPUX) */
    if (NameList[0].n_type == 0
     || lseek(fd, (off_t) NameList[X_AVENRUN].n_value, SEEK_SET) == -1
     || read(fd, (char *)avenrun, sizeof avenrun) != sizeof avenrun) {
	oerrno = errno;
	(void)close(fd);
	errno = oerrno;
	return -1;
    }

    (void)close(fd);

#if	defined(FSCALE)
    return (int)(avenrun[0] + FSCALE / 2) >> FSHIFT;
#else
    return (int)(avenrun[0] + 0.5);
#endif	/* defined(FSCALE) */
}
Exemplo n.º 12
0
bool image_info_initialize() {
  /* Looking up dyld_all_image_infos as per mach-o/dyld_images.h */
  struct nlist l[8] = { 0 };
  struct nlist *list = &l[0];
  list->n_un.n_name = "_dyld_all_image_infos";
  /* Hmm I'd prefer to pull this from memory if possible ... */
  nlist("/usr/lib/dyld", list);
  if (list->n_value) {
    all_image_infos = (struct dyld_all_image_infos *) list->n_value;
    return true;
  }
  return false;
}
Exemplo n.º 13
0
Arquivo: getproc.c Projeto: pkgw/iraf
/* GET_PROCESSTABLE -- Take a snapshot of the current kernel process table.
 */
struct proc *
get_processtable (
    int	kmem,			/* fd of kernel memory file */
    int	*o_nproc		/* number of processes in output table */
)
{
	char	*symbols = SYMBOLS;
	struct	proc *pt = NULL;
	struct	nlist nl[3];
	int	nproc, nb;
	long	proc;

	/* Check that the kernel symbol table file exists. */
	if (access (symbols, R_OK) < 0) {
	    fprintf (stderr, "Cannot open symbol file %s\n", symbols);
	    return (NULL);
	}

	/* Get addresses of symbols '_proc' and '_nproc'. */
	nl[0].n_name = "_proc";
	nl[1].n_name = "_nproc";
	nl[2].n_name = NULL;
	nlist (symbols, nl);
	if (nl[0].n_value == -1) {
	    fprintf (stderr, "Cannot read symbol file %s\n", symbols);
	    return (NULL);
	}

	/* Get values of these symbols from the kernel. */
	lseek (kmem, (long)nl[0].n_value, 0);
	if (read (kmem, &proc, sizeof(proc)) <= 0) {
kerr:	    fprintf (stderr, "Cannot read kernel memory\n");
	    return (NULL);
	}
	lseek (kmem, (long)nl[1].n_value, 0);
	if (read (kmem, &nproc, sizeof(nproc)) <= 0)
	    goto kerr;

	/* Read the kernel process table. */
	if (nproc > 0) {
	    nb = nproc * sizeof(struct proc);
	    pt = (struct proc *) malloc (nb);
	    lseek (kmem, proc, 0);
	    if (read (kmem, pt, nb) < nb)
		goto kerr;
	}

	*o_nproc = nproc;
	return (pt);
}
Exemplo n.º 14
0
char *
loadprotoblocks(char *fname, size_t *size)
{
	int	fd;
	u_long	marks[MARK_MAX], bp, offs;

	fd = -1;

	/* Locate block number array in proto file */
	if (nlist(fname, nl) != 0) {
		warnx("nlist: %s: symbols not found", fname);
		return NULL;
	}

	marks[MARK_START] = 0;
	if ((fd = loadfile(fname, marks, COUNT_TEXT|COUNT_DATA)) == -1)
		return NULL;
	(void)close(fd);

	*size = roundup(marks[MARK_END] - marks[MARK_START], DEV_BSIZE);
	bp = (u_long)malloc(*size);

	offs = marks[MARK_START];
	marks[MARK_START] = bp - offs;

	if ((fd = loadfile(fname, marks, LOAD_TEXT|LOAD_DATA)) == -1)
		return NULL;
	(void)close(fd);

	/* Calculate the symbols' locations within the proto file */
	block_size_p  =   (int *)(bp + (nl[X_BLOCK_SIZE ].n_value - offs));
	block_count_p =   (int *)(bp + (nl[X_BLOCK_COUNT].n_value - offs));
	/* XXX ondisk32 */
	block_table = (int32_t *)(bp + (nl[X_BLOCK_TABLE].n_value - offs));
	maxblocknum = *block_count_p;

	if (verbose) {
		printf("%s: entry point %#lx\n", fname, marks[MARK_ENTRY]);
		printf("proto bootblock size %d\n", *size);
		printf("room for %d filesystem blocks at %#lx\n",
			maxblocknum, nl[X_BLOCK_TABLE].n_value);
	}

	return (char *)bp;

	if (bp)
		free((void *)bp);
	return NULL;
}
Exemplo n.º 15
0
int getla()
{
    static int kmem = -1;
#if LA_TYPE == LA_INT
    long avenrun[3];
#else
#if LA_TYPE == LA_SHORT
    short avenrun[3];
#else
    double avenrun[3];
#endif
#endif
    extern int errno;
    extern off_t lseek();

    if (kmem < 0) {
#ifdef _AUX_SOURCE
	strcpy(Nl[X_AVENRUN].n_name, LA_AVENRUN);
	Nl[1].n_name[0] = '\0';
#endif

#if defined(_AIX3) || defined(_AIX4)
	if (knlist(Nl, 1, sizeof Nl[0]) < 0)
#else
	if (nlist(_PATH_UNIX, Nl) < 0)
#endif
	    return (-1);
	if (Nl[X_AVENRUN].n_value == 0)
	    return (-1);
#ifdef NAMELISTMASK
	Nl[X_AVENRUN].n_value &= NAMELISTMASK;
#endif

	kmem = open(_PATH_KMEM, 0, 0);
	if (kmem < 0)
	    return (-1);
	(void) fcntl(kmem, F_SETFD, 1);
    }
    if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, SEEK_SET) == -1 ||
	read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
	/* thank you Ian */
	return (-1);
#if (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT)
    return ((int) (avenrun[0] + FSCALE / 2) >> FSHIFT);
#else /* LA_TYPE == LA_FLOAT */
    return ((int) (avenrun[0] + 0.5));
#endif
}
Exemplo n.º 16
0
Arquivo: mib.c Projeto: Kampbell/ISODE
init_mib () {
	register struct nlist *nz;

	if (nlist (VMUNIX, nl) == NOTOK)
		adios (VMUNIX, "unable to nlist");
	for (nz = nl; nz -> n_name; nz++)
		if (nz -> n_value == 0)
			advise (LLOG_EXCEPTIONS, NULLCP, "\"%s\" not in %s (warning)",
					nz -> n_name, VMUNIX);

	if ((kd = open ("/dev/kmem", O_RDONLY)) == NOTOK)
		adios ("/dev/kmem", "unable to read");
	wd = NOTOK;

	if ((nullSpecific = text2oid ("0.0")) == NULLOID)
		adios (NULLCP, "text2oid (\"0.0\") failed!");
}
Exemplo n.º 17
0
int
get_slave_controlling(dev_t device)
{
    struct nlist nl[2];
    struct tty dummy;
    short procid;
    static int fd = -1;
    static off_t offset = 0;

    if (offset == 0) {
	if ((fd = open(MEM_NAME, O_RDONLY)) == -1) {
	    sysmessage(MSG_WARNING, "Can't open %s : %s\n",
		       MEM_NAME, strerror(errno));
	    return (0);
	}

	nl[0].n_name = PTY_TABLE;
	nl[1].n_name = (char *) NULL;
	if (nlist(KERNEL_NAME, &nl[0]) == -1) {
	    sysmessage(MSG_WARNING, "Can't nlist %s : %s\n",
		       MEM_NAME, strerror(errno));
	    return (0);
	}
	offset = nl[0].n_value;
	if (offset != 0) {
	    offset += (off_t) (minor(device) * sizeof(dummy)) +
		(off_t) & dummy.t_pgrp - (off_t) & dummy;
	}
	else {
	    sysmessage(MSG_WARNING,
		       "Kernel symbol not found : %s\n", PTY_TABLE);
	    return (0);
	}
    }
    if (lseek(fd, offset, 0) == -1) {
	printf("%s %s: mem seek error\n");
	return (0);
    }

    if (read(fd, (char *) &procid, sizeof(short)) <= 0) {
	sysmessage(MSG_WARNING, "Can't open %s : %s\n",
		   MEM_NAME, strerror(errno));
	return (0);
    }
    return ((int) procid);
}
Exemplo n.º 18
0
lispval
Lgetaddress(){
	register struct argent *mlbot = lbot;
	register lispval work;
	register int numberofargs, i;
	char ostabf[128];
	struct nlist NTABLE[100];
	lispval dispget();

	Savestack(4);

	if(np-lbot == 2) protect(nil);	/* allow 2 args */
	numberofargs = (np - lbot)/3;
	if(numberofargs * 3 != np-lbot)
	   error("getaddress: arguments must come in triples ",FALSE);

	for ( i=0; i<numberofargs; i++,mlbot += 3) {
		NTABLE[i].n_value = 0;
	        mlbot[0].val = verify(mlbot[0].val,"Incorrect entry specification for binding");
		STASSGN(i,(char *) mlbot[0].val);
		while(TYPE(mlbot[1].val) != ATOM)
			mlbot[1].val = errorh1(Vermisc,
					"Bad associated atom name for binding",
					  nil,TRUE,0,mlbot[1].val);
		mlbot[2].val = dispget(mlbot[2].val,"getaddress: Incorrect discipline specification ",(lispval)Vsubrou->a.pname);
	}
		STASSGN(numberofargs,"");
	strncpy(ostabf,gstab(),128);
	if ( nlist(ostabf,NTABLE) == -1 ) {
	    errorh1(Vermisc,"Getaddress: Bad file",nil,FALSE,0,inewstr(ostabf));
	} else 
	    for (i=0,mlbot=lbot+1; i<numberofargs; i++,mlbot+=3) {
		if ( NTABLE[i].n_value == 0 )
		    fprintf(stderr,"Undefined symbol: %s\n",
			      NTABLE[i].N_name);
		else {
		    work= newfunct();
		    work->bcd.start = (lispval (*) ())NTABLE[i].n_value;
		    work->bcd.discipline = mlbot[1].val;
		    mlbot->val->a.fnbnd = work;
		}
	    };
	Restorestack();
	return(lbot[1].val->a.fnbnd);
};
Exemplo n.º 19
0
static int sge_get_kernel_address(char *name, long *address)
{
   int ret = 0;

   DENTER(TOP_LAYER, "sge_get_kernel_address");

#if defined(IRIX)
   if (!strcmp(KERNEL_AVG_NAME, name)) {
      *address = sysmp(MP_KERNADDR, MPKA_AVENRUN); 
      ret = 1;
   } else {
      *address = 0;
      ret = 0; 
   }
#else
   {
#  if defined(AIX51)
      struct nlist64 kernel_nlist[2];
#  else
      struct nlist kernel_nlist[2];
#  endif

      kernel_nlist[0].n_name = name;
      kernel_nlist[1].n_name = NULL;
#  if defined(ALPHA4) || defined(ALPHA5) || defined(HPUX)
      if (nlist(KERNEL_NAME_FILE, kernel_nlist) >= 0)
#  elif defined(AIX51)
      if (nlist64(KERNEL_NAME_FILE, kernel_nlist) >= 0)
#  else
      if (kernel_initialized && (kvm_nlist(kernel_fd, kernel_nlist) >= 0)) 
#  endif
      {
         *address = kernel_nlist[0].n_value;
         ret = 1;
      } else {
         DPRINTF(("nlist(%s) failed: %s\n", name, strerror(errno)));
         *address = 0;
         ret = 0;
      }
   }
#endif
   DEXIT;
   return ret;
}    
Exemplo n.º 20
0
static int kvm_nlist (kvm_t *kd, struct nlist *nl) {
  int count;
  
#ifdef HAVE_KNLIST
  if (kd->execfile == NULL) {
#ifdef HAVE_KNLIST_ARGS3 
    for(count = 0; nl[count].n_name != NULL; count++);
    count = knlist(nl, count, sizeof(struct nlist));
#else
    count = knlist(nl);
#endif
    if (count < 0)
      _kvm_error(kd->errbuf, "error looking up symbol in live kernel");
    return count;
  }
#endif  
  if ((count = nlist(kd->execfile ? kd->execfile : _PATH_UNIX, nl)) < 0)
    _kvm_error(kd->errbuf, "error looking up symbol in kernel file");
  return count;
}
Exemplo n.º 21
0
dkinit()
{
	register int i;
	register char *cp;
	static int once = 0;
	static char buf[1024];

	if (once)
		return(1);
	nlist("/vmunix", nlst);
	if (nlst[X_DK_NDRIVE].n_value == 0) {
		error("dk_ndrive undefined in kernel");
		return(0);
	}
	dk_ndrive = getw(nlst[X_DK_NDRIVE].n_value);
	if (dk_ndrive <= 0) {
		error("dk_ndrive=%d according to /vmunix", dk_ndrive);
		return(0);
	}
	dk_mspw = (float *)calloc(dk_ndrive, sizeof (float));
	lseek(kmem, nlst[X_DK_MSPW].n_value, L_SET);
	read(kmem, dk_mspw, dk_ndrive * sizeof (float));
	dr_name = (char **)calloc(dk_ndrive, sizeof (char *));
	dk_select = (int *)calloc(dk_ndrive, sizeof (int));
	for (cp = buf, i = 0; i < dk_ndrive; i++) {
		dr_name[i] = cp;
		sprintf(dr_name[i], "dk%d", i);
		cp += strlen(dr_name[i]) + 1;
		if (dk_mspw[i] != 0.0)
			dk_select[i] = 1;
	}
	if (! read_names()) {
		free(dr_name);
		free(dk_select);
		free(dk_mspw);
		return(0);
	}
	once = 1;
	return(1);
}
Exemplo n.º 22
0
int
find_rd_root_image(char *file, Elf_Ehdr *eh, Elf_Phdr *ph, int segment)
{
	unsigned long kernel_start, kernel_size;

	if (nlist(file, wantsyms)) {
		printf("%s: no rd_root_image symbols?\n", file);
		exit(1);
	}
	kernel_start = ph->p_paddr;
	kernel_size = ph->p_filesz;

	rd_root_size_off	= wantsyms[0].n_value - kernel_start;
	rd_root_size_off	-= (ph->p_vaddr - ph->p_paddr);
	rd_root_image_off	= wantsyms[1].n_value - kernel_start;
	rd_root_image_off	-= (ph->p_vaddr - ph->p_paddr);

#ifdef DEBUG
	printf("segment %d rd_root_size_off = 0x%x\n", segment, rd_root_size_off);
	if ((ph->p_vaddr - ph->p_paddr) != 0)
		printf("root_off v %x p %x, diff %x altered %x\n",
		    ph->p_vaddr, ph->p_paddr,
		    (ph->p_vaddr - ph->p_paddr),
		    rd_root_size_off - (ph->p_vaddr - ph->p_paddr));
	printf("rd_root_image_off = 0x%x\n", rd_root_image_off);
#endif

	/*
	 * Sanity check locations of db_* symbols
	 */
	if (rd_root_image_off < 0 || rd_root_image_off >= kernel_size)
		return(0);
	if (rd_root_size_off < 0 || rd_root_size_off >= kernel_size) {
		printf("%s: rd_root_size not in data segment?\n", file);
		return(0);
	}
	mmap_offs = ph->p_offset;
	mmap_size = kernel_size;
	return(1);
}
Exemplo n.º 23
0
static 
setup()
{
	struct ifnet ifnet;
	int off;

	nlist("/vmunix", nl);
	if (nl[0].n_value == 0) {
		fprintf(stderr, "rstat: Variables missing from namelist\n");
		exit (1);
	}
	if ((kmem = open("/dev/kmem", 0)) < 0) {
		fprintf(stderr, "rstat: can't open kmem\n");
		exit(1);
	}

	off = nl[X_IFNET].n_value;
	if (lseek(kmem, (long)off, 0) == -1) {
		fprintf(stderr, "rstat: can't seek in kmem\n");
		exit(1);
	}
	if (read(kmem, (char *)&firstifnet, sizeof(int)) != sizeof (int)) {
		fprintf(stderr, "rstat: can't read firstifnet from kmem\n");
		exit(1);
	}
	numintfs = 0;
	for (off = firstifnet; off;) {
		if (lseek(kmem, (long)off, 0) == -1) {
			fprintf(stderr, "rstat: can't seek in kmem\n");
			exit(1);
		}
		if (read(kmem, (char *)&ifnet, sizeof ifnet) != sizeof ifnet) {
			fprintf(stderr, "rstat: can't read ifnet from kmem\n");
			exit(1);
		}
		numintfs++;
		off = (int) ifnet.if_next;
	}
}
Exemplo n.º 24
0
static void
init_nlist(struct nlist nl[])
 
{
#ifdef CAN_USE_NLIST
  int ret;
#if HAVE_KVM_OPENFILES
  kvm_t *kernel;
  char kvm_errbuf[4096];

  if((kernel = kvm_openfiles(KERNEL_LOC, NULL, NULL, O_RDONLY, kvm_errbuf)) == NULL) {
      fprintf(stderr, "kvm_openfiles: %s\n", kvm_errbuf);
      exit(1);
  }
  if ((ret = kvm_nlist(kernel, nl)) == -1) {
      perror("kvm_nlist");
      exit(1);
  }
  kvm_close(kernel);
#else
  if ((ret = nlist(KERNEL_LOC,nl)) == -1) {
    perror("nlist");
    exit(1);
  }
#endif
  for(ret = 0; nl[ret].n_name != NULL; ret++) {
#ifdef aix4
      if (nl[ret].n_type == 0 && nl[ret].n_value != 0)
	nl[ret].n_type = 1;
#endif
      if (nl[ret].n_type == 0) {
	  DEBUGMSGTL(("auto_nlist", "nlist err:  %s not found\n",nl[ret].n_name));
      } else {
	  DEBUGMSGTL(("auto_nlist", "nlist: %s 0x%X\n", nl[ret].n_name,
                      (unsigned int)nl[ret].n_value));
      }
  }
#endif
}
Exemplo n.º 25
0
int
os_getloadavg(void)
{
LOAD_AVG_TYPE avg;

if (avg_kd < 0)
  {
  struct nlist nl[2];
  nl[0].n_name = LOAD_AVG_SYMBOL;
  nl[1].n_name = "";
  nlist (KERNEL_PATH, nl);
  avg_offset = (long)nl[0].n_value;
  avg_kd = open ("/dev/kmem", 0);
  if (avg_kd < 0) return -1;
  (void) fcntl(avg_kd, F_SETFD, FD_CLOEXEC);
  }

if (lseek (avg_kd, avg_offset, 0) == -1L
    || read (avg_kd, (char *)(&avg), sizeof (avg)) != sizeof(avg))
  return -1;

return (int)(((double)avg/FSCALE)*1000.0);
}
Exemplo n.º 26
0
/*
 * getoffsets - read the magic offsets from the specified file
 */
static void
getoffsets(
	off_t *tick_off,
	off_t *tickadj_off,
	off_t *dosync_off,
	off_t *noprintf_off
	)
{

#ifndef NOKMEM
# ifndef HAVE_KVM_OPEN
	const char **kname;
# endif
#endif

#ifndef NOKMEM
# ifdef NLIST_NAME_UNION
#  define NL_B {{
#  define NL_E }}
# else
#  define NL_B {
#  define NL_E }
# endif
#endif

#define K_FILLER_NAME "DavidLetterman"

#ifdef NLIST_EXTRA_INDIRECTION
	int i;
#endif

#ifndef NOKMEM
	static struct nlist nl[] =
	{
		NL_B
#ifdef K_TICKADJ_NAME
#define N_TICKADJ	0
		K_TICKADJ_NAME
#else
		K_FILLER_NAME
#endif
		NL_E,
		NL_B
#ifdef K_TICK_NAME
#define N_TICK		1
		K_TICK_NAME
#else
		K_FILLER_NAME
#endif
		NL_E,
		NL_B
#ifdef K_DOSYNCTODR_NAME
#define N_DOSYNC	2
		K_DOSYNCTODR_NAME
#else
		K_FILLER_NAME
#endif
		NL_E,
		NL_B
#ifdef K_NOPRINTF_NAME
#define N_NOPRINTF	3
		K_NOPRINTF_NAME
#else
		K_FILLER_NAME
#endif
		NL_E,
		NL_B "" NL_E,
	};

#ifndef HAVE_KVM_OPEN
	static const char *kernels[] =
	{
#ifdef HAVE_GETBOOTFILE
		NULL,			/* *** SEE BELOW! *** */
#endif
		"/kernel/unix",
		"/kernel",
		"/vmunix",
		"/unix",
		"/mach",
		"/hp-ux",
		"/386bsd",
		"/netbsd",
		"/stand/vmunix",
		"/bsd",
		NULL
	};
#endif /* not HAVE_KVM_OPEN */

#ifdef HAVE_KVM_OPEN
	/*
	 * Solaris > 2.5 doesn't have a kernel file.  Use the kvm_* interface
	 * to read the kernel name list. -- stolcke 3/4/96
	 */
	kvm_t *kvm_handle = kvm_open(NULL, NULL, NULL, O_RDONLY, progname);

	if (kvm_handle == NULL)
	{
		(void) fprintf(stderr,
			       "%s: kvm_open failed\n",
			       progname);
		exit(1);
	}
	if (kvm_nlist(kvm_handle, nl) == -1)
	{
		(void) fprintf(stderr,
			       "%s: kvm_nlist failed\n",
			       progname);
		exit(1);
	}
	kvm_close(kvm_handle);
#else /* not HAVE_KVM_OPEN */
#ifdef HAVE_GETBOOTFILE		/* *** SEE HERE! *** */
	if (kernels[0] == NULL)
	{
		char * cp = (char *)getbootfile();

		if (cp)
		{
			kernels[0] = cp;
		}
		else
		{
			kernels[0] = "/Placeholder";
		}
	}
#endif /* HAVE_GETBOOTFILE */
	for (kname = kernels; *kname != NULL; kname++)
	{
		struct stat stbuf;

		if (stat(*kname, &stbuf) == -1)
		{
			continue;
		}
		if (nlist(*kname, nl) >= 0)
		{
			break;
		}
		else
		{
			(void) fprintf(stderr,
				       "%s: nlist didn't find needed symbols from <%s>: %s\n",
				       progname, *kname, strerror(errno));
		}
	}
	if (*kname == NULL)
	{
		(void) fprintf(stderr,
			       "%s: Couldn't find the kernel\n",
			       progname);
		exit(1);
	}
#endif /* HAVE_KVM_OPEN */

	if (dokmem)
	{
		file = kmem;

		fd = openfile(file, O_RDONLY);
#ifdef NLIST_EXTRA_INDIRECTION
		/*
		 * Go one more round of indirection.
		 */
		for (i = 0; i < (sizeof(nl) / sizeof(struct nlist)); i++)
		{
			if ((nl[i].n_value) && (nl[i].n_sclass == 0x6b))
			{
				readvar(fd, nl[i].n_value, &nl[i].n_value);
			}
		}
#endif /* NLIST_EXTRA_INDIRECTION */
	}
#endif /* not NOKMEM */

	*tickadj_off  = 0;
	*tick_off     = 0;
	*dosync_off   = 0;
	*noprintf_off = 0;

#if defined(N_TICKADJ)
	*tickadj_off = nl[N_TICKADJ].n_value;
#endif

#if defined(N_TICK)
	*tick_off = nl[N_TICK].n_value;
#endif

#if defined(N_DOSYNC)
	*dosync_off = nl[N_DOSYNC].n_value;
#endif

#if defined(N_NOPRINTF)
	*noprintf_off = nl[N_NOPRINTF].n_value;
#endif
	return;
}
Exemplo n.º 27
0
int
main(int argc, char** argv)
{
	register int	n;
	register int	i;
	register long	v;
	char*		s;
	char*		e;
	char*		data;
	int		uf;
	int		wf;
	int		idlecmd;
	int		usercount;
	unsigned long	t;
	unsigned long	toss;
	unsigned long	usertime;
	unsigned long	now;
	unsigned long	then;
	Proc_t*		proc;
	CSSTAT		ss;
	struct stat	st;
	char		cmd[PATH_MAX];
	char		buf[PATH_MAX];
	char		tmp[PATH_MAX / 4];
	char*		av[4];
	char*		iv[3];
#if NAMELIST
	DIR*		root;
	struct dirent*	entry;
	int		kf;
#endif

	NoP(argc);
	error_info.id = CS_STAT_DAEMON;
	if (!pathpath(error_info.id, argv[0], PATH_ABSOLUTE|PATH_REGULAR|PATH_EXECUTE, cmd, sizeof(cmd)))
		error(ERROR_SYSTEM|3, "cannot locate daemon executable");
	if (!pathpath(CS_STAT_DIR, argv[0], PATH_EXECUTE, buf, sizeof(buf)))
		error(3, "%s: cannot locate data directory", CS_STAT_DIR);
	if (stat(buf, &st))
		error(ERROR_SYSTEM|3, "%s: stat error", buf);
	if (st.st_uid != geteuid())
		error(3, "%s: effective uid mismatch", buf);
	if (chdir(buf))
		error(ERROR_SYSTEM|3, "%s: chdir error", buf);
	data = csname(0);
	if (argv[1] && strcmp(argv[1], data))
	{
		/*
		 * start remote status daemon
		 */

		data = argv[1];
		if (!csaddr(data))
			error(3, "%s: unknown host", data);
		if (!stat(data, &st) && (long)(CSTIME() - (unsigned long)st.st_ctime) < CS_STAT_DOWN)
			exit(0);
		sfsprintf(buf, sizeof(buf), "./%s", data);
		csstat(buf, &ss);
		if (s = csattr(CS_HOST_LOCAL, "type"))
		{
			strcpy(tmp, s);
			if (s = csattr(data, "type"))
				pathrepl(cmd, sizeof(cmd), tmp, s);
		}

		/*
		 * loop until remote status daemon starts
		 * check for competing startup daemon
		 */

		if (csdaemon(0))
			exit(1);
		umask(S_IRWXU|S_IRWXG|S_IRWXO);
		av[0] = CS_REMOTE_SHELL;
		av[1] = data;
		av[2] = cmd;
		av[3] = 0;
		for (;;)
		{
			update(data, 0, 0, &ss);
			if (!(remote = procopen(av[0], av, NiL, NiL, PROC_UID|PROC_GID)))
				break;
			while (!kill(remote->pid, 0))
				update(data, 0, CS_STAT_FREQ + (CS_STAT_DOWN - CS_STAT_FREQ) / 2, &ss);
			procclose(remote);
			remote = 0;
			if (ss.up > 0)
				ss.up = -ss.up;
		}
		for (;;) update(data, 0, CS_STAT_FREQ + (CS_STAT_DOWN - CS_STAT_FREQ) / 2, &ss);
	}
	remove(data);
	if ((n = open(data, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0)) < 0)
		error(ERROR_SYSTEM|3, "%s: cannot update", data);
	for (i = 0; i < elementsof(usrfiles); i++)
		if ((uf = open(usrfile = usrfiles[i], O_RDONLY)) >= 0) break;
	if (uf < 0)
		error(ERROR_SYSTEM|3, "%s: cannot read", usrfiles[0]);

	/*
	 * final initialization
	 */

	if (csdaemon((1<<2)|(1<<n)|(1<<uf)))
		error(ERROR_SYSTEM|3, "cannot dive into background");
	umask(S_IRWXU|S_IRWXG|S_IRWXO);
	close(2);
	dup(n);
	close(n);
	error_info.id = data;
	av[0] = "uptime";
	av[1] = 0;
	toss = getpid();
	for (s = data; *s; s++)
		CSTOSS(toss, *s);
	usertime = 0;
#if NAMELIST
	for (n = 0; n < elementsof(symbols); n++)
		names[n].n_name = symbols[n].name;
	if ((kf = open(memfile, O_RDONLY)) >= 0)
	{
		if (chdir("/"))
			error(ERROR_SYSTEM|3, "/: chdir error");
		s = 0;
		for (i = 0; i < elementsof(sysfiles); i++)
			if (!access(sysfiles[i], F_OK))
			{
				s = sysfiles[i];
				break;
			}
		if (!s)
		{
			if (!(root = opendir(".")))
				error(ERROR_SYSTEM|3, "/: cannot read");
			while (entry = readdir(root))
			{
				if ((i = strlen(entry->d_name) - 2) > 0 && entry->d_name[i] == 'i' && entry->d_name[i + 1] == 'x' && !stat(entry->d_name, &st) && (st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))
				{
					s = entry->d_name;
					break;
				}
			}
			closedir(root);
		}
		nlist(s, names);
		for (n = 0; n < elementsof(symbols); n++)
			if (!names[n].n_type)
			{
				error(1, "%s: %s not in nlist", s, names[n].n_name);
				close(kf);
				kf = -1;
			}
		if (chdir(buf))
			error(ERROR_SYSTEM|3, "%s: chdir error", buf);
	}
	if (kf < 0)
#endif
	{
		sfsprintf(buf, sizeof(buf), "%s/%s%s%s", WHODIR, WHOPRE, data, WHOSUF);
		if ((wf = open(buf, O_RDONLY)) >= 0)
		{
			if (read(wf, &who, sizeof(who)) != sizeof(who) || who.wd_vers != WHOVERS || who.wd_type != WHOTYPE)
			{
				error(1, "%s: rwhod protocol mismatch", buf);
				close(wf);
				wf = -1;
			}
			else whofile = strdup(buf);
		}
	}
	strcpy(cmd + strlen(cmd), ".idle");
	if (eaccess(cmd, X_OK)) idlecmd = 0;
	else
	{
		idlecmd = 1;
		iv[0] = cmd;
		iv[1] = data;
		iv[2] = 0;
	}

	/*
	 * the daemon loop
	 */

	ss.idle = 4 * 60 * 60;
	now = CSTIME();
	for (;;)
	{
		then = now;
		now = CSTIME();

		/*
		 * update logged in user stats
		 */

		if (fstat(uf, &st))
			error(ERROR_SYSTEM|3, "%s: stat error", usrfile);
		if (usertime != (unsigned long)st.st_mtime)
		{
			usertime = st.st_mtime;
			if (lseek(uf, 0L, 0))
				error(ERROR_SYSTEM|3, "%s: seek error", usrfile);
			if ((n = read(uf, usrs, sizeof(usrs))) < 0)
				error(ERROR_SYSTEM|3, "%s: read error", usrfile);
			usercount = n / sizeof(struct utmp);
		}

		/*
		 * count the interesting users
		 * find the min user idle time
		 */

		if (idlecmd)
		{
			/*
			 * check idle command
			 */

			if (!(proc = procopen(iv[0], iv, NiL, NiL, PROC_READ|PROC_UID|PROC_GID)))
				idlecmd = 0;
			else
			{
				idlecmd = 1;
				n = read(proc->rfd, buf, sizeof(buf));
				if (procclose(proc) || n < 0)
					idlecmd = 0;
				else
				{
					if (n > 0)
						n--;
					buf[n] = 0;
					if (isdigit(buf[0]))
						ss.idle = strtol(buf, NiL, 10);
					else if (streq(buf, "busy"))
						ss.idle = 0;
					else if (streq(buf, "free"))
						ss.idle = ~0;
					else if (streq(buf, "idle"))
					{
						n = since(then);
						if ((ss.idle + n) < ss.idle) ss.idle = ~0;
						else ss.idle += n;
					}
					else idlecmd = -1;
				}
			}
		}
		if (idlecmd <= 0)
			ss.idle = ~0;
		ss.users = 0;
		for (i = 0; i < usercount; i++)
			if (usrs[i].ut_name[0] && usrs[i].ut_line[0])
			{
				sfsprintf(buf, sizeof(buf), "/dev/%s", usrs[i].ut_line);
				if (stat(buf, &st)) usrs[i].ut_name[0] = 0;
				else
				{
					v = since(st.st_atime);
					if (v < CS_STAT_IGNORE)
						ss.users++;
					if (idlecmd <= 0 && v < ss.idle)
						ss.idle = v;
				}
			}
		if (idlecmd <= 0 || !ss.users)
		{
			/*
			 * check devices for min idle time
			 */

			for (i = 0; i < elementsof(devfiles); i++)
				if (devfiles[i])
				{
					if (stat(devfiles[i], &st)) devfiles[i] = 0;
					else
					{
						v = since(st.st_atime);
						if (!ss.users && v < CS_STAT_IGNORE)
							ss.users++;
						if (idlecmd <= 0 && v < ss.idle)
							ss.idle = v;
					}
				}
		}

		/*
		 * get the hard stuff
		 */

#if NAMELIST
		if (kf >= 0)
		{
			/*
			 * update memfile symbol values
			 */

			for (n = 0; n < elementsof(symbols); n++)
				if (symbols[n].once >= 0)
				{
					if (lseek(kf, (long)names[n].n_value, 0) != (long)names[n].n_value)
						error(ERROR_SYSTEM|3, "%s: %s seek error", memfile, names[n].n_name);
					if (read(kf, symbols[n].addr, symbols[n].size) != symbols[n].size)
						error(ERROR_SYSTEM|3, "%s: %s read error", memfile, names[n].n_name);
					if (symbols[n].once) symbols[n].once = -1;
				}
#ifdef CP_TIME
			for (i = 0; i < CPUSTATES; i++)
				cp_time[i] = 0;
			for (n = 0; n <= maxcpu; n++)
				if (CPUFOUND(n))
					for (i = 0; i < CPUSTATES; i++)
						cp_time[i] += CP_TIME(n)[i];
#endif
			ss.load = (avenrun * 100) / FSCALE;
		}
		else
#endif
		if (wf >= 0)
		{
			if (lseek(wf, 0L, 0))
				error(ERROR_SYSTEM|3, "%s: seek error", whofile);
			read(wf, &who, sizeof(who));
			ss.load = who.wd_loadav[0];
			boottime = who.wd_boottime;
			for (i = 0; i < elementsof(cp_time); i++)
				cp_time[i] = 100;
		}
		else if (!(proc = procopen(av[0], av, NiL, NiL, PROC_READ|PROC_UID|PROC_GID)))
			error(ERROR_SYSTEM|3, "%s: exec error", av[0]);
		else
		{
			/*
			 * defer to process with memfile access
			 */

			n = read(proc->rfd, buf, sizeof(buf) - 1);
			if (procclose(proc) || n <= 0)
				error(3, "%s: invalid", av[0]);
			buf[n] = 0;
			if (!(s = strrchr(buf, ':')))
				error(3, "%s: invalid output", av[0]);
			ss.load = strton(s + 1, NiL, NiL, 100);
			n = 0;
			if ((s = strchr(buf, 'u')) && *++s == 'p')
			{
				n = strtol(s + 1, &e, 10) * 60 * 60;
				s = e;
				while (isspace(*s)) s++;
				if (*s == 'd')
				{
					n *= 24;
					while (*s && !isdigit(*s)) s++;
					n += strtol(s, &e, 10) * 60 * 60;
					s = e;
				}
				if (*s == ':') n += strtol(s + 1, NiL, 10) * 60;
			}
			boottime = since(n);
			for (i = 0; i < elementsof(cp_time); i++)
				cp_time[i] = 0;
		}

		/*
		 * finalize the new stat info
		 */

		t = 0;
		for (i = 0; i < elementsof(cp_time); i++)
		{
			if ((cp_diff[i] = cp_time[i] - cp_prev[i]) < 0) cp_diff[i] = -cp_diff[i];
			t += cp_diff[i];
			cp_prev[i] = cp_time[i];
		}
		if (!t) t = 1;
		ss.pctsys = (cp_diff[CP_SYS] * 100) / t;
		ss.pctusr = ((cp_diff[CP_USER] + cp_diff[CP_NICE]) * 100) / t;
		ss.up = since(boottime);
		update(data, now, (4 * CS_STAT_FREQ + 2 * (CSTOSS(toss, 0) % (CS_STAT_FREQ + 1))) / 5, &ss);
	}
}
Exemplo n.º 28
0
int
getloadavg (double loadavg[], int nelem)
{
  int elem = 0;                 /* Return value.  */

# ifdef NO_GET_LOAD_AVG
#  define LDAV_DONE
  /* Set errno to zero to indicate that there was no particular error;
     this function just can't work at all on this system.  */
  errno = 0;
  elem = -1;
# endif

# if !defined (LDAV_DONE) && defined (HAVE_LIBKSTAT)
/* Use libkstat because we don't have to be root.  */
#  define LDAV_DONE
  kstat_ctl_t *kc;
  kstat_t *ksp;
  kstat_named_t *kn;

  kc = kstat_open ();
  if (kc == 0)
    return -1;
  ksp = kstat_lookup (kc, "unix", 0, "system_misc");
  if (ksp == 0)
    return -1;
  if (kstat_read (kc, ksp, 0) == -1)
    return -1;


  kn = kstat_data_lookup (ksp, "avenrun_1min");
  if (kn == 0)
    {
      /* Return -1 if no load average information is available.  */
      nelem = 0;
      elem = -1;
    }

  if (nelem >= 1)
    loadavg[elem++] = (double) kn->value.ul / FSCALE;

  if (nelem >= 2)
    {
      kn = kstat_data_lookup (ksp, "avenrun_5min");
      if (kn != 0)
        {
          loadavg[elem++] = (double) kn->value.ul / FSCALE;

          if (nelem >= 3)
            {
              kn = kstat_data_lookup (ksp, "avenrun_15min");
              if (kn != 0)
                loadavg[elem++] = (double) kn->value.ul / FSCALE;
            }
        }
    }

  kstat_close (kc);
# endif /* HAVE_LIBKSTAT */

# if !defined (LDAV_DONE) && defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC)
/* Use pstat_getdynamic() because we don't have to be root.  */
#  define LDAV_DONE
#  undef LOAD_AVE_TYPE

  struct pst_dynamic dyn_info;
  if (pstat_getdynamic (&dyn_info, sizeof (dyn_info), 0, 0) < 0)
    return -1;
  if (nelem > 0)
    loadavg[elem++] = dyn_info.psd_avg_1_min;
  if (nelem > 1)
    loadavg[elem++] = dyn_info.psd_avg_5_min;
  if (nelem > 2)
    loadavg[elem++] = dyn_info.psd_avg_15_min;

# endif /* hpux && HAVE_PSTAT_GETDYNAMIC */

# if ! defined LDAV_DONE && defined HAVE_LIBPERFSTAT
#  define LDAV_DONE
#  undef LOAD_AVE_TYPE
/* Use perfstat_cpu_total because we don't have to be root. */
  {
    perfstat_cpu_total_t cpu_stats;
    int result = perfstat_cpu_total (NULL, &cpu_stats, sizeof cpu_stats, 1);
    if (result == -1)
      return result;
    loadavg[0] = cpu_stats.loadavg[0] / (double)(1 << SBITS);
    loadavg[1] = cpu_stats.loadavg[1] / (double)(1 << SBITS);
    loadavg[2] = cpu_stats.loadavg[2] / (double)(1 << SBITS);
    elem = 3;
  }
# endif

# if !defined (LDAV_DONE) && (defined (__linux__) || defined (__CYGWIN__))
#  define LDAV_DONE
#  undef LOAD_AVE_TYPE

#  ifndef LINUX_LDAV_FILE
#   define LINUX_LDAV_FILE "/proc/loadavg"
#  endif

  char ldavgbuf[3 * (INT_STRLEN_BOUND (int) + sizeof ".00 ")];
  char const *ptr = ldavgbuf;
  int fd, count;

  fd = open (LINUX_LDAV_FILE, O_RDONLY);
  if (fd == -1)
    return -1;
  count = read (fd, ldavgbuf, sizeof ldavgbuf - 1);
  (void) close (fd);
  if (count <= 0)
    return -1;
  ldavgbuf[count] = '\0';

  for (elem = 0; elem < nelem; elem++)
    {
      char *endptr;
      double d;

      errno = 0;
      d = c_strtod (ptr, &endptr);
      if (ptr == endptr || (d == 0 && errno != 0))
        {
          if (elem == 0)
            return -1;
          break;
        }
      loadavg[elem] = d;
      ptr = endptr;
    }

  return elem;

# endif /* __linux__ || __CYGWIN__ */

# if !defined (LDAV_DONE) && defined (__NetBSD__)
#  define LDAV_DONE
#  undef LOAD_AVE_TYPE

#  ifndef NETBSD_LDAV_FILE
#   define NETBSD_LDAV_FILE "/kern/loadavg"
#  endif

  unsigned long int load_ave[3], scale;
  int count;
  FILE *fp;

  fp = fopen (NETBSD_LDAV_FILE, "r");
  if (fp == NULL)
    return -1;
  count = fscanf (fp, "%lu %lu %lu %lu\n",
                  &load_ave[0], &load_ave[1], &load_ave[2],
                  &scale);
  (void) fclose (fp);
  if (count != 4)
    return -1;

  for (elem = 0; elem < nelem; elem++)
    loadavg[elem] = (double) load_ave[elem] / (double) scale;

  return elem;

# endif /* __NetBSD__ */

# if !defined (LDAV_DONE) && defined (NeXT)
#  define LDAV_DONE
  /* The NeXT code was adapted from iscreen 3.2.  */

  host_t host;
  struct processor_set_basic_info info;
  unsigned int info_count;

  /* We only know how to get the 1-minute average for this system,
     so even if the caller asks for more than 1, we only return 1.  */

  if (!getloadavg_initialized)
    {
      if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS)
        getloadavg_initialized = true;
    }

  if (getloadavg_initialized)
    {
      info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
      if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host,
                              (processor_set_info_t) &info, &info_count)
          != KERN_SUCCESS)
        getloadavg_initialized = false;
      else
        {
          if (nelem > 0)
            loadavg[elem++] = (double) info.load_average / LOAD_SCALE;
        }
    }

  if (!getloadavg_initialized)
    return -1;
# endif /* NeXT */

# if !defined (LDAV_DONE) && defined (UMAX)
#  define LDAV_DONE
/* UMAX 4.2, which runs on the Encore Multimax multiprocessor, does not
   have a /dev/kmem.  Information about the workings of the running kernel
   can be gathered with inq_stats system calls.
   We only know how to get the 1-minute average for this system.  */

  struct proc_summary proc_sum_data;
  struct stat_descr proc_info;
  double load;
  register unsigned int i, j;

  if (cpus == 0)
    {
      register unsigned int c, i;
      struct cpu_config conf;
      struct stat_descr desc;

      desc.sd_next = 0;
      desc.sd_subsys = SUBSYS_CPU;
      desc.sd_type = CPUTYPE_CONFIG;
      desc.sd_addr = (char *) &conf;
      desc.sd_size = sizeof conf;

      if (inq_stats (1, &desc))
        return -1;

      c = 0;
      for (i = 0; i < conf.config_maxclass; ++i)
        {
          struct class_stats stats;
          bzero ((char *) &stats, sizeof stats);

          desc.sd_type = CPUTYPE_CLASS;
          desc.sd_objid = i;
          desc.sd_addr = (char *) &stats;
          desc.sd_size = sizeof stats;

          if (inq_stats (1, &desc))
            return -1;

          c += stats.class_numcpus;
        }
      cpus = c;
      samples = cpus < 2 ? 3 : (2 * cpus / 3);
    }

  proc_info.sd_next = 0;
  proc_info.sd_subsys = SUBSYS_PROC;
  proc_info.sd_type = PROCTYPE_SUMMARY;
  proc_info.sd_addr = (char *) &proc_sum_data;
  proc_info.sd_size = sizeof (struct proc_summary);
  proc_info.sd_sizeused = 0;

  if (inq_stats (1, &proc_info) != 0)
    return -1;

  load = proc_sum_data.ps_nrunnable;
  j = 0;
  for (i = samples - 1; i > 0; --i)
    {
      load += proc_sum_data.ps_nrun[j];
      if (j++ == PS_NRUNSIZE)
        j = 0;
    }

  if (nelem > 0)
    loadavg[elem++] = load / samples / cpus;
# endif /* UMAX */

# if !defined (LDAV_DONE) && defined (DGUX)
#  define LDAV_DONE
  /* This call can return -1 for an error, but with good args
     it's not supposed to fail.  The first argument is for no
     apparent reason of type `long int *'.  */
  dg_sys_info ((long int *) &load_info,
               DG_SYS_INFO_LOAD_INFO_TYPE,
               DG_SYS_INFO_LOAD_VERSION_0);

  if (nelem > 0)
    loadavg[elem++] = load_info.one_minute;
  if (nelem > 1)
    loadavg[elem++] = load_info.five_minute;
  if (nelem > 2)
    loadavg[elem++] = load_info.fifteen_minute;
# endif /* DGUX */

# if !defined (LDAV_DONE) && defined (apollo)
#  define LDAV_DONE
/* Apollo code from [email protected] (Ray Lischner).

   This system call is not documented.  The load average is obtained as
   three long integers, for the load average over the past minute,
   five minutes, and fifteen minutes.  Each value is a scaled integer,
   with 16 bits of integer part and 16 bits of fraction part.

   I'm not sure which operating system first supported this system call,
   but I know that SR10.2 supports it.  */

  extern void proc1_$get_loadav ();
  unsigned long load_ave[3];

  proc1_$get_loadav (load_ave);

  if (nelem > 0)
    loadavg[elem++] = load_ave[0] / 65536.0;
  if (nelem > 1)
    loadavg[elem++] = load_ave[1] / 65536.0;
  if (nelem > 2)
    loadavg[elem++] = load_ave[2] / 65536.0;
# endif /* apollo */

# if !defined (LDAV_DONE) && defined (OSF_MIPS)
#  define LDAV_DONE

  struct tbl_loadavg load_ave;
  table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
  loadavg[elem++]
    = (load_ave.tl_lscale == 0
       ? load_ave.tl_avenrun.d[0]
       : (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale));
# endif /* OSF_MIPS */

# if !defined (LDAV_DONE) && (defined (__MSDOS__) || defined (WINDOWS32))
#  define LDAV_DONE

  /* A faithful emulation is going to have to be saved for a rainy day.  */
  for ( ; elem < nelem; elem++)
    {
      loadavg[elem] = 0.0;
    }
# endif  /* __MSDOS__ || WINDOWS32 */

# if !defined (LDAV_DONE) && defined (OSF_ALPHA)
#  define LDAV_DONE

  struct tbl_loadavg load_ave;
  table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
  for (elem = 0; elem < nelem; elem++)
    loadavg[elem]
      = (load_ave.tl_lscale == 0
         ? load_ave.tl_avenrun.d[elem]
         : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale));
# endif /* OSF_ALPHA */

# if ! defined LDAV_DONE && defined __VMS
  /* VMS specific code -- read from the Load Ave driver.  */

  LOAD_AVE_TYPE load_ave[3];
  static bool getloadavg_initialized;
#  ifdef eunice
  struct
  {
    int dsc$w_length;
    char *dsc$a_pointer;
  } descriptor;
#  endif

  /* Ensure that there is a channel open to the load ave device.  */
  if (!getloadavg_initialized)
    {
      /* Attempt to open the channel.  */
#  ifdef eunice
      descriptor.dsc$w_length = 18;
      descriptor.dsc$a_pointer = "$$VMS_LOAD_AVERAGE";
#  else
      $DESCRIPTOR (descriptor, "LAV0:");
#  endif
      if (sys$assign (&descriptor, &channel, 0, 0) & 1)
        getloadavg_initialized = true;
    }

  /* Read the load average vector.  */
  if (getloadavg_initialized
      && !(sys$qiow (0, channel, IO$_READVBLK, 0, 0, 0,
                     load_ave, 12, 0, 0, 0, 0) & 1))
    {
      sys$dassgn (channel);
      getloadavg_initialized = false;
    }

  if (!getloadavg_initialized)
    return -1;
# endif /* ! defined LDAV_DONE && defined __VMS */

# if ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS

  /* UNIX-specific code -- read the average from /dev/kmem.  */

#  define LDAV_PRIVILEGED               /* This code requires special installation.  */

  LOAD_AVE_TYPE load_ave[3];

  /* Get the address of LDAV_SYMBOL.  */
  if (offset == 0)
    {
#  ifndef sgi
#   if ! defined NLIST_STRUCT || ! defined N_NAME_POINTER
      strcpy (nl[0].n_name, LDAV_SYMBOL);
      strcpy (nl[1].n_name, "");
#   else /* NLIST_STRUCT */
#    ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME
      nl[0].n_un.n_name = LDAV_SYMBOL;
      nl[1].n_un.n_name = 0;
#    else /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
      nl[0].n_name = LDAV_SYMBOL;
      nl[1].n_name = 0;
#    endif /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
#   endif /* NLIST_STRUCT */

#   ifndef SUNOS_5
      if (
#    if !(defined (_AIX) && !defined (ps2))
          nlist (KERNEL_FILE, nl)
#    else  /* _AIX */
          knlist (nl, 1, sizeof (nl[0]))
#    endif
          >= 0)
          /* Omit "&& nl[0].n_type != 0 " -- it breaks on Sun386i.  */
          {
#    ifdef FIXUP_KERNEL_SYMBOL_ADDR
            FIXUP_KERNEL_SYMBOL_ADDR (nl);
#    endif
            offset = nl[0].n_value;
          }
#   endif /* !SUNOS_5 */
#  else  /* sgi */
      int ldav_off;

      ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN);
      if (ldav_off != -1)
        offset = (long int) ldav_off & 0x7fffffff;
#  endif /* sgi */
    }

  /* Make sure we have /dev/kmem open.  */
  if (!getloadavg_initialized)
    {
#  ifndef SUNOS_5
      channel = open ("/dev/kmem", O_RDONLY);
      if (channel >= 0)
        {
          /* Set the channel to close on exec, so it does not
             litter any child's descriptor table.  */
          set_cloexec_flag (channel, true);
          getloadavg_initialized = true;
        }
#  else /* SUNOS_5 */
      /* We pass 0 for the kernel, corefile, and swapfile names
         to use the currently running kernel.  */
      kd = kvm_open (0, 0, 0, O_RDONLY, 0);
      if (kd != 0)
        {
          /* nlist the currently running kernel.  */
          kvm_nlist (kd, nl);
          offset = nl[0].n_value;
          getloadavg_initialized = true;
        }
#  endif /* SUNOS_5 */
    }

  /* If we can, get the load average values.  */
  if (offset && getloadavg_initialized)
    {
      /* Try to read the load.  */
#  ifndef SUNOS_5
      if (lseek (channel, offset, 0) == -1L
          || read (channel, (char *) load_ave, sizeof (load_ave))
          != sizeof (load_ave))
        {
          close (channel);
          getloadavg_initialized = false;
        }
#  else  /* SUNOS_5 */
      if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave))
          != sizeof (load_ave))
        {
          kvm_close (kd);
          getloadavg_initialized = false;
        }
#  endif /* SUNOS_5 */
    }

  if (offset == 0 || !getloadavg_initialized)
    return -1;
# endif /* ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS */

# if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) /* Including VMS.  */
  if (nelem > 0)
    loadavg[elem++] = LDAV_CVT (load_ave[0]);
  if (nelem > 1)
    loadavg[elem++] = LDAV_CVT (load_ave[1]);
  if (nelem > 2)
    loadavg[elem++] = LDAV_CVT (load_ave[2]);

#  define LDAV_DONE
# endif /* !LDAV_DONE && LOAD_AVE_TYPE */

# if !defined LDAV_DONE
  /* Set errno to zero to indicate that there was no particular error;
     this function just can't work at all on this system.  */
  errno = 0;
  elem = -1;
# endif
  return elem;
}
Exemplo n.º 29
0
/******************************************************************
 *              macho_load_file
 *
 * Loads the information for Mach-O module stored in 'filename'.
 * The module has been loaded at 'load_addr' address.
 * returns
 *      FALSE if the file cannot be found/opened or if the file doesn't
 *              contain symbolic info (or this info cannot be read or parsed)
 *      TRUE on success
 */
static BOOL macho_load_file(struct process* pcs, const WCHAR* filename,
                            unsigned long load_addr, struct macho_info* macho_info)
{
    BOOL                    ret = TRUE;
    struct macho_file_map   fmap;

    TRACE("(%p/%p, %s, 0x%08lx, %p/0x%08x)\n", pcs, pcs->handle, debugstr_w(filename),
            load_addr, macho_info, macho_info->flags);

    if (!macho_map_file(filename, &fmap)) return FALSE;

    /* Find the dynamic loader's table of images loaded into the process.
     */
    if (macho_info->flags & MACHO_INFO_DEBUG_HEADER)
    {
        static void* dyld_all_image_infos_addr;

        /* This symbol should be in the same place in all processes. */
        if (!dyld_all_image_infos_addr)
        {
            struct nlist nl[2];
            memset(nl, 0, sizeof(nl));
            nl[0].n_un.n_name = (char*)"_dyld_all_image_infos";
            if (!nlist("/usr/lib/dyld", nl))
                dyld_all_image_infos_addr = (void*)nl[0].n_value;
        }

        if (dyld_all_image_infos_addr)
            macho_info->dbg_hdr_addr = (unsigned long)dyld_all_image_infos_addr;
        else
            ret = FALSE;
        TRACE("dbg_hdr_addr = 0x%08lx\n", macho_info->dbg_hdr_addr);
    }

    if (macho_info->flags & MACHO_INFO_MODULE)
    {
        struct macho_module_info *macho_module_info;
        struct module_format*   modfmt =
            HeapAlloc(GetProcessHeap(), 0, sizeof(struct module_format) + sizeof(struct macho_module_info));
        if (!modfmt) goto leave;
        macho_info->module = module_new(pcs, filename, DMT_MACHO, FALSE, load_addr,
                                        fmap.segs_size, 0, calc_crc32(fmap.fd));
        if (!macho_info->module)
        {
            HeapFree(GetProcessHeap(), 0, modfmt);
            goto leave;
        }
        macho_module_info = (void*)(modfmt + 1);
        macho_info->module->format_info[DFI_MACHO] = modfmt;

        modfmt->module       = macho_info->module;
        modfmt->remove       = NULL;
        modfmt->loc_compute  = NULL;
        modfmt->u.macho_info = macho_module_info;

        macho_module_info->load_addr = load_addr;

        if (dbghelp_options & SYMOPT_DEFERRED_LOADS)
            macho_info->module->module.SymType = SymDeferred;
        else if (!macho_load_debug_info(macho_info->module, &fmap))
            ret = FALSE;

        macho_info->module->format_info[DFI_MACHO]->u.macho_info->in_use = 1;
        macho_info->module->format_info[DFI_MACHO]->u.macho_info->is_loader = 0;
        TRACE("module = %p\n", macho_info->module);
    }

    if (macho_info->flags & MACHO_INFO_NAME)
    {
        WCHAR*  ptr;
        ptr = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1) * sizeof(WCHAR));
        if (ptr)
        {
            strcpyW(ptr, filename);
            macho_info->module_name = ptr;
        }
        else ret = FALSE;
        TRACE("module_name = %p %s\n", macho_info->module_name, debugstr_w(macho_info->module_name));
    }
leave:
    macho_unmap_file(&fmap);

    TRACE(" => %d\n", ret);
    return ret;
}
Exemplo n.º 30
0
int
getloadavg (double loadavg[], int nelem)
{
  int elem = 0;			/* Return value.  */

#ifdef NO_GET_LOAD_AVG
#define LDAV_DONE
  /* Set errno to zero to indicate that there was no particular error;
     this function just can't work at all on this system.  */
  errno = 0;
  elem = -2;
#endif /* NO_GET_LOAD_AVG */

#if ! defined (LDAV_DONE) && defined (HAVE_KSTAT_H) && defined (HAVE_LIBKSTAT)
#define LDAV_DONE
/* getloadavg is best implemented using kstat (kernel stats), on
   systems (like SunOS5) that support it, since you don't need special
   privileges to use it.

   Initial implementation courtesy Zlatko Calusic <*****@*****.**>.
   Integrated to XEmacs by Hrvoje Niksic <*****@*****.**>.
   Additional cleanup by Hrvoje Niksic, based on code published by
   Casper Dik <*****@*****.**>.  */
  kstat_ctl_t *kc;
  kstat_t *ksp;
  static char *avestrings[] = { "avenrun_1min",
				"avenrun_5min",
				"avenrun_15min" };

  if (nelem > countof (avestrings))
    nelem = countof (avestrings);

  kc = kstat_open ();
  if (!kc)
    return -1;
  ksp = kstat_lookup (kc, "unix", 0, "system_misc");
  if (!ksp)
    {
      kstat_close (kc);
      return -1;
    }
  if (kstat_read (kc, ksp, 0) < 0)
    {
      kstat_close (kc);
      return -1;
    }
  for (elem = 0; elem < nelem; elem++)
    {
      kstat_named_t *kn =
	(kstat_named_t *) kstat_data_lookup (ksp, avestrings[elem]);
      if (!kn)
	{
	  kstat_close (kc);
	  return -1;
	}
      loadavg[elem] = (double)kn->value.ul / FSCALE;
    }
  kstat_close (kc);
#endif /* HAVE_KSTAT_H && HAVE_LIBKSTAT */

#if !defined (LDAV_DONE) && defined (HAVE_SYS_PSTAT_H)
#define LDAV_DONE
  /* This is totally undocumented, and is not guaranteed to work, but
     mayhap it might ....  If it does work, it will work only on HP-UX
     8.0 or later.  -- Darryl Okahata <*****@*****.**> */
#undef LOAD_AVE_TYPE		/* Make sure these don't exist. */
#undef LOAD_AVE_CVT
#undef LDAV_SYMBOL
  struct pst_dynamic	procinfo;
  union pstun		statbuf;

  statbuf.pst_dynamic = &procinfo;
  if (pstat (PSTAT_DYNAMIC, statbuf, sizeof (struct pst_dynamic), 0, 0) == -1)
    return (-1);
  loadavg[elem++] = procinfo.psd_avg_1_min;
  loadavg[elem++] = procinfo.psd_avg_5_min;
  loadavg[elem++] = procinfo.psd_avg_15_min;
#endif	/* HPUX */

#if !defined (LDAV_DONE) && defined (__linux__)
#define LDAV_DONE
#undef LOAD_AVE_TYPE

#ifndef LINUX_LDAV_FILE
#define LINUX_LDAV_FILE "/proc/loadavg"
#endif

  char ldavgbuf[40];
  double load_ave[3];
  int fd, count;

  fd = open (LINUX_LDAV_FILE, O_RDONLY);
  if (fd == -1)
    return -1;
  count = read (fd, ldavgbuf, 40);
  (void) close (fd);
  if (count <= 0)
    return -1;

  count = sscanf (ldavgbuf, "%lf %lf %lf",
		  &load_ave[0], &load_ave[1], &load_ave[2]);
  if (count < 1)
    return -1;

  for (elem = 0; elem < nelem && elem < count; elem++)
    loadavg[elem] = load_ave[elem];
#endif /* __linux__ */

#if !defined (LDAV_DONE) && defined (__NetBSD__) || defined (__OpenBSD__)
#define LDAV_DONE
#undef LOAD_AVE_TYPE

#ifndef NETBSD_LDAV_FILE
#define NETBSD_LDAV_FILE "/kern/loadavg"
#endif

  unsigned long int load_ave[3], scale;
  int count;
  FILE *fp;

  fp = fopen (NETBSD_LDAV_FILE, "r");
  if (fp == NULL)
    return -1;
  count = fscanf (fp, "%lu %lu %lu %lu\n",
		  &load_ave[0], &load_ave[1], &load_ave[2],
		  &scale);
  (void) fclose (fp);
  if (count != 4)
    return -1;

  for (elem = 0; elem < nelem; elem++)
    loadavg[elem] = (double) load_ave[elem] / (double) scale;
#endif /* __NetBSD__ or __OpenBSD__ */

#if !defined (LDAV_DONE) && defined (NeXT)
#define LDAV_DONE
  /* The NeXT code was adapted from iscreen 3.2.  */

  host_t host;
  struct processor_set_basic_info info;
  unsigned info_count;

  /* We only know how to get the 1-minute average for this system,
     so even if the caller asks for more than 1, we only return 1.  */

  if (!getloadavg_initialized)
    {
      if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS)
	getloadavg_initialized = 1;
    }

  if (getloadavg_initialized)
    {
      info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
      if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host,
			     (processor_set_info_t) &info, &info_count)
	  != KERN_SUCCESS)
	getloadavg_initialized = 0;
      else
	{
	  if (nelem > 0)
	    loadavg[elem++] = (double) info.load_average / LOAD_SCALE;
	}
    }

  if (!getloadavg_initialized)
    return -1;
#endif /* NeXT */

#if !defined (LDAV_DONE) && defined (UMAX)
#define LDAV_DONE
/* UMAX 4.2, which runs on the Encore Multimax multiprocessor, does not
   have a /dev/kmem.  Information about the workings of the running kernel
   can be gathered with inq_stats system calls.
   We only know how to get the 1-minute average for this system.  */

  struct proc_summary proc_sum_data;
  struct stat_descr proc_info;
  double load;
  REGISTER unsigned int i, j;

  if (cpus == 0)
    {
      REGISTER unsigned int c, i;
      struct cpu_config conf;
      struct stat_descr desc;

      desc.sd_next = 0;
      desc.sd_subsys = SUBSYS_CPU;
      desc.sd_type = CPUTYPE_CONFIG;
      desc.sd_addr = (char *) &conf;
      desc.sd_size = sizeof conf;

      if (inq_stats (1, &desc))
	return -1;

      c = 0;
      for (i = 0; i < conf.config_maxclass; ++i)
	{
	  struct class_stats stats;
	  memset ((char *) &stats, 0, sizeof stats);

	  desc.sd_type = CPUTYPE_CLASS;
	  desc.sd_objid = i;
	  desc.sd_addr = (char *) &stats;
	  desc.sd_size = sizeof stats;

	  if (inq_stats (1, &desc))
	    return -1;

	  c += stats.class_numcpus;
	}
      cpus = c;
      samples = cpus < 2 ? 3 : (2 * cpus / 3);
    }

  proc_info.sd_next = 0;
  proc_info.sd_subsys = SUBSYS_PROC;
  proc_info.sd_type = PROCTYPE_SUMMARY;
  proc_info.sd_addr = (char *) &proc_sum_data;
  proc_info.sd_size = sizeof (struct proc_summary);
  proc_info.sd_sizeused = 0;

  if (inq_stats (1, &proc_info) != 0)
    return -1;

  load = proc_sum_data.ps_nrunnable;
  j = 0;
  for (i = samples - 1; i > 0; --i)
    {
      load += proc_sum_data.ps_nrun[j];
      if (j++ == PS_NRUNSIZE)
	j = 0;
    }

  if (nelem > 0)
    loadavg[elem++] = load / samples / cpus;
#endif /* UMAX */

#if !defined (LDAV_DONE) && defined (DGUX)
#define LDAV_DONE
  /* This call can return -1 for an error, but with good args
     it's not supposed to fail.  The first argument is for no
     apparent reason of type `long int *'.  */
  dg_sys_info ((long int *) &load_info,
	       DG_SYS_INFO_LOAD_INFO_TYPE,
	       DG_SYS_INFO_LOAD_VERSION_0);

  if (nelem > 0)
    loadavg[elem++] = load_info.one_minute;
  if (nelem > 1)
    loadavg[elem++] = load_info.five_minute;
  if (nelem > 2)
    loadavg[elem++] = load_info.fifteen_minute;
#endif /* DGUX */

#if !defined (LDAV_DONE) && defined (OSF_MIPS)
#define LDAV_DONE

  struct tbl_loadavg load_ave;
  table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
  loadavg[elem++]
    = (load_ave.tl_lscale == 0
       ? load_ave.tl_avenrun.d[0]
       : (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale));
#endif	/* OSF_MIPS */

#if !defined (LDAV_DONE) && (defined (WIN32_NATIVE) || defined (CYGWIN))
#define LDAV_DONE

  /* A faithful emulation is going to have to be saved for a rainy day.  */
  for ( ; elem < nelem; elem++)
    {
      loadavg[elem] = 0.0;
    }
#endif  /* WIN32_NATIVE or CYGWIN */

#if !defined (LDAV_DONE) && defined (OSF_ALPHA)
#define LDAV_DONE

  struct tbl_loadavg load_ave;
  table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
  for (elem = 0; elem < nelem; elem++)
    loadavg[elem]
      = (load_ave.tl_lscale == 0
       ? load_ave.tl_avenrun.d[elem]
       : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale));
#endif /* OSF_ALPHA */

#if !defined (LDAV_DONE) && defined(LOAD_AVE_TYPE)

  /* UNIX-specific code -- read the average from /dev/kmem.  */

#define LDAV_PRIVILEGED		/* This code requires special installation.  */

  LOAD_AVE_TYPE load_ave[3];

  /* Get the address of LDAV_SYMBOL.  */
  if (offset == 0)
    {
#ifndef sgi
#ifndef NLIST_STRUCT
      strcpy (nl[0].n_name, LDAV_SYMBOL);
      strcpy (nl[1].n_name, "");
#else /* NLIST_STRUCT */
#ifdef NLIST_NAME_UNION
      nl[0].n_un.n_name = LDAV_SYMBOL;
      nl[1].n_un.n_name = 0;
#else /* not NLIST_NAME_UNION */
      nl[0].n_name = (char *) LDAV_SYMBOL;
      nl[1].n_name = 0;
#endif /* not NLIST_NAME_UNION */
#endif /* NLIST_STRUCT */

#ifndef SUNOS_5
      if (
#if !(defined (_AIX) && !defined (ps2))
	  nlist (KERNEL_FILE, nl)
#else  /* _AIX */
	  knlist (nl, 1, sizeof (nl[0]))
#endif
	  >= 0)
	  /* Omit "&& nl[0].n_type != 0 " -- it breaks on Sun386i.  */
	  {
#ifdef FIXUP_KERNEL_SYMBOL_ADDR
	    FIXUP_KERNEL_SYMBOL_ADDR (nl);
#endif
	    offset = nl[0].n_value;
	  }
#endif /* !SUNOS_5 */
#else  /* sgi */
	  int ldav_off;

	  ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN);
	  if (ldav_off != -1)
	  offset = (long) ldav_off & 0x7fffffff;
#endif /* sgi */
	}

  /* Make sure we have /dev/kmem open.  */
  if (!getloadavg_initialized)
    {
#ifndef SUNOS_5
      channel = open ("/dev/kmem", 0);
      if (channel >= 0)
	{
	  /* Set the channel to close on exec, so it does not
	     litter any child's descriptor table.  */
#ifdef FD_SETFD
#ifndef FD_CLOEXEC
#define FD_CLOEXEC 1
#endif
	  (void) fcntl (channel, F_SETFD, FD_CLOEXEC);
#endif
	  getloadavg_initialized = 1;
	}
#else /* SUNOS_5 */
      /* We pass 0 for the kernel, corefile, and swapfile names
	 to use the currently running kernel.  */
      kd = kvm_open (0, 0, 0, O_RDONLY, 0);
      if (kd != 0)
	{
	  /* nlist the currently running kernel.  */
	  kvm_nlist (kd, nl);
	  offset = nl[0].n_value;
	  getloadavg_initialized = 1;
	}
#endif /* SUNOS_5 */
    }

  /* If we can, get the load average values.  */
  if (offset && getloadavg_initialized)
    {
      /* Try to read the load.  */
#ifndef SUNOS_5
      if (lseek (channel, offset, 0) == -1L
	  || read (channel, (char *) load_ave, sizeof (load_ave))
	  != sizeof (load_ave))
	{
	  close (channel);
	  getloadavg_initialized = 0;
	}
#else  /* SUNOS_5 */
      if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave))
	  != sizeof (load_ave))
        {
          kvm_close (kd);
          getloadavg_initialized = 0;
	}
#endif /* SUNOS_5 */
    }

  if (offset == 0 || !getloadavg_initialized)
    return -1;

  if (nelem > 0)
    loadavg[elem++] = LDAV_CVT (load_ave[0]);
  if (nelem > 1)
    loadavg[elem++] = LDAV_CVT (load_ave[1]);
  if (nelem > 2)
    loadavg[elem++] = LDAV_CVT (load_ave[2]);

#define LDAV_DONE
#endif /* !LDAV_DONE && LOAD_AVE_TYPE */

  return elem;
}