顯示具有 C 標籤的文章。 顯示所有文章
顯示具有 C 標籤的文章。 顯示所有文章

2018年8月8日 星期三

[FSM] The sample code of two dimension FSM


#include <stdio.h>
//Different state of ATM machine
typedef enum {
    Idle_State,
    Card_Inserted_State,
    Pin_Eentered_State,
    Option_Selected_State,
    Amount_Entered_State,
    last_State
} eSystemState;

//Different type events
typedef enum {
    Card_Insert_Event,
    Pin_Enter_Event,
    Option_Selection_Event,
    Amount_Enter_Event,
    Amount_Dispatch_Event,
    last_Event
} eSystemEvent;

//typedef of 2d array
typedef eSystemState (*const afEventHandler[last_State][last_Event])(void);

//typedef of function pointer
typedef eSystemState (*pfEventHandler)(void);

//function call to dispatch the amount and return the ideal state
eSystemState AmountDispatchHandler(void)
{
    return Idle_State;
}

//function call to Enter amount and return amount enetered state
eSystemState EnterAmountHandler(void)
{
    return Amount_Entered_State;
}

//function call to option select and return the option selected state
eSystemState OptionSelectionHandler(void)
{
    return Option_Selected_State;
}

//function call to enter the pin and return pin entered state
eSystemState EnterPinHandler(void)
{
    return Pin_Eentered_State;
}

//function call to processing track data and return card inserted state
eSystemState InsertCardHandler(void)
{
    return Card_Inserted_State;
}

eSystemEvent ReadEvent()
{

}

int main(int argc, char *argv[])
{
    eSystemState eNextState = Idle_State;
    eSystemEvent eNewEvent;
// Table to define valid states and event of finite state machine
    static afEventHandler StateMachine = {
  /* Idle_State: 0 */              [Idle_State]            =       {[Card_Insert_Event]= InsertCardHandler,NULL,NULL,NULL,NULL},
  /* Card_Inserted_State 1*/       [Card_Inserted_State]   =       {NULL,[Pin_Enter_Event] = EnterPinHandler,NULL,NULL,NULL },
  /* Pin_Eentered_State 2 */       [Pin_Eentered_State]    =       {NULL,NULL,[Option_Selection_Event] = OptionSelectionHandler,NULL,NULL},
  /* Option_Selected_State: 3 */   [Option_Selected_State] =       {NULL,NULL,NULL,[Amount_Enter_Event] = EnterAmountHandler,NULL},
  /* Amount_Entered_State 4 */     [Amount_Entered_State]  =       {NULL,NULL,NULL,NULL,[Amount_Dispatch_Event] = AmountDispatchHandler},
    };
    while(1) {
// assume api to read the next event
        eSystemEvent eNewEvent = ReadEvent();
        if( ( eNextState < last_State) && (eNewEvent < last_Event) && StateMachine[eNextState][eNewEvent]!= NULL) { //Check NULL pointer and array boundary
// function call as per the state and event and return the next state of the finite state machine
            eNextState = (*StateMachine[eNextState][eNewEvent])();
        } else {
//Invalid
        }
    }
    return 0;
}

Method 2
#include <stdio.h>
//Different state of ATM machine
typedef enum {
    Idle_State,
    Card_Inserted_State,
    Pin_Eentered_State,
    Option_Selected_State,
    Amount_Entered_State,
    last_State
} eSystemState;

//Different type events
typedef enum {
    Card_Insert_Event,
    Pin_Enter_Event,
    Option_Selection_Event,
    Amount_Enter_Event,
    Amount_Dispatch_Event,
    last_Event
} eSystemEvent;

//typedef of 2d array
typedef eSystemState (*const afEventHandler[last_State][last_Event])(void);

//typedef of function pointer
typedef eSystemState (*pfEventHandler)(void);

//function call to dispatch the amount and return the ideal state
eSystemState AmountDispatchHandler(void)
{
    return Idle_State;
}

//function call to Enter amount and return amount enetered state
eSystemState EnterAmountHandler(void)
{
    return Amount_Entered_State;
}

//function call to option select and return the option selected state
eSystemState OptionSelectionHandler(void)
{
    return Option_Selected_State;
}

//function call to enter the pin and return pin entered state
eSystemState EnterPinHandler(void)
{
    return Pin_Eentered_State;
}

//function call to processing track data and return card inserted state
eSystemState InsertCardHandler(void)
{
    return Card_Inserted_State;
}

eSystemEvent ReadEvent()
{
    /* [Hardware detection] User insert the card
     * if (Card Insert == True)
     *      return Card_Insert_Event;
     * 
     * [Hardware detection] User start to press button
     * else if (User press button == True)
     *      return Pin_Enter_Event;
     * */
}

// Table to define valid states and event of finite state machine
const static afEventHandler StateMachine = {
/* Idle_State: 0 */              {/*Card_Insert_Event*/ InsertCardHandler, /*Pin_Enter_Event*/ NULL,             /*Option_Selection_Event*/ NULL,                  /*Amount_Enter_Event*/ NULL,              /*Amount_Dispatch_Event*/ NULL},
/* Card_Inserted_State 1*/       {/*Card_Insert_Event*/ NULL,              /*Pin_Enter_Event*/ EnterPinHandler,  /*Option_Selection_Event*/ NULL,                  /*Amount_Enter_Event*/ NULL,              /*Amount_Dispatch_Event*/ NULL},
/* Pin_Eentered_State 2 */       {/*Card_Insert_Event*/ NULL,              /*Pin_Enter_Event*/ NULL,             /*Option_Selection_Event*/ OptionSelectionHandler,/*Amount_Enter_Event*/ NULL,              /*Amount_Dispatch_Event*/ NULL},
/* Option_Selected_State: 3 */   {/*Card_Insert_Event*/ NULL,              /*Pin_Enter_Event*/ NULL,             /*Option_Selection_Event*/ NULL,                  /*Amount_Enter_Event*/ EnterAmountHandler,/*Amount_Dispatch_Event*/ NULL},
/* Amount_Entered_State 4 */     {/*Card_Insert_Event*/ NULL,              /*Pin_Enter_Event*/ NULL,             /*Option_Selection_Event*/ NULL,                  /*Amount_Enter_Event*/ NULL,              /*Amount_Dispatch_Event*/ AmountDispatchHandler},
};

int main(int argc, char *argv[])
{
    eSystemState eNextState = Idle_State;
    eSystemEvent eNewEvent;

    while(1) {
// assume api to read the next event
        eSystemEvent eNewEvent = ReadEvent();
        if( ( eNextState < last_State) && (eNewEvent < last_Event) && StateMachine[eNextState][eNewEvent]!= NULL) { //Check NULL pointer and array boundary
// function call as per the state and event and return the next state of the finite state machine
            eNextState = (*StateMachine[eNextState][eNewEvent])();
        } else {
//Invalid
        }
    }
        
    return 0;
}

2018年4月17日 星期二

[C][pthread] How to use pthread

#include <stdio.h>
#include <pthread.h>
#include <time.h>

static struct timespec start, now;

/** @return in ms */
static double time_diff(struct timespec t1, struct timespec t2)
{
    struct timespec diff;
    if (t2.tv_nsec - t1.tv_nsec < 0) {
        diff.tv_sec  = t2.tv_sec - t1.tv_sec - 1;
        diff.tv_nsec = t2.tv_nsec - t1.tv_nsec + 1000000000;
    } else {
        diff.tv_sec  = t2.tv_sec - t1.tv_sec;
        diff.tv_nsec = t2.tv_nsec - t1.tv_nsec;
    }
    return (diff.tv_sec * 1000.0 + diff.tv_nsec / 1000000.0);
}

void *happy()
{
 printf("Happy\n");
 clock_gettime(CLOCK_REALTIME, &start);
 do {
  clock_gettime(CLOCK_REALTIME, &now);
  printf("time elapse = %lf\n",time_diff(start, now));
 } while(time_diff(start, now) <= 10000 /* 10000 ms*/);
}

void main()
{
 pthread_t id;
 int ret;
 
 printf("main - Start\n");
 ret = pthread_create(&id, NULL, (void *) happy, NULL);
 if(ret!=0) {
  printf ("Create pthread error!\n");
 }
 while (1);
 printf("main - End\n");
}

Why need to “while (1)” at main function.
Using pthread, main function like brain, and pthread like second arm when it creates a new thread. So if brain(main function) died, pthread died as well.

[C][Concept] some differences between fork() and pthread()

In C there are some differences however:

**fork()**

-   Purpose is to create a new process, which becomes the child process of the caller
    
-   Both processes will execute the next instruction following the fork() system call
    
-   Two identical copies of the computer's address space,code, and stack are created one for parent and child.
    

Thinking of the fork as it was a person; Forking causes a clone of your program (process), that is running the code it copied.

----------

**pthread_create()**

-   Purpose is to create a new thread in the program which is given the same process of the caller
    
-   Threads within the same process can communicate using shared memory. (Be careful!)
    
-   The second thread will share data,open files, signal handlers and signal dispositions, current working directory, user and group ID's. The new thread will get its own stack, thread ID, and registers though.
    

Continuing the analogy; your program (process) grows a second arm when it creates a new thread, connected to the same brain.

Ref:

2018年4月12日 星期四

[C] read value from file

#include <stdio.h>
#include <stdlib.h>

int GetCfgSettings(char *f)
{
    FILE *fp;
    char cmd[50]= {0};
    char ret[20]= {0};
    int vol = 0;

    strncpy(cmd, f, sizeof(cmd)-1);
    cmd[sizeof(cmd)-1] = '\0';
    fp = popen(cmd, "r");

    if (fp != NULL) {
        fgets(ret, sizeof(ret)-1, fp);
        ret[sizeof(ret)-1] = '\0';
        pclose(fp);

        vol = atoi(ret);
        return vol;
    } else
        return 0;
}

void main ()
{
    int a;
    a= GetCfgSettings("cat /tmp/a.txt");
    printf("a = %d",a);
}

/*
 * Execute this command.
 * if a.txt have 123 inside.
 *
 * ./a.out will show  a = 123
 *
 * */

2018年3月27日 星期二

[C][time] time function


#include<time.h>
/** Method 1 */ 
time_t timep;

time(&timep);
printf("[Debug] time: %s\n",ctime(&timep));



  static struct timespec start, now;
/** Method 2 */    

#include 
#include 

static struct timespec start, now;

/** @return in ms */
static double time_diff(struct timespec t1, struct timespec t2)
{
    struct timespec diff;
    if (t2.tv_nsec - t1.tv_nsec < 0) {
        diff.tv_sec  = t2.tv_sec - t1.tv_sec - 1;
        diff.tv_nsec = t2.tv_nsec - t1.tv_nsec + 1000000000;
    } else {
        diff.tv_sec  = t2.tv_sec - t1.tv_sec;
        diff.tv_nsec = t2.tv_nsec - t1.tv_nsec;
    }
    return (diff.tv_sec * 1000.0 + diff.tv_nsec / 1000000.0);
}


void main(void)
{
    clock_gettime(CLOCK_REALTIME, &start);
    printf("# signal Test\n");
    clock_gettime(CLOCK_REALTIME, &now);
    printf("# signal finish at (%lf) ms\n", time_diff(start, now));
}



2018年1月29日 星期一

[C] Finite State machine (FSM)


#include <stdio.h>

typedef struct {
    int st;
    int ev;
    int (*fn)(void);
} tTransition;

enum states { ST_ANY, ST_INIT, ST_ERROR, ST_TERM } current_state;
enum events { EV_ANY, EV_KEYPRESS, EV_MOUSEMOVE } new_event;

static int GotKey (void) {}
static int FsmError (void) {}

tTransition trans[] = {
    { ST_INIT, EV_KEYPRESS, &GotKey},
    { ST_ANY, EV_ANY, &FsmError}
};
#define TRANS_COUNT (sizeof(trans)/sizeof(*trans))

/* Return the next event to process - how this works depends on your
application. */

enum events GetNextEvent (void)
{
    printf("start new event \n");
    return EV_ANY;
}

void main (void)
{
 int i = 0;

 current_state = ST_INIT;
 while (current_state != ST_TERM) {
  new_event = GetNextEvent();
  for (i = 0; i < TRANS_COUNT; i++) {
   if ((current_state == trans[i].st) || (ST_ANY == trans[i].st)) {
    if ((new_event == trans[i].ev) || (EV_ANY == trans[i].ev)) {
     current_state = (trans[i].fn)();
     break;
    }
   }
  }
 }
}

Ref:

2018年1月19日 星期五

2017年5月11日 星期四

[C][example code] snmp get


Makefile
#
# Warning: you may need more libraries than are included here on the
# build line.  The agent frequently needs various libraries in order
# to compile pieces of it, but is OS dependent and we can't list all
# the combinations here.  Instead, look at the libraries that were
# used when linking the snmpd master agent and copy those to this
# file.
#

CC=gcc

OBJS1=snmpdemoapp.o
OBJS2=example-demon.o nstAgentSubagentObject.o
OBJS3=asyncapp.o
TARGETS=example-demon snmpdemoapp asyncapp

CFLAGS=-I. `net-snmp-config --cflags`
BUILDLIBS=`net-snmp-config --libs`
BUILDAGENTLIBS=`net-snmp-config --agent-libs`

# shared library flags (assumes gcc)
DLFLAGS=-fPIC -shared

all: $(TARGETS)

snmpdemoapp: $(OBJS1)
    $(CC) -o snmpdemoapp $(OBJS1) $(BUILDLIBS)

asyncapp: $(OBJS3)
    $(CC) -o asyncapp $(OBJS3) $(BUILDLIBS)

example-demon: $(OBJS2)
    $(CC) -o example-demon $(OBJS2)  $(BUILDAGENTLIBS)

clean:
    rm $(OBJS2) $(OBJS2) $(TARGETS)

nstAgentPluginObject.so: nstAgentPluginObject.c Makefile
    $(CC) $(CFLAGS) $(DLFLAGS) -c -o nstAgentPluginObject.o nstAgentPluginObject.c
    $(CC) $(CFLAGS) $(DLFLAGS) -o nstAgentPluginObject.so nstAgentPluginObject.o


C code
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <string.h>

/* change the word "define" to "undef" to try the (insecure) SNMPv1 version */
#define DEMO_USE_SNMP_VERSION_3

#ifdef DEMO_USE_SNMP_VERSION_3
const char *our_v3_passphrase = "The Net-SNMP Demo Password";
#endif

int main(int argc, char ** argv)
{
    netsnmp_session session, *ss;
    netsnmp_pdu *pdu;
    netsnmp_pdu *response;

    oid anOID[MAX_OID_LEN];
    size_t anOID_len;

    netsnmp_variable_list *vars;
    int status;
    int count=1;

    /*
     * Initialize the SNMP library
     */
    init_snmp("snmpdemoapp");

    /*
     * Initialize a "session" that defines who we're going to talk to
     */
    snmp_sess_init( &session );                   /* set up defaults */
    session.peername = strdup("test.net-snmp.org");  /* Remote IP Address */

    /* set up the authentication parameters for talking to the server */

#ifdef DEMO_USE_SNMP_VERSION_3

    /* Use SNMPv3 to talk to the experimental server */

    /* set the SNMP version number */
    session.version=SNMP_VERSION_3;

    /* set the SNMPv3 user name */
    session.securityName = strdup("MD5User");
    session.securityNameLen = strlen(session.securityName);

    /* set the security level to authenticated, but not encrypted */
    session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;

    /* set the authentication method to MD5 */
    session.securityAuthProto = usmHMACMD5AuthProtocol;
    session.securityAuthProtoLen = sizeof(usmHMACMD5AuthProtocol)/sizeof(oid);
    session.securityAuthKeyLen = USM_AUTH_KU_LEN;

    /* set the authentication key to a MD5 hashed version of our
       passphrase "The Net-SNMP Demo Password" (which must be at least 8
       characters long) */
    if (generate_Ku(session.securityAuthProto,
                    session.securityAuthProtoLen,
                    (u_char *) our_v3_passphrase, strlen(our_v3_passphrase),
                    session.securityAuthKey,
                    &session.securityAuthKeyLen) != SNMPERR_SUCCESS) {
        snmp_perror(argv[0]);
        snmp_log(LOG_ERR,
                 "Error generating Ku from authentication pass phrase. \n");
        exit(1);
    }

#else /* we'll use the insecure (but simplier) SNMPv1 */

    /* set the SNMP version number */
    session.version = SNMP_VERSION_1;

    /* set the SNMPv1 community name used for authentication */
    session.community = "demopublic";
    session.community_len = strlen(session.community);

#endif /* SNMPv1 */

    /*
     * Open the session
     */
    SOCK_STARTUP;
    ss = snmp_open(&session);                     /* establish the session */

    if (!ss) {
      snmp_sess_perror("ack", &session);
      SOCK_CLEANUP;
      exit(1);
    }

    /*
     * Create the PDU for the data for our request.
     *   1) We're going to GET the system.sysDescr.0 node.
     */
    pdu = snmp_pdu_create(SNMP_MSG_GET);
    anOID_len = MAX_OID_LEN;
    if (!snmp_parse_oid(".1.3.6.1.2.1.1.1.0", anOID, &anOID_len)) {
      snmp_perror(".1.3.6.1.2.1.1.1.0");
      SOCK_CLEANUP;
      exit(1);
    }
#if OTHER_METHODS
    /*
     *  These are alternatives to the 'snmp_parse_oid' call above,
     *    e.g. specifying the OID by name rather than numerically.
     */
    read_objid(".1.3.6.1.2.1.1.1.0", anOID, &anOID_len);
    get_node("sysDescr.0", anOID, &anOID_len);
    read_objid("system.sysDescr.0", anOID, &anOID_len);
#endif

    snmp_add_null_var(pdu, anOID, anOID_len);

    /*
     * Send the Request out.
     */
    status = snmp_synch_response(ss, pdu, &response);

    /*
     * Process the response.
     */
    if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
      /*
       * SUCCESS: Print the result variables
       */

      for(vars = response->variables; vars; vars = vars->next_variable)
        print_variable(vars->name, vars->name_length, vars);

      /* manipuate the information ourselves */
      for(vars = response->variables; vars; vars = vars->next_variable) {
        if (vars->type == ASN_OCTET_STR) {
      char *sp = (char *)malloc(1 + vars->val_len);
      memcpy(sp, vars->val.string, vars->val_len);
      sp[vars->val_len] = '\0';
          printf("value #%d is a string: %s\n", count++, sp);
      free(sp);
    }
        else
          printf("value #%d is NOT a string! Ack!\n", count++);
      }
    } else {
      /*
       * FAILURE: print what went wrong!
       */

      if (status == STAT_SUCCESS)
        fprintf(stderr, "Error in packet\nReason: %s\n",
                snmp_errstring(response->errstat));
      else if (status == STAT_TIMEOUT)
        fprintf(stderr, "Timeout: No response from %s.\n",
                session.peername);
      else
        snmp_sess_perror("snmpdemoapp", ss);

    }

    /*
     * Clean up:
     *  1) free the response.
     *  2) close the session.
     */
    if (response)
      snmp_free_pdu(response);
    snmp_close(ss);

    SOCK_CLEANUP;
    return (0);
} /* main() */


Compile command as following:
[happy@localhost 3]$ make snmpdemoapp
gcc -I. net-snmp-config --cflags -c -o snmpdemoapp.o snmpdemoapp.c
gcc -o snmpdemoapp snmpdemoapp.o net-snmp-config --libs


Execute command as following:
[happy@localhost 3]$ ./snmpdemoapp
SNMPv2-MIB::sysDescr.0 = STRING: test.net-snmp.org
value #1 is a string: test.net-snmp.org


Reference:

2017年3月1日 星期三

[C] file status in C

  void process(int fd, struct sockaddr_in *clientaddr){                                                                                                 
      printf("accept request, fd is %d, pid is %d\n", fd, getpid());                                                                                    
      http_request req;                                                                                                                                 
      parse_request(fd, &req);                                                                                                                          

      struct stat sbuf;                                                                                                                                 
      int status = 200, ffd = open(req.filename, O_RDONLY, 0);                                                                                          
      if(ffd <= 0){                                                                                                                                     
          status = 404;                                                                                                                                 
          char *msg = "File not found";                                                                                                                 
          client_error(fd, status, "Not found", msg);                                                                                                   
      } else {                                                                                                                                          
          fstat(ffd, &sbuf);                                                                                                                            
          if(S_ISREG(sbuf.st_mode)){                                                                                                                    
              if (req.end == 0){                                                                                                                        
                  req.end = sbuf.st_size;                                                                                                               
              }                                                                                                                                         
              if (req.offset > 0){                                                                                                                      
                  status = 206;                                                                                                                         
              }                                                                                                                                         
              serve_static(fd, ffd, &req, sbuf.st_size);                                                                                                
          } else if(S_ISDIR(sbuf.st_mode)){                                                                                                             
              status = 200;                                                                                                                             
              handle_directory_request(fd, ffd, req.filename);                                                                                          
          } else {                                                                                                                                      
              status = 400;                                                                                                                             
              char *msg = "Unknow Error";                                                                                                               
              client_error(fd, status, "Error", msg);                                                                                                   
          }                                                                                                                                             
          close(ffd);                                                                                                                                   
      }                                                                                                                                                 
      log_access(status, clientaddr, &req);                                                                                                             
  } 
       S_ISREG(m)  is it a regular file?

       S_ISDIR(m)  directory?

       S_ISCHR(m)  character device?

       S_ISBLK(m)  block device?

       S_ISFIFO(m) FIFO (named pipe)?

       S_ISLNK(m)  symbolic link?  (Not in POSIX.1-1996.)

       S_ISSOCK(m) socket?  (Not in POSIX.1-1996.)

Reference:

2017年2月28日 星期二

[C] Simple Program to List a Directory

#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>


int
main (void)
{
  DIR *dp;
  struct dirent *ep;

  dp = opendir ("./");
  if (dp != NULL)
    {
      while (ep = readdir (dp))
        puts (ep->d_name);
      (void) closedir (dp);
    }
  else
    perror ("Couldn't open the directory");

  return 0;
}

Result :
Print all file name which under the folder of “./”.

Reference:

2017年1月23日 星期一

[C] Return index of last non digit or -1 if it does not end with digits

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>

/* return index of last non digit or -1 if it does not end with digits */
int rindex_nondigit(char *name)
{
    int pos = 0;

    for(pos=strlen(name); pos>0; pos--)
    {
        printf("pos = %d, name[pos - 1] = %c \n", pos, name[pos-1]);
        if (!isdigit(name[pos-1]))
            return pos;
    }
    return 0;
}


int main()
{
    int position = 0;
    char a[] = "happy1";

    position = rindex_nondigit(a);
    printf("position = %d\n", position);
}



Result

pos = 6, name[pos - 1] = 1 
pos = 5, name[pos - 1] = y 
position = 5



Reference:

2017年1月4日 星期三

[C][Concept] malloc

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
{
    char *log;

    log = malloc(256);

    strcpy(log, "happy");
    printf("log = %s\n",log);
}

Result

log = happy

Compare

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
{
    char *log;

    strcpy(log, "happy");
    printf("log = %s\n",log);
}

Result

Segmentation fault (core dumped)

[C][Concept] sizeof

#include <string.h>
#include <stdio.h>

void load_buffer(char *buffer);

int main()
{
    char buffer[100]="\0";
    printf("buffer size: %d\n", sizeof(buffer));
    load_buffer(buffer);

    return 0;
}

void load_buffer(char *buffer)
{
    printf("sizeof(buffer): %d\n", sizeof(&buffer));
}

Result

buffer size: 100
sizeof(buffer): 8

Reference:

2016年12月3日 星期六

[C] Using ioctl to control socket to get ip address and netmask

#include <net/if.h>
#include <sys/ioctl.h>
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>

int main()
{
        int inet_sock;
        struct ifreq ifr;
        inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
        strcpy(ifr.ifr_name, "eth0");
        if (ioctl(inet_sock, SIOCGIFADDR, &ifr) < 0)
                perror("ioctl");
        printf("%s\n", inet_ntoa(((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr));

        if (ioctl(inet_sock, SIOCGIFNETMASK, &ifr) < 0) {
            perror("ioctl");
        }
        printf("%s\n", inet_ntoa(((struct sockaddr_in*)&(ifr.ifr_netmask))->sin_addr));
}


Reference:

2016年11月22日 星期二

[C] valgrind - debug memory

Valgrind is an instrumentation framework for building dynamic analysis tools.

Let download source code and use it.
Source Code download place

valgrind –leak-check=full ./

Reference:


Embedded System

Please refer the code at github - Valgrind

export VALGRIND_LIB=/lib/valgrind

Reference:

2016年9月19日 星期一