Thursday, 24 May 2018

Signal handler using signal() commad

Signal handler using signal() commad


Declaration:

  • Following is the declaration for signal() function.
    • #include <signal.h>
    • typedef void (*sighandler_t)(int);
    • sighandler_t signal(int signum, sighandler_t handler)
    • other declare
      • void (*signal(int sig, void (*func)(int)))(int)


DESCRIPTION:

  •  signal() sets the disposition of the signal signum to handler, which is either SIG_IGN, SIG_DFL, or the address of a programmer-defined function (a "signal handler").
  • sig − This is the signal number to which a handling function is set. The following are few important standard signal numbers.

Return Value

  • This function returns the previous value of the signal handler, or SIG_ERR on error.

Program:

* Singal program by Velraj.K
   Check : http://velrajcoding.blogspot.in
*/

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <stdbool.h>

void sighandler(int);

int main()
{
    signal(SIGINT, sighandler);

    signal(SIGHUP, sighandler);
    while(1)
    {
        printf("Going to sleep for a second...\n");
        sleep(1);
    }
    return(0);
}
void sighandler(int signum)
{
    static int sighup = 0;

    printf("Caught signal %d, coming out...\n", signum);
    switch(signum)
    {
        case SIGHUP:
            printf("Vel instid eSIGUP.\n");
            if(sighup++ %2)
            {
                printf("Ignore the sigint \n");
                signal(SIGINT, SIG_IGN);
            }
            else
            {
                printf("set defalt to  int \n");
                signal(SIGINT, SIG_DFL);
            }
            break;
    }

//    exit(1);
}


Output:


   $./a.out
   Going to sleep for a second...
   Going to sleep for a second...
   Going to sleep for a second...
   Going to sleep for a second...
   ^CCaught signal 2, coming out...
  

Send the signal from Command prompt:
1. Need to know the signal number:
  • The signal number will be different for OS, as check in net they commonly mentioned SIGUSR1 value as 10 but in mips64 archetecture, we are getting SIGUSR1 value as 16.
  • To know the signal number, give "kill -l" command to get signal number:

EG: $ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGEMT       8) SIGFPE       9) SIGKILL     10) SIGBUS
11) SIGSEGV     12) SIGSYS      13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGUSR1     17) SIGUSR2  

  • To send signal use below:
  • kill -s 16 14517
     


Monday, 21 May 2018

Break statement on nested loop

Break statement on nested loop

  • When a break statement is encountered inside a loop, the loop is immediately terminated and the program control resumes at the next statement following the loop.
  • If you are using nested loops, the break statement will stop the execution of the innermost loop and start executing the next line of code after the block.

Program:

/* Break statement on nested loop */
#include <stdio.h>


int main()
{
    int count_1 = 0, count_2 = 0;

    while(1) {

        printf("Vel 1st while count = %d \n", count_1++);
        while(1) {
            printf("Vel Inside 2nd while count %d, 1st while = %d \n",count_2++, count_1);
            sleep(1);
            if(!(count_2 % 5)) {
                /* This break will be apply to this while loop only,
                   1st while loop still be live. */
                break;
            }
        }
        sleep(1);
    }

    return 0;
}

Output:

   sample$ ./a.out
   Vel 1st while count = 0
   Vel Inside 2nd while count 0, 1st while = 1
   Vel Inside 2nd while count 1, 1st while = 1
   Vel Inside 2nd while count 2, 1st while = 1
   Vel Inside 2nd while count 3, 1st while = 1
   Vel Inside 2nd while count 4, 1st while = 1
   Vel 1st while count = 1
   Vel Inside 2nd while count 5, 1st while = 2
   Vel Inside 2nd while count 6, 1st while = 2
   Vel Inside 2nd while count 7, 1st while = 2
   Vel Inside 2nd while count 8, 1st while = 2
   Vel Inside 2nd while count 9, 1st while = 2
   Vel 1st while count = 2
   Vel Inside 2nd while count 10, 1st while = 3
   Vel Inside 2nd while count 11, 1st while = 3
   Vel Inside 2nd while count 12, 1st while = 3
   Vel Inside 2nd while count 13, 1st while = 3
   Vel Inside 2nd while count 14, 1st while = 3
   Vel 1st while count = 3
   Vel Inside 2nd while count 15, 1st while = 4
   Vel Inside 2nd while count 16, 1st while = 4
   Vel Inside 2nd while count 17, 1st while = 4
   Vel Inside 2nd while count 18, 1st while = 4
   Vel Inside 2nd while count 19, 1st while = 4
   Vel 1st while count = 4
   Vel Inside 2nd while count 20, 1st while = 5
   Vel Inside 2nd while count 21, 1st while = 5
   Vel Inside 2nd while count 22, 1st while = 5

Friday, 18 May 2018

Checks if specified IP is multicast IP

Checks if specified IP is multicast IP


  • IPv4 multicast addresses are defined by the leading address bits of 1110, originating from the classful network design of the early Internet when this group of addresses was designated as Class D.
  • The Classless Inter-Domain Routing (CIDR) prefix of this group is 224.0.0.0/4. The group includes the addresses from 224.0.0.0 to 239.255.255.255.
  • The macro IN_MULTICAST is used to check the IP as multicast, this macro is impleted as part of Linux kernal.
  • The below file contain this macro.
    • https://github.com/torvalds/linux/blob/master/include/uapi/linux/in.h#L268
  • The userlevel application header file netinet/in.h & arpa/inet.h contain this macro definition.

Program:



#include <stdio.h>
#include <stdbool.h>   // For bool

// For inet_addr
#include <sys/socket.h>
#include <netinet/in.h>    // This contain the in_addr_t, & IN_MULTICAST macro
#include <arpa/inet.h>  // This also including  <netinet/in.h>

/*
  IN_MULTICAST macro is defined in Linux in.h file,
  Below is the definition
  */

//#define IN_CLASSD(a)            ((((long int) (a)) & 0xf0000000) == 0xe0000000)
//#define IN_MULTICAST(a)         IN_CLASSD(a)


bool isMulticastAddress(in_addr_t s_addr)
{
    //in_addr_t stored in network order
    uint32_t address = ntohl(s_addr);
    char *char_saddr = (char*) &s_addr;
    char *char_address = (char *) &address;

    printf("S-add value = %x %x %x %x address = %x %x %x %x \n", char_saddr[0], char_saddr[1], char_saddr[2], char_saddr[3],
                    char_address[0], char_address[1], char_address[2], char_address[3]);

    return (address & 0xF0000000) == 0xE0000000;
}

int main()
{
    int ret = 0;

    if (IN_MULTICAST(ntohl(inet_addr("239.4.4.4")))) {
        printf("239.4.4.4 is an multicast using IN_MULTICAST macro. \n");
    }
    else {
        printf("Not an multicast IP check using IN_MULTICAST macro. \n");
    }


    ret = isMulticastAddress(inet_addr("239.4.4.4"));
    if(ret) {
        printf("239.4.4.4 is an multicast using isMulticastAddress function. \n");
    }
    else {
        printf("Not an multicast IP check using isMulticastAddress function. \n");
    }

    ret = isMulticastAddress(inet_addr("224.4.4.4"));
    if(ret) {
        printf("224.4.4.4 is an multicast using isMulticastAddress function. \n");
    }
    else {
        printf("Not an multicast IP check using isMulticastAddress function. \n");
    }


}

Output:

sample$ ./a.out
239.4.4.4 is an multicast using IN_MULTICAST macro.
S-add value = ffffffef 4 4 4 address = 4 4 4 ffffffef
239.4.4.4 is an multicast using isMulticastAddress function.
S-add value = ffffffe0 4 4 4 address = 4 4 4 ffffffe0
224.4.4.4 is an multicast using isMulticastAddress function.


Refer: http://www.tcpipguide.com/free/t_IPMulticastAddressing.htm

Get the currently process priority & scheduling policy & priority, also change the priority

Get the currently process priority & scheduling policy & priority, also change the priority

API Description:

 #include <sched.h>
       int sched_get_priority_max(int policy);
       int sched_get_priority_min(int policy);
  • sched_get_priority_max() returns the maximum priority value that can be used with the scheduling algorithm identified by policy.
  • sched_get_priority_min() returns the minimum priority value that can be used with the scheduling algorithm identified by policy.

 #include <sched.h>

       int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param);
       int sched_getscheduler(pid_t pid);

  • The sched_setscheduler() system call sets both the scheduling policy and parameters for the thread whose ID is specified in pid.
  • If pid equals zero, the scheduling policy and parameters of the calling thread will be set.


#include <sys/time.h>
#include <sys/resource.h>
             int getpriority(int which, int who);
            int setpriority(int which, int who, int prio);
  • The scheduling priority of the process, process group, or user, as indicated by which and who is obtained with the getpriority() call and set with the setpriority() call.
  • The value which is one of PRIO_PROCESS, PRIO_PGRP, or PRIO_USER, and who is interpreted relative to which (a process identifier for PRIO_PROCESS, process group identifier for PRIO_PGRP, and a user ID for PRIO_USER).
  • A zero value for who denotes (respectively) the calling process, the process group of the calling process, or the real user ID of the calling process.

  • Prio is a value in the range -20 to 19 (but see the Notes below). The default priority is 0; lower priorities cause more favorable scheduling.

#include <sched.h>
      int sched_setparam(pid_t pid, const struct sched_param *param);
      int sched_getparam(pid_t pid, struct sched_param *param);

struct sched_param {
    ...
    int sched_priority;
    ...
};
  • sched_setparam() sets the scheduling parameters associated with the scheduling policy for the process identified by pid. If pid is zero, then the parameters of the calling process are set.


Program:


#include <stdio.h>
#include <sched.h>   // sched_getscheduler & set

/* For getpriority & setpriority */
#include <sys/time.h>
#include <sys/resource.h>

#include <errno.h>   // For errno
#include <stdlib.h>   // For exit
#include <string.h>  // for memset

const static int SCHED_POLICY_MAX = 3;
const char *sched_policies[] = {
    "SCHED_OTHER",
    "SCHED_FIFO",
    "SCHED_RR",
    "SCHED_BATCH"
};

int print_sched_type(pid_t pid)
{
    int policy = sched_getscheduler(pid);
    if (policy < 0) {
        perror("Syscall sched_getscheduler() had problems");
        return -1;
    }
    if (policy > SCHED_POLICY_MAX) {
        printf("Syscall sched_getscheduler() returned a policy number greater than allowed!\n");
        return -1;
    }
    printf("The current scheduling policy is: %s\n", sched_policies[policy]);
 
void print_process_prio(pid_t pid)
{
    /* Get the proirity of this process. This is the NON-REALTIME priority.
     *   http://linux.die.net/man/2/getpriority
     */
    /* This can return -1 as a legitimate value, so first clear errno
     * and make sure to check it after the call.
     */
    errno = 0;
    int this_prio = getpriority(PRIO_PROCESS, pid);

    if ((this_prio == -1) && (errno)) {
        perror("Syscall getpriority failed");
    } else {
        printf("Process priority is: %i\n", this_prio);
    }
}

void print_sched_priority(pid_t pid)
{
    /* Get and inspect the scheduling parameters.  This can contain realtime relevant
     * information if this process is operating with SCHED_FIFO
     */
    struct sched_param param;

    if (sched_getparam(pid, &param) < 0) {
        perror("Syscall sched_getparam barfed");
    } else {
        printf("The sched_param schedule priority is: %i\n", param.sched_priority);
    }
}

void hline(void)
{
    char str[82];
    memset(str, '-', 80);
    str[80] = '\n';
    str[81] = '\0';
    printf("%s", str);
}

int main(int argc, char *argv[])
{
    int policy = -1;

    /* Get the maximum schedule priority
http://linux.die.net/man/2/sched_get_priority_max
     */
    int max_prio_FIFO = sched_get_priority_max(SCHED_FIFO);
    int max_prio_RR = sched_get_priority_max(SCHED_RR);
    int max_prio_OTHER = sched_get_priority_max(SCHED_OTHER);

    printf("Scheduling Priority Maximums:\n"
            "    SCHED_FIFO: %i\n"
            "    SCHED_RR: %i\n"
            "    SCHED_OTHER: %i\n",
            max_prio_FIFO,
            max_prio_RR,
            max_prio_OTHER);

    /* Get the minimum schedule priorities for each process scheduling type
     *  http://linux.die.net/man/2/sched_get_priority_min
     */
    int min_prio_FIFO = sched_get_priority_min(SCHED_FIFO);
    int min_prio_RR = sched_get_priority_min(SCHED_RR);
    int min_prio_OTHER = sched_get_priority_min(SCHED_OTHER);
   printf("Scheduling Priority Minimums:\n"
            "    SCHED_FIFO: %i\n"
            "    SCHED_RR: %i\n"
            "    SCHED_OTHER: %i\n",
            min_prio_FIFO,
            min_prio_RR,
            min_prio_OTHER);

    print_process_prio(0);
    print_sched_priority(0);
    policy = print_sched_type(0);    // If we run on ubuntu getting default proces schedule is "Other"

    hline();


    /* Need to run from root user if we need to change the process priroty,
       otherwise it will thrown on error */
    printf("Attempting to switch process to SCHED_FIFO...\n");
    struct sched_param sp;
    memset(&sp, 0, sizeof(sp));
    sp.sched_priority = 50; /* This cannot be higher than max_prio_FIFO! */
    if (sched_setscheduler(0, SCHED_FIFO, &sp) < 0) {
        perror("Problem setting scheduling policy to SCHED_FIFO (probably need rtprio rule in /etc/security/limits.conf)");
        exit(1);
    }

    print_process_prio(0);
    print_sched_priority(0);
    print_sched_type(0);

    printf("\nTest completed successfully!\n");
}

Output without Root permission:

sample$ ./a.out
Scheduling Priority Maximums:
    SCHED_FIFO: 99
    SCHED_RR: 99
    SCHED_OTHER: 0
Scheduling Priority Minimums:
    SCHED_FIFO: 1
    SCHED_RR: 1
    SCHED_OTHER: 0
Process priority is: 0
The sched_param schedule priority is: 0
The current scheduling policy is: SCHED_OTHER
--------------------------------------------------------------------------------
Attempting to switch process to SCHED_FIFO...
Problem setting scheduling policy to SCHED_FIFO (probably need rtprio rule in /etc/security/limits.conf): Operation not permitted

Output with Root permission:

labuser@labuser-virtual-machine:~/velrajk/sample$ sudo ./a.out
[sudo] password for labuser:
Scheduling Priority Maximums:
    SCHED_FIFO: 99
    SCHED_RR: 99
    SCHED_OTHER: 0
Scheduling Priority Minimums:
    SCHED_FIFO: 1
    SCHED_RR: 1
    SCHED_OTHER: 0
Process priority is: 0
The sched_param schedule priority is: 0
The current scheduling policy is: SCHED_OTHER
--------------------------------------------------------------------------------
Attempting to switch process to SCHED_FIFO...
Process priority is: 0
The sched_param schedule priority is: 50
The current scheduling policy is: SCHED_FIFO

Test completed successfully!




Saturday, 12 May 2018

Bitwise Operator


Bit Operator


| – Bitwise OR
& – Bitwise AND
~ – One’s complement
^ – Bitwise XOR
<< – left shift
>> – right shift


Bitwise OR – |


   1010
   1100
   -------
OR 1110 
   -------
 

Bitwise AND – &


    1010
    1100
    -------
AND 1000   
    -------


One’s Complement operator – ~


       1001
NOT
      -------
       0110
      -------

 

Bitwise XOR – ^


     0101
     0110
     ------
XOR  0011
     ------


 

Left shift Operator – <<

int a=2<<1;

Position  7    6    5    4    3    2    1    0
Bits      0    0    0    0    0    0    1    0

after 1 time shift:

Position  7    6    5    4    3    2    1    0
Bits      0    0    0    0    0    1    0    0

 

Right shift Operator – >>

========================

int a=8>>1;

Position    7    6    5    4    3    2    1    0
Bits        0    0    0    0    1    0    0    0


after 1 right shift:

Position   7    6    5    4    3    2    1    0
Bits      0     0    0    0    0    1    0    0

 

Note on shifting signed and unsigned numbers

============================================

While performing shifting, if the operand is a signed value, then arithmetic shift will be used. If the type is unsigned, then logical shift will be used.

In case of arithmetic shift, the sign-bit ( MSB ) is preserved. Logical shift will not preserve the signed bit. Let’s see this via an example.


int main() {
    signed char a=-8;
    signed char b= a >> 1;
    printf("%d\n",b);
}


In the above code, we are right shifting -8 by 1. The result will be “-4”. Here arithmetic shift is applied since the operand is a signed value.




Now unsigned shift:

int main() {
    unsigned char a=-8;
    unsigned char b= a >> 1;
    printf("%d\n",b);
}


Note: Negative number are represented using 2’s complement of its positive equivalent.


2's compliment of +8 is
          8 = 0000 1000
1st complit = 1111 0111
2's compli  = 1111 1000

1111 1000

Right shifting by 1 yields, 0111 1100 ( 124 in decimal )

Hence we will get the positive 124 value:


 

Toggle a bit:

============
value = data ^ (1 << n)

Input data is 8
Bit needs to be toggled is 2.

   value = (0000 1000) ^ (0000 0001 << 2)
         = (0000 1000) ^ (0000 0100) => (0000 1100) = 12




 

Tricks:

********

Get the maximum integer

int maxInt = ~(1 << 31);
int maxInt = (1 << 31) - 1;
int maxInt = (1 << -1) - 1;

 

Get the minimum integer

int minInt = 1 << 31;
int minInt = 1 << -1;

 

Get the maximum long

long maxLong = ((long)1 << 127) - 1;

 

Multiplied by 2

n << 1; // n*2

 

Divided by 2

n >> 1; // n/2

 

Multiplied by the m-th power of 2

n << m;

 

Divided by the m-th power of 2

n >> m;

 

Check odd number

(n & 1) == 1;


Exchange two values

a ^= b;
b ^= a;
a ^= b;