Chinaunix首页 | 论坛 | 博客
  • 博客访问: 664206
  • 博文数量: 156
  • 博客积分: 6010
  • 博客等级: 准将
  • 技术积分: 1201
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-05 20:08
文章分类

全部博文(156)

文章存档

2010年(13)

2008年(39)

2007年(104)

我的朋友

分类: LINUX

2007-07-19 00:31:28

conky_1.4.4源代码分析-1
Conky, a system monitor, based on torsmo
 
Conky,就是一个系统的监视器,因为最近在读kernel,自己的机器没有这个,所以想自己看看它怎么设计的。
 
按照分析linux下代码的惯例,首先看他的makefile
makefile.am
 

bin_PROGRAMS = conky

if BUILD_AUDACIOUS   //一个音乐播放器类似BMP
audacious = audacious.c audacious.h
endif

if BUILD_BMPX
bmpx = bmpx.c
endif

if BUILD_MPD
mpd = mpd.c libmpdclient.c
endif

if BUILD_XMMS2
xmms2 = xmms2.c
endif

if BUILD_LINUX   //我的系统就是linux
linux = linux.c top.c
PTHREAD_LIBS = -lpthread
endif

#if BUILD_SOLARIS
#solaris = solaris.c
#endif

if BUILD_FREEBSD
freebsd = freebsd.c
PTHREAD_LIBS = -pthread
endif

#if BUILD_NETBSD
#netbsd = netbsd.c
#endif

if BUILD_PORT_MONITORS  //还支持远程监视啊?
port_monitors = libtcp-portmon.h libtcp-portmon.c hash.h hash.c
endif

if BUILD_X11       //一般都是在X下吧
x11 = x11.c
endif

if BUILD_HDDTEMP    //这个是硬盘的温度监视
hddtemp = hddtemp.c
endif
//下面可以看出主要文件是 common.c conky.c conky.h fs.h mail.c remotec.c

//remotec.h remoted.c remoted.h
conky_SOURCES =         \
    $(audacious) \
    $(bmpx) \
    common.c         \
    conky.c \
    conky.h \
    $(freebsd) \
    fs.c             \
    $(hddtemp)        \
    $(linux)         \
    mail.c             \
    mixer.c         \
    $(mpd) \
    $(netbsd) \
    $(port_monitors) \
    $(solaris)         \
    remotec.c \
    remotec.h \
    remoted.c         \
    remoted.h         \
    $(x11) \
    $(xmms2)

AM_LDFLAGS = $(PTHREAD_LIBS) -lm

EXTRA_DIST =             \
    audacious.c        \
    audacious.h        \
    bmpx.c            \
    freebsd.c        \
    ftp.c \
    ftp.h \
    hash.c            \
    hash.h            \
    hddtemp.c        \
    linux.c            \
    libmpdclient.c \
    libmpdclient.h \
    libtcp-portmon.c    \
    libtcp-portmon.h    \
    mpd.c            \
    netbsd.c        \
    solaris.c         \
    top.h \
    x11.c \
    xmms2.c

下面就看看它的common.c
 

/*
 * Conky, a system monitor, based on torsmo
 *
 * This program is licensed under BSD license, read COPYING
 *
 * $Id: common.c 727 2006-11-05 00:23:18Z pkovacs $
 */


#include "conky.h"
#include "remoted.h"
#include "remotec.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <sys/time.h>

struct information info;

void update_uname()//得到OS版本信息

{
    uname(&info.uname_s);
}

double get_time()//获取时间

{
    struct timeval tv;
    gettimeofday(&tv, 0);
    return tv.tv_sec + (tv.tv_usec / 1000000.0);
}

FILE *open_file(const char *file, int *reported)//通用的open_file,内含出错代码,一个宏!

{
    FILE *fp = fopen(file, "r");
    if (!fp) {
        if (!reported || *reported == 0) {
            ERR("can't open %s: %s", file, strerror(errno));
            if (reported)
                *reported = 1;
        }
        return 0;
    }

    return fp;
}

void variable_substitute(const char *s, char *dest, unsigned int n)//读取变量

{
    while (*s && n > 1) {
        if (*s == '$') {
            s++;
            if (*s != '$') {
                char buf[256];
                const char *a, *var;
                unsigned int len;

                /* variable is either $foo or ${foo} */
                if (*s == '{') {
                    s++;
                    a = s;
                    while (*s && *s != '}')
                        s++;
                } else {
                    a = s;
                    while (*s && (isalnum((int) *s)
                         || *s == '_'))
                        s++;
                }

                /* copy variable to buffer and look it up */
                len = (s - a > 255) ? 255 : (s - a);
                strncpy(buf, a, len);
                buf[len] = '\0';

                if (*s == '}')
                    s++;

                var = getenv(buf);

                if (var) {
                    /* add var to dest */
                    len = strlen(var);
                    if (len >= n)
                        len = n - 1;
                    strncpy(dest, var, len);
                    dest += len;
                    n -= len;
                }
                continue;
            }
        }

        *dest++ = *s++;
        n--;
    }

    *dest = '\0';
}

/* network interface stuff *///网络接口部分


static struct net_stat netstats[16];

struct net_stat *get_net_stat(const char *dev)//获取网络信息

{
    unsigned int i;

    if (!dev)
        return 0;

    /* find interface stat */
    for (i = 0; i < 16; i++) {
        if (netstats[i].dev && strcmp(netstats[i].dev, dev) == 0)
            return &netstats[i];
    }

    /* wasn't found? add it */
    if (i == 16) {
        for (i = 0; i < 16; i++) {
            if (netstats[i].dev == 0) {
                netstats[i].dev = strdup(dev);
                return &netstats[i];
            }
        }
    }

    CRIT_ERR("too many interfaces used (limit is 16)");
    return 0;
}

void format_seconds(char *buf, unsigned int n, long t)//格式化 秒数

{
    if (t >= 24 * 60 * 60)    /* hours necessary when there are days? */
        snprintf(buf, n, "%ldd %ldh %ldm", t / 60 / 60 / 24,
             (t / 60 / 60) % 24, (t / 60) % 60);
    else if (t >= 60 * 60)
        snprintf(buf, n, "%ldh %ldm", (t / 60 / 60) % 24,
             (t / 60) % 60);
    else
        snprintf(buf, n, "%ldm %lds", t / 60, t % 60);
}

void format_seconds_short(char *buf, unsigned int n, long t)//

{
    if (t >= 24 * 60 * 60)
        snprintf(buf, n, "%ldd %ldh", t / 60 / 60 / 24,
             (t / 60 / 60) % 24);
    else if (t >= 60 * 60)
        snprintf(buf, n, "%ldh %ldm", (t / 60 / 60) % 24,
             (t / 60) % 60);
    else
        snprintf(buf, n, "%ldm", t / 60);
}

static double last_meminfo_update;//meminfo更新信息

static double last_fs_update;//fs更新信息


unsigned long long need_mask;

void update_stuff()//需要更新的部分

{
    unsigned int i;
    info.mask = 0;

    if (no_buffers)
        need_mask |= 1 << INFO_BUFFERS;

    /* clear speeds and up status in case device was removed and doesn't get
     updated */


    for (i = 0; i < 16; i++) {
        if (netstats[i].dev) {
            netstats[i].up = 0;
            netstats[i].recv_speed = 0.0;
            netstats[i].trans_speed = 0.0;
        }
    }

    prepare_update();
    /* client(); this is approximately where the client should be called */
#define NEED(a) ((need_mask & (1 << a)) && ((info.mask & (1 << a)) == 0))

    if (NEED(INFO_UPTIME))
        update_uptime();//更新时间


    if (NEED(INFO_PROCS))
        update_total_processes();//更新的总进程数


    if (NEED(INFO_RUN_PROCS))
        update_running_processes();//运行的进程


    if (NEED(INFO_CPU))
        update_cpu_usage();//cpu的使用率


    if (NEED(INFO_NET))
        update_net_stats();//网络的情况


    if (NEED(INFO_DISKIO))
        update_diskio();//diskio


    if (NEED(INFO_WIFI))
        update_wifi_stats();//无线部分


    if (NEED(INFO_MAIL))
        update_mail_count();//mail的情况




#if defined(__linux__)
    if (NEED(INFO_I8K))
        update_i8k();//linux需要这个??

#endif /* __linux__ */
    
#ifdef MPD
    if (NEED(INFO_MPD))
        update_mpd();//mpd就是Music Player Daemon for Linux allows remote access to music files and managing playlists

#endif

#ifdef XMMS2
    if (NEED(INFO_XMMS2))
        update_xmms2();//常用的播放器xmms?

#endif

#ifdef AUDACIOUS
    if (NEED(INFO_AUDACIOUS))
        update_audacious();//这个播放器我是没有用过

#endif

#ifdef BMPX
    if (NEED(INFO_BMPX))
                update_bmpx();//bmp吧,我现在就是使用的这个,在xmms的基础上使用gtk2的库开发的

#endif

    if (NEED(INFO_LOADAVG))
        update_load_average();//系统运行时间



    if ((NEED(INFO_MEM) || NEED(INFO_BUFFERS) || NEED(INFO_TOP)) &&
     current_update_time - last_meminfo_update > 6.9) {
        update_meminfo();
        if (no_buffers) {
            info.mem -= info.bufmem;
        }
        last_meminfo_update = current_update_time;
    }//这里就可以获取MEM的讯息了


    if (NEED(INFO_TOP))
        update_top();//top,^_^


    /* update_fs_stat() won't do anything if there aren't fs -things *///文件系统的显示

    if (NEED(INFO_FS) && current_update_time - last_fs_update > 12.9) {
        update_fs_stats();
        last_fs_update = current_update_time;
    }
#ifdef TCP_PORT_MONITOR
    if (NEED(INFO_TCP_PORT_MONITOR))//TCP PORT的显示

        update_tcp_port_monitor_collection( info.p_tcp_port_monitor_collection );
#endif
}

int round_to_int(float f)//浮点-->整型变量的转换

{
    int intval = (int)f;
    double delta = f - intval;
    if (!(delta < 0.5)) {
        ++intval;
    }

    return intval;
}

阅读(3446) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-02-24 21:02:58

我最近正准备在MID上开发一个类似于Conky的widget,这篇代码分析对我刚接触kernel不久的初学者,理解Conky代码帮助太大了,谢谢啊~~