Wednesday, 29 May 2019

Send an signal with an argument (integer value)

sigaction Definition

Name:

  •     sigaction, rt_sigaction - examine and change a signal action

Synopsis:

  • #include <signal.h>
  • int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

DESCRIPTION

  • The sigaction() system call is used to change the action taken by a process on receipt of a specific signal.
  • signum specifies the signal and can be any valid signal except SIGKILL and SIGSTOP.
  • If act is non-NULL, the new action for signal signum is installed from act.
  • If oldact is non-NULL, the previous action is saved in oldact.

  • The sigaction structure is defined as something like:
           struct sigaction {
               void     (*sa_handler)(int);
               void     (*sa_sigaction)(int, siginfo_t *, void *);
               sigset_t   sa_mask;
               int        sa_flags;
               void     (*sa_restorer)(void);
           };

Note: On some architectures a union is involved: do not assign to both sa_handler and sa_sigaction.

  • The sa_restorer field is not intended for application use.
  • If SA_SIGINFO is specified in sa_flags, then sa_sigaction (instead of sa_handler)
    sa_mask specifies a mask of signals which should be blocked
  • The siginfo_t data type is a structure with the following fields:
           siginfo_t {
               int      si_signo;     /* Signal number */
               int      si_errno;     /* An errno value */
               int      si_code;      /* Signal code */
               int      si_trapno;    /* Trap number that caused
                                         hardware-generated signal
                                         (unused on most architectures) */
               pid_t    si_pid;       /* Sending process ID */
               uid_t    si_uid;       /* Real user ID of sending process */
               int      si_status;    /* Exit value or signal */
               clock_t  si_utime;     /* User time consumed */
               clock_t  si_stime;     /* System time consumed */
               sigval_t si_value;     /* Signal value */
               int      si_int;       /* POSIX.1b signal */
               void    *si_ptr;       /* POSIX.1b signal */
               int      si_overrun;   /* Timer overrun count;
                                         POSIX.1b timers */
               int      si_timerid;   /* Timer ID; POSIX.1b timers */
               void    *si_addr;      /* Memory location which caused fault */
               long     si_band;      /* Band event (was int in
                                         glibc 2.3.2 and earlier) */
               int      si_fd;        /* File descriptor */
               short    si_addr_lsb;  /* Least significant bit of address
                                         (since Linux 2.6.32) */
               void    *si_lower;     /* Lower bound when address violation
                                         occurred (since Linux 3.19) */
               void    *si_upper;     /* Upper bound when address violation
                                         occurred (since Linux 3.19) */
               int      si_pkey;      /* Protection key on PTE that caused
                                         fault (since Linux 4.6) */
               void    *si_call_addr; /* Address of system call instruction
                                         (since Linux 3.5) */
               int      si_syscall;   /* Number of attempted system call
                                         (since Linux 3.5) */
               unsigned int si_arch;  /* Architecture of attempted system call
                                         (since Linux 3.5) */
           }

  • si_signo, si_errno and si_code are defined for all signals.
  • Signals sent with kill(2) and sigqueue(3) fill in si_pid and si_uid.
  • In addition, signals sent with sigqueue(3) fill in si_int and si_ptr with the values specified by the sender of the signal

The si_code field:

  •     The si_code field inside the siginfo_t argument that is passed to a SA_SIGINFO signal handler is a value (not a bit mask) indicating why this signal was sent.
  • The following values can be placed in si_code for a SIGILL signal:
           ILL_ILLOPC
                  Illegal opcode.

           ILL_ILLOPN
                  Illegal operand.

           ILL_ILLADR
                  Illegal addressing mode.

           ILL_ILLTRP
                  Illegal trap.

           ILL_PRVOPC
                  Privileged opcode.

           ILL_PRVREG
                  Privileged register.

           ILL_COPROC
                  Coprocessor error.

RETURN VALUE

  • sigaction() returns 0 on success; on error, -1 is returned, and set errno.

ERRORS        

  • EFAULT act or oldact points to memory which is not a valid part of the process address space.

sigqueue

Name

  • sigqueue - queue a signal and data to a process

SYNOPSIS   

  •      #include <signal.h>
  •     int sigqueue(pid_t pid, int sig, const union sigval value);

DESCRIPTION       

  • sigqueue() sends the signal specified in sig to the process whose PID is given in pid.
  • The value argument is used to specify an accompanying item of data (either an integer or a pointer value) to be sent with the signal, and has the following type:
           union sigval {
               int   sival_int;
               void *sival_ptr;
           };
  • If the receiving process has installed a handler for this signal using the SA_SIGINFO flag to sigaction(2), then it can obtain this data via the si_value field of the siginfo_t structure

RETURN VALUE

  • On success, sigqueue() returns 0, Otherwise, -1 is returned and set errno .

Program


/* Send an signal with an argument (integer value) by Velraj.K
 * Check : http://velrajcoding.blogspot.in
 */

#include <stdio.h>
#include <stdlib.h>        // For exit()
#include <string.h>       // For memset()
#include <unistd.h>      // For fork() & sleep()
#include <sys/wait.h>      // For sig_atomic_t, siginfo_t, sigaction, SA_SIGINFO, SIGUSR1, SIGUSR2, sigqueue(), wait()
#include <assert.h>        // For assert()

static volatile sig_atomic_t got_value = 0;

void sig_handler(int sig, siginfo_t *info, void *x)
{
    pid_t pid = 0;

    pid = getpid();
    /* info->si_value.sival_int contains the integer value receive from sender */
    switch (info->si_value.sival_int) {
        case 1:
            printf("Vel Child:%d, received Signal with arg value as 1 sig num = %d SIG_USR1:%d SIG_USR2:%d \n", pid, sig, SIGUSR1, SIGUSR2);
            break;
        case 2:
            printf("Vel Child:%d, received Signal with arg value as 2 sig num = %d \n", pid, sig);
            break;
        default:
            printf("Invalid value \n");
            break;
    }
    ++got_value;

    return;
}


int main()
{
    struct sigaction act = {0};
    int ret;
    int status = 0;
    pid_t pid = -1;
    union sigval send_arg = {0};

    act.sa_flags = SA_SIGINFO;
    act.sa_sigaction = sig_handler;

    /* Install hangler for singal */
    ret = sigaction(SIGUSR1, &act, NULL);
    assert(ret == 0);

    ret = sigaction(SIGUSR2, &act, NULL);
    assert(ret == 0);

    /* Create child process & send the signal from parent to Child */
    pid = fork();
    /*
     * On success, parent process get child PID,
     * Child process get pid as 0
     */
    if (-1 == pid) {
        exit(1);
    } else if (0 == pid) {
        /* Child process */
        while (2 != got_value) {
            sleep(1);
        }
        exit(0);
    } else {
        /* Parent process */
        /* Send signal along with value 1 */
        send_arg.sival_int = 1;
        printf("Vel Parent:%d send SIGUSR2 with arg value as 1 to the Child:%d \n", getpid(), pid);
        sigqueue(pid, SIGUSR2, send_arg);

        /* Send signal along with value 2 */
        send_arg.sival_int = 2;
        printf("Vel Parent:%d send SIGUSR1 with arg value as 2 to the Child:%d \n", getpid(), pid);
        sigqueue(pid, SIGUSR1, send_arg);
        wait(&status);
        printf("Vel Parent:%d  -->  Status return by Child:%d \n", getpid(), status);
    }

    return 0;
}

 

Output:

 Vel Parent:10474 send SIGUSR2 with arg value as 1 to the Child:10475
Vel Parent:10474 send SIGUSR1 with arg value as 2 to the Child:10475
Vel Child:10475, received Signal with arg value as 1 sig num = 12 SIG_USR1:10 SIG_USR2:12
Vel Child:10475, received Signal with arg value as 2 sig num = 10
Vel Parent:10474  -->  Status return by Child:0



Reference:

  • http://man7.org/linux/man-pages/man2/sigaction.2.html
  • http://man7.org/linux/man-pages/man3/sigqueue.3.html

Tuesday, 30 April 2019

Simcllist linked list open source library sorting example program

Simcllist linked list open source library sorting example program


  • Sorting will sort the master list, it won't have any separate list for sort.
  • Simclist not support the single data place in two list, like one list as master and another list will be sorted one.
  • EG for 1 node to be a member of 2 list:
    •  linux list.h or bsd's queue.h it is possible to have one node be a member of two lists
    • Thus one list is sorted by time and the other list is sorted by something else, like MAC or an order that matches the dpi data.

Program:




/* Simclist sorting by Velraj.K
 * Check : http://velrajcoding.blogspot.in
 */


#include 
#include 
#include 

Monday, 29 April 2019

Simcllist linked list open source library Introduction & example program

Simcllist linked list open source library Introduction & example program


  • SimCList is a high quality C (C++ embeddable) library for handling lists.
  • SimCList is available for free, under restrictions imposed by the BSD license.
  • Need to explore below thread safe mechanism:
  • The SimCList library is thread safe, meaning that many threads can run SimCList operators on different lists concurrently without hurt
Memory:
  • SimClist free only the containter memory, suppose if you use strucute value & allocate memory for that structure then you need to take care of that memory, hence we have to store that allocated memory in one place & have to free after delete the container.
  • Or you have to get first API to get memory & then delete first API to delete and then free the memory, so that we don't need to store allocated memory.
  • Best way is allow SimClist to allocate memory by setting list_attributes_copy() API with size of strucute function pointer, so that SimClist will allocate memory for container & data also, while deleting, SimcList will delete the data & container memory.
API & Description:
  • list_init              -> Initialize the global list variable
  • list_attributes_seeker -> Intall the search function pointer for list_seek
  • list_attributes_copy   -> Intall function pointer to get the size of data (strucute) so that SimcList allocate memory for this data.
  • list_insert_at         -> Insert the data into the corresponding place 0-> to insert first
  • list_seek              -> Used to search the data using the keyword, list_attributes_seeker() installed the function to search the keyword.
  • list_size              -> Get the total number of node in the list.
  • list_get_at            -> Get the node from the list in particular position , 0 -> get first.
To display:
  •   list_iterator_start   -> starting an iteration "session"
  •   In while loop:
    • list_iterator_hasnext -> Use this in while loop for check , tell whether more values available
    • list_iterator_next    -> Get the node from the list
  •   list_iterator_stop  -> stop the iteration "session". After while must call this otherwise, next time it will not start from first, face issue,
To delete & check:
  • list_delete_at      -> Delete the node from the list in particular position, 0-> delete first
  • list_empty          -> Check list is empty, if empty return 1 otherwise return 0
  • list_clear          -> Delete all the node in the list
  • list_destroy        -> It will destroy the compelete list, need to call list_init if we need to use the list again.
License:
  • SimCList is BSD-licensed, so you can simply its whole source code into your application.
 
Program:
* Simcllist linked list example by Velraj.K
 * Check : http://velrajcoding.blogspot.in
 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>   /* for srandom() */
#include "../simclist.h"

//#define N       100000
#define N       10
#define LEN     12

struct foo_s {
    int a, b;
    char c[LEN];
};

//#define VEL_DYNAMIC_MEM

int seeker(const void  *el, const void *indicator) {
    if (((struct foo_s *)el)->a == *(int *)indicator)
        return 1;
    return 0;
}

/* This will used to inform list to copy the data for this size */
size_t mymeter(const void *el) {
    return (sizeof(struct foo_s));
}

void display_list(list_t *list)
{
    struct foo_s *temp2 = NULL;

    printf("Displaying the list \n");

    list_iterator_start(list);        /* starting an iteration "session" */
    while (list_iterator_hasnext(list)) { /* tell whether more values available */
        temp2 = list_iterator_next(list);
        printf("%d\n", temp2->a);
    }
    list_iterator_stop(list);         /* stop the iteration "session" */

    return;
}

void insert_list(list_t *list, int num)
{
    int i =0;
    struct foo_s el;

#if defined VEL_DYNAMIC_MEM
    struct foo_s *temp = NULL;
#endif
    for (i = 0; i < num; i++) {
#if defined VEL_DYNAMIC_MEM
        /* Should not allocate memory for data, because if we didn't give the
           then it will free only the containers not the element data */
        temp = malloc(sizeof(struct foo_s));
        temp->a = i;
        temp->b = 3*i;
        snprintf(temp->c, LEN, "%d-%d", temp->a, temp->b);
        list_insert_at(list, temp, i);
        if (i == 100) {
            printf("Vel memory at i = 100 is = %p\n", temp);
        }
#else
        el.a = i;
        el.b = 3*i;
        snprintf(el.c, LEN, "%d-%d", el.a, el.b);
        list_insert_at(list, & el, i);
#endif
    }
}

void line(char ch)
{
    int i = 0;

    for (i = 0; i < 80; printf("%c", ch), i++);

    printf("\n");

    return;
}

int main()
{
    list_t l;

    struct foo_s el, *new = NULL;
    struct foo_s *temp2 = NULL;
    int i = 0, j = 0;

#if defined VEL_DYNAMIC_MEM
    struct foo_s *temp = NULL;
#endif


    line('*');
    printf("Vel starting Size of list_t = %zu \n", sizeof(list_t));
    list_init(& l);
    list_attributes_seeker(&l, seeker);
#if defined VEL_DYNAMIC_MEM
    printf("Vel Using the dynamic memory allocation for node \n");
#else
    printf("Vel Allow list to allocation memory for node \n");
    /* To copy data install function to get the size */
    list_attributes_copy(&l, mymeter, 1);
#endif

    insert_list(&l, N);
   srandom(time(NULL));

    j = 5;
    /* it retrun the node with same our dynamic memory */
    new = (struct foo_s *)list_seek(&l, &j);
    if (new) {
        printf("Vel list_seek found node with key as 5 = %d Addres is = %p \n", new->a, new);
    }

    line('*');
    for (i = 0; i < N/4; i++) {
        j = random() % list_size(&l);
        el = *(struct foo_s *)list_seek(&l, &j);
        if (el.a != j) {
            printf("KO: %d retrieved %d\n", j, el.a);
            return 1;
        }
    }
    /* Return element if found otherwise return NULL */
    temp2 = (struct foo_s *)list_get_at(&l, 0);
    if (temp2) {
        printf("First elemet is a = %d, Addr = %p list size = %d\n", temp2->a, temp2, list_size(&l));
    } else {
        printf("Element not found \n");
    }

    line('*');
    display_list(&l);
    line('*');
    printf("Deleting the 2 node from the staring of the list \n");
    list_delete_at(&l, 0);
    list_delete_at(&l, 0);

    temp2 = (struct foo_s *)list_get_at(&l, 0);
    if (temp2) {
        /*
         * list_size(const list_t *restrict l):
         *     Description: Inspect the number of elements in the list.
         *     Input :  l       list to operate
         *     Returns: number of elements currently held by the list
         *     Vel: This is not looping all the element to find the number of element,
         *          just return l->numels value, it contain the total no. of element.
         */

        printf("First elemet is a = %d, Addr = %p list size = %d \n", temp2->a, temp2, list_size(&l));
    } else {
        printf("Element not found on 2nd get \n");
    }

    line('*');
    display_list(&l);
    line('*');

    printf("list_empty output %d list_size:%d \n", list_empty(&l), list_size(&l));


    /*
     * list_empty(const list_t *restrict l):
     *     Description : inspect whether the list is empty.
     *     Input       : l list to operate
     *     Returns     : 0 iff the list is not empty, if 1 then the list is empty(That is no element in the list)
     */
    if (list_empty(&l) == 0) {
        display_list(&l);
        /* After clear we can able to insert the node */
        list_clear(&l);
        insert_list(&l, 1);
        printf("Tryign to insert \n");
        line('*');
        display_list(&l);
        line('*');

        list_destroy(&l);
        printf("Destroying the item and the list \n");
        /* Below insert is wrong becasue we deleted the string
         * Valgrind thrown an following error:
         *    Invalid write of size 8
         */
       // insert_list(&l, 1);
//      printf("Tryign to insert \n");
    } else {
        /* Even the item is empty need to destroy the list to release all the internal using memory
         * At the time of initialization(list_init) it will allocate memory for internal purpose,
         * we should clear that memory when clear the list
         */
        list_destroy(&l);
        printf("Destroying only the list \n");
    }

    printf("list_empty output = %d \n", list_empty(&l));
    return 0;
}

/*
 * list_append(list_t *restrict l, const void *data):
 *     Description : append data at the end of the list.
 *     Input       : l list to operate & data   pointer to user data to append
 *     Returns     : 1 for success. < 0 for failure.
 *     Vel         : It won't do loop to find the last, It use the list_findpos to find the last
 *                       This function split the give position into 4 quarter, for last they start from end to decrease.
 *                       Our case append end will start on end only, so first check in for loop itself getting the data.
 */




Output:
labuser@labuser-virtual-machine:~/image/software/simclist-1.5/regrtest$ valgrind ./a.out
==13116== Memcheck, a memory error detector
==13116== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==13116== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==13116== Command: ./a.out
==13116==
********************************************************************************
Vel starting Size of list_t = 120
Vel Allow list to allocation memory for node
Vel list_seek found node with key as 5 = 5 Addres is = 0x5406590
********************************************************************************
First elemet is a = 0, Addr = 0x54061d0 list size = 10
********************************************************************************
Displaying the list
0
1
2
3
4
5
6
7
8
9
********************************************************************************
Deleting the 2 node from the staring of the list
First elemet is a = 2, Addr = 0x5406350 list size = 8
********************************************************************************
Displaying the list
2
3
4
5
6
7
8
9
********************************************************************************
list_empty output 0 list_size:8
Displaying the list
2
3
4
5
6
7
8
9
Tryign to insert
********************************************************************************
Displaying the list
0
********************************************************************************
Destroying the item and the list
list_empty output = 1
==13116==
==13116== HEAP SUMMARY:
==13116==     in use at exit: 0 bytes in 0 blocks
==13116==   total heap usage: 24 allocs, 24 frees, 548 bytes allocated
==13116==
==13116== All heap blocks were freed -- no leaks are possible
==13116==
==13116== For counts of detected and suppressed errors, rerun with: -v
==13116== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
labuser@labuser-virtual-machine:~/image/software/simclist-1.5/regrtest$
labuser@labuser-virtual-machine:~/image/software/simclist-1.5/regrtest$

Scenario 2: compiled with allocate memory dynamic and found the memory leak:

labuser@labuser-virtual-machine:~/image/software/simclist-1.5/regrtest$ vi vel_seeker_add_del.c
labuser@labuser-virtual-machine:~/image/software/simclist-1.5/regrtest$ gcc vel_seeker_add_del.c -DVEL_DYNAMIC_MEM -lsimclist
labuser@labuser-virtual-machine:~/image/software/simclist-1.5/regrtest$ valgrind ./a.out
==13626== Memcheck, a memory error detector
==13626== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==13626== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==13626== Command: ./a.out
==13626==
********************************************************************************
Vel starting Size of list_t = 120
Vel Using the dynamic memory allocation for node
Vel list_seek found node with key as 5 = 5 Addres is = 0x5406530
********************************************************************************
First elemet is a = 0, Addr = 0x5406170 list size = 10
********************************************************************************
Displaying the list
0
1
2
3
4
5
6
7
8
9
********************************************************************************
Deleting the 2 node from the staring of the list
First elemet is a = 2, Addr = 0x54062f0 list size = 8
********************************************************************************
Displaying the list
2
3
4
5
6
7
8
9
********************************************************************************
list_empty output 0 list_size:8
Displaying the list
2
3
4
5
6
7
8
9
Tryign to insert
********************************************************************************
Displaying the list
0
********************************************************************************
Destroying the item and the list
list_empty output = 1
==13626==
==13626== HEAP SUMMARY:
==13626==     in use at exit: 220 bytes in 11 blocks
==13626==   total heap usage: 24 allocs, 13 frees, 548 bytes allocated
==13626==
==13626== LEAK SUMMARY:
==13626==    definitely lost: 220 bytes in 11 blocks
==13626==    indirectly lost: 0 bytes in 0 blocks
==13626==      possibly lost: 0 bytes in 0 blocks
==13626==    still reachable: 0 bytes in 0 blocks
==13626==         suppressed: 0 bytes in 0 blocks
==13626== Rerun with --leak-check=full to see details of leaked memory
==13626==
==13626== For counts of detected and suppressed errors, rerun with: -v
==13626== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Before restart read below reference:
http://mij.oltrelinux.com/devel/simclist/sneakpeakapi.html
http://mij.oltrelinux.com/devel/simclist/



Friday, 19 April 2019

How to check the return value of sscanf

Check SScanf return value:


int sscanf(const char *str, const char *format, ...);

Description:

sscanf() reads its input from the character string pointed to by str
  1. sscanf return number of variable written into the buffer, so that we can check retun value with number of variable return
  2. we could not do the same in snprint, because it return the number buffer writting, 
      Example : Suppose write (%s,%s, "Vel", "kutralam"), then sscanf return 2 since 2 variable is written, but snprintf return 11 because it return number of character written

hh modifier:


As for h, but the next pointer is a pointer to a signed char or unsigned char.
This hh modifier is used to print the mac address(octal)

Return:

  Return the number of input items successfully matched and assigned.
  Which can be fewer than provided for, or even zero in the event of an early matching failure.


Program:


/* Sscanf return value checker by Velraj.K
 * Check : http://velrajcoding.blogspot.in
 */


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

int main()
{
    int ret = 0;
    unsigned char mac_addr[6] = {0};
    char *mac_value_buf = NULL;
    unsigned int int_value[6];
    int count = 0;
    char str[256] = {0};
//    uint32_t new;

    do {
    if (count == 0) {
        mac_value_buf = "000C2956BAF5,1,2,3,4,5,6";
    } else {
        mac_value_buf = "000C2956:BAF5,1,2,3,4,5";
    }
    count++;
    printf("\n\n\t\t ************* Mac buff value = %s Start ****************\n", mac_value_buf);

    /* Here using 04d, this is not needed */
    ret = sscanf(mac_value_buf, "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx,%04d,%04d,%04d,%04d,%04d,%04d",
            &mac_addr[0], &mac_addr[1],
            &mac_addr[2], &mac_addr[3],
            &mac_addr[4], &mac_addr[5],
            &int_value[0], &int_value[1],
            &int_value[2], &int_value[3],
            &int_value[4], &int_value[5]);
    /*
     * Reading 12 variable, so sscanf return 12 then all the values are read successfully,
     * and no error, otherwise error in reading
     */

    if (ret != 12) {
        printf("Error in retrieve the data from buffer mac_value_buf = %s \n", mac_value_buf);
    } else {
        printf("sscanf ret = %d dev inf = %d inf[5] = %d \n", ret, int_value[0], int_value[5]);
    }

     memset(int_value, 0, sizeof(int_value));

     /* Here using %d, this is enough */
     ret = sscanf(mac_value_buf, "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx,%d,%d,%d,%d,%d,%d",
             &mac_addr[0], &mac_addr[1], &mac_addr[2], &mac_addr[3], &mac_addr[4], &mac_addr[5], &int_value[0],
             &int_value[1], &int_value[2], &int_value[3], &int_value[4], &int_value[5]);

     printf("sscanf to skip ret = %d dev inf = %d inf[5] = %d errno = %d \n", ret, int_value[0], int_value[5], errno);

     /*
      * Here trying to skip the mac & start read from comma, but sscanf is not working this module,
      * it will fail and won't retrieve any value.
      */
     ret = sscanf(mac_value_buf, ",%u,%u,%u,%u,%u,%u",
//             &mac_addr[0], &mac_addr[1], &mac_addr[2], &mac_addr[3], &mac_addr[4], &mac_addr[5], &int_value[0],
             &int_value[0],
             &int_value[1], &int_value[2], &int_value[3], &int_value[4], &int_value[5]);
     printf("sscanf to skip ret = %d dev inf = %d inf[5] = %d errno = %d \n", ret, int_value[0], int_value[5], errno);


     /* snprintf return number of bytes read not an number variable so could not add if check */
     ret = snprintf(str, sizeof(str), "%02X:%02X:%02X:%02X:%02X:%02X,%04d,%04d,%04d,%04d,%04d,%04d",
            mac_addr[0], mac_addr[1],
            mac_addr[2], mac_addr[3],
            mac_addr[4], mac_addr[5],
            int_value[0], int_value[1],
            int_value[2], int_value[3],
            int_value[4], int_value[5]);
    /*
      * we could not check 12 with snprintf because snprintf calculate number bytes is writing,
      * not a number variable is writing, here value change from 45 to 50 based on number of digit in dev_info
      */
     printf("snprintf ret = %d \n", ret);
     printf("\t\t************* Mac buff value = %s END ****************\n", mac_value_buf);

    } while (count < 2);


     return 0;
}

Output:

 sample$ ./a.out
                 ************* Mac buff value = 000C2956BAF5,1,2,3,4,5,6 Start ****************
sscanf ret = 12 dev inf = 1 inf[5] = 6
sscanf to skip ret = 12 dev inf = 1 inf[5] = 6 errno = 0
sscanf to skip ret = 0 dev inf = 1 inf[5] = 6 errno = 0
snprintf ret = 47
                ************* Mac buff value = 000C2956BAF5,1,2,3,4,5,6 END ****************


                 ************* Mac buff value = 000C2956:BAF5,1,2,3,4,5 Start ****************
Error in retrieve the data from buffer mac_value_buf = 000C2956:BAF5,1,2,3,4,5
sscanf to skip ret = 4 dev inf = 0 inf[5] = 0 errno = 0
sscanf to skip ret = 0 dev inf = 0 inf[5] = 0 errno = 0
snprintf ret = 47
                ************* Mac buff value = 000C2956:BAF5,1,2,3,4,5 END ****************

Sunday, 24 February 2019

Difference between uint32_t vs unsigned int

Difference between uint32_t vs unsigned int



  • uint32_t is defined in stdint.h header file, so we have to include this header file if we want to use uint32_t
  • It is guaranteed to be a 32-bit unsigned integer
  • unsigned int
    •  Like int, unsigned int typically is an integer that is fast to manipulate for the current architecture
    • so it's to be used when a "normal", fast integer is required.
    •  For example, on a 16 bit-processor unsigned int will typically be 16 bits wide, while uint32_t will have to be 32 bits wide.


Program:

/* Difference between uint32_t vs unsigned int by Velraj.K
 * Check : http://velrajcoding.blogspot.in
 */


#include <stdio.h>
#include <stdint.h>  /* For uint32_t */

int main()
{

        /* It is guaranteed to be a 32-bit unsigned integer */
        uint32_t int32_val = 0;
        /* Like int, unsigned int typically is an integer that is fast to manipulate for the current architecture.
         * so it's to be used when a "normal", fast integer is required.
         * For example, on a 16 bit-processor unsigned int will typically be 16 bits wide, while uint32_t
         * will have to be 32 bits wide.
         */
        unsigned int uint_val = 0;

        printf("Vel value int32_val:size <%u:%zu> uint_val:size <%u:%zu> \n", int32_val, sizeof(int32_val), uint_val, sizeof(uint_val));

        return 0;
}



Output:

velraj@velraj-H310M-H:~/velraj/cLang$ ./a.out
Vel value int32_val:size <0:4> uint_val:size <0:4>