Showing posts with label C basics. Show all posts
Showing posts with label C basics. Show all posts

Wednesday, 3 July 2019

How to compile 32 bit binary on 64 bit machine



GCC option to compile 32 bit binary on 64 bit machine:


Generate code for a 32-bit or 64-bit environment.
  • -m32 
    • sets "int", "long", and pointer types to 32 bits, and generates code that runs on any i386 system.
  • -m64
    •  sets "int" to 32 bits and "long" and pointer types to 64 bits, and generates code for the x86-64 architecture.
    • For Darwin only the -m64 option also turns off the -fno-pic and -mdynamic-no-pic options.
  • -mx32
    • sets "int", "long", and pointer types to 32 bits, and generates code for the x86-64 architecture.


Compile:

velrajk/sample$ gcc sizeof.c
velrajk/sample$ gcc -m32 sizeof.c -o 32_bit
velrajk/sample$

Output:

velrajk/sample$ ./32_bit
size of vel = 4 int= 4 float = 4double= 8 0 = 4 NULL = 4  "" = 1 int * = 4 unsigned long = 4 Unsigned int = 4
velrajk/sample$ ./a.out
size of vel = 4 int= 4 float = 4double= 8 0 = 4 NULL = 8  "" = 1 int * = 8 unsigned long = 8 Unsigned int = 4
velrajk/sample$


Wednesday, 26 June 2019

strtol - convert str to interger


strtol - Convert the number from string into interger

NAME

  • strtol, strtoll, strtoq - convert a string to a long integer

SYNOPSIS

       #include <stdlib.h>

       long int strtol(const char *nptr, char **endptr, int base);
       long long int strtoll(const char *nptr, char **endptr, int base);

       strtoll():
           _ISOC99_SOURCE
               || /* Glibc versions <= 2.19: */ _SVID_SOURCE || _BSD_SOURCE

DESCRIPTION  

  • The strtol() function converts the initial part of the string in nptr to a long integer value according to the given base.
  • If base is 2 then binary, if 8 then octal, if 10 then decimal & 16 for hexa decimal.
  • In bases above 10, the letter 'A' in either uppercase or lowercase represents 10, 'B' represents 11, and so forth, with 'Z' representing 35.
  • Checked in sample program, Hence If u give base as 20 then, f as 15, g as 16, h as 17... j as 19, k will throw an error.
  •  
  • If endptr is not NULL, strtol() stores the address of the first invalid character in *endptr.
  • If there were no digits at all, strtol() stores the original value of nptr in *endptr (and returns 0).

RETURN VALUE

  • The strtol() function returns the result of the conversion, unless the value would underflow or overflow.
  • If an underflow occurs, strtol() returns LONG_MIN.
  • If an overflow occurs, strtol() returns LONG_MAX.
  • In both cases, errno is set to ERANGE.

Note: Program should set errno to 0 before the call, after call check the errno.

Difference between atoi, strtol & sscanf :

atoi()
    Pro: Simple.
    Pro: Convert to an int.
    Pro: In the C standard library.
    Pro: Fast.
    Con: No error handling.
    Con: Handle neither hexadecimal nor octal.

atol()
    Pro: Simple.
    Pro: In the C standard library.
    Pro: Fast.
    Con: Converts to an long, not int which may differ in size.
    Con: No error handling.
    Con: Handle neither hexadecimal nor octal.

strtol()
    Pro: Simple.
    Pro: In the C standard library.
    Pro: Good error handling.
    Pro: Fast.
    Con: Convert to an long, not int which may differ in size.

strtoul()
    Pro: Simple.
    Pro: In the C standard library.
    Pro: Good error handling.
    Pro: Fast.
    ---: Appears to not complain about negative numbers.
    Con: Converts to an unsigned long, not int which may differ in size.

sscanf(..., "%i", ...)
    Pro: In the C standard library.
    Pro: Converts to int.
    ---: Middle-of-the-road complexity.
    Con: Slow.
    Con: OK error handling (overflow is not defined).
    #define BASE_DECIMAL             10
Eg: pid_count = (int)strtol(buf, NULL, BASE_DECIMAL);

Program:

/* strtol - convert str to interger by Velraj.K
 * Check : http://velrajcoding.blogspot.in
 */

#include <stdio.h>>
#include <errno.h>  // errno & ERANGE
#include <stdlib.h>  // strtol & LONG_MAX
#include <limits.h>  // LONG_MAX & LONG_MIN
#include <string.h>  // for strerror

enum {
    FAILED = -1,
    SUCCESS,
};

/*************************************************************************************
 * FUNCTION NAME: convert_str_to_int
 *
 * DESCRIPTION  : convert the string into interget value
 *
 * RETURNS      : None
 * RETURNS      : FAIL on failure,
 *                SUCCESS on successfull update.
 *************************************************************************************/
static int convert_str_to_int(char *str_val, unsigned int *conv_value, char **save_endptr)
{
    char *endptr = NULL;
    long int result = 0;

    if (!str_val || !conv_value) {
        printf("input string is NULL \n");
        return FAILED;
    }

   errno = 0;
    result = strtol(str_val, &endptr, 10);
    *conv_value = (unsigned int)result;
    if (((errno == ERANGE) && ((result == LONG_MAX) || (result == LONG_MIN))) ||
            ((errno != 0) && (result == 0))) {
        printf("Error: conversion %s(%d) \n", strerror(errno), errno);
        return FAILED;
    }

    /* Save the endptr string for any future usage, after conversion. */
    if (save_endptr) {
        *save_endptr = endptr;
        if ((*save_endptr) && (**save_endptr != '\0') &&
                (!isspace(**save_endptr))) {
            printf("End string of input value saved as:%s \n", *save_endptr);
        }
    }

    if (endptr == str_val) {
        printf("No digits were found \n");
        return FAILED;
    }


    return SUCCESS;
}

int main()
{
    int      value = 0;
    char     *endptr = NULL;
    char     str[32] = {0};

    while (1) {
        printf("Enter the number to convert strint to int   :   ");
//        scanf("%[^\t\n]s", str);
        fgets(str, sizeof(str), stdin);
        convert_str_to_int(str, &value, &endptr);
        /*
         * Check the endptr has any invalid trailing strings,
         * after strtol conversion.
         */
        if ((endptr) && (*endptr != '\0') && (!isspace(*endptr))) {
            printf("Error invalid string is present \n");
        } else {
            printf("Input value    :  %s", str);
            printf("Value after convert val to : %d\n",value);
        }
    }

        convert_str_to_int("5m", &value, &endptr);
    if ((endptr) && (*endptr != '\0') && (!isspace(*endptr))) {
        printf("Error invalid string is present for 5m \n");
    } else {
        printf("Value after conver 5m val : %d \n", value);
    }

    return 0;
}



Output: 

 velraj@virtual-machine:~/velrajk/sample$ ./a.out
Enter the number to convert strint to int   :   5
Input value    :  5
Value after convert val to : 5
Enter the number to convert strint to int   :   5m
End string of input value saved as:m

Error invalid string is present
Enter the number to convert strint to int   :   5
Input value    :  5
Value after convert val to : 5
Enter the number to convert strint to int   :   5    m
Input value    :  5    m
Value after convert val to : 5
Enter the number to convert strint to int   :   5 mnews
Input value    :  5 mnews
Value after convert val to : 5
Enter the number to convert strint to int   :   ^C
 

Friday, 7 June 2019

stat, fstat & lstat Usage & diff

Name

  • stat, fstat, lstat - get file status

Synopsis

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

  • int stat(const char *path, struct stat *buf);
  • int fstat(int fd, struct stat *buf);
  • int lstat(const char *path, struct stat *buf)

Description

  • These functions return information about a file.
  • No permissions are required for file, but-in the case of stat() and lstat() - execute (search) permission is required on all of the directories in path that lead to the file.

Def:

  • stat() stats the file pointed to by path and fills in buf.
  • lstat() is identical to stat(), except that if path is a symbolic link, then the link itself is stat-ed, not the file that it refers to.
  • fstat() is identical to stat(), except that the file to be stat-ed is specified by the file descriptor fd.

Difference:

  • lstat() - if pathname is a symbolic link, then it returns information about the link itself, not the file (target) that it refers to.
  • stat()  - if pathname is a symbolic link, then it returns information about the target file that it refers to.

Symbolic file behaviour while opening:

  • Even if we touch the symbalic file, the modified time for target fill only will get modified, symbolic file modified time will be remain same.
  • If we edit the file using symbolic link, then modified time for target will be get changed but not symbolic file.

  • All of these system calls return a stat structure, which contains the following fields:
    struct stat {
        dev_t     st_dev;     /* ID of device containing file */
        ino_t     st_ino;     /* inode number */
        mode_t    st_mode;    /* protection */
        nlink_t   st_nlink;   /* number of hard links */
        uid_t     st_uid;     /* user ID of owner */
        gid_t     st_gid;     /* group ID of owner */
        dev_t     st_rdev;    /* device ID (if special file) */
        off_t     st_size;    /* total size, in bytes */
        blksize_t st_blksize; /* blocksize for file system I/O */
        blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
        time_t    st_atime;   /* time of last access */
        time_t    st_mtime;   /* time of last modification */
        time_t    st_ctime;   /* time of last status change */
    };

st_mode field:

The following POSIX macros are defined to check the file type using the st_mode field:
    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

Return Value

On success, zero is returned. On error, -1 is returned, and errno is set appropriately.

Program:



/* Difference between stat & lstat  by Velraj.K
 * Check : http://velrajcoding.blogspot.in
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>         // For memset

/* Note:
 *     Even if we touch the symbalic file, the modified time for target fill only will get modified,
 *          symbolic file modified time will be remain same.
 *     If we edit the file using symbolic link, then modified time for target will be get changed but not symbolic file.
 *     Difference:
 *       lstat() - if pathname is a symbolic link, then it returns information about the link itself,
 *                     not the file (target) that it refers to.
 *       stat()  - if pathname is a symbolic link, then it returns information about the target file that it refers to.
 */

void hline(char ch)
{
    int i;

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

    return;
}

void stat_display(struct stat *sb, char *method)
{
    if (!sb || !method) {
        printf("Error stat details is NULL \n");
        return;
    }

    hline('*');
    printf("\n\t Retrieve the file stat details using %s API\n", method);
    printf("\n\t ------------------------------------------------\n");
    printf("File type:                ");

    switch (sb->st_mode & S_IFMT) {
        case S_IFBLK:  printf("block device\n");            break;
        case S_IFCHR:  printf("character device\n");        break;
        case S_IFDIR:  printf("directory\n");               break;
        case S_IFIFO:  printf("FIFO/pipe\n");               break;
        case S_IFLNK:  printf("symlink\n");                 break;
        case S_IFREG:  printf("regular file\n");            break;
        case S_IFSOCK: printf("socket\n");                  break;
        default:       printf("unknown?\n");                break;
    }

    printf("I-node number:            %ld\n", (long) sb->st_ino);

    printf("Mode:                     %lo (octal)\n",
            (unsigned long) sb->st_mode);

    printf("Link count:               %ld\n", (long) sb->st_nlink);
    printf("Ownership:                UID=%ld   GID=%ld\n",
            (long) sb->st_uid, (long) sb->st_gid);

    printf("Preferred I/O block size: %ld bytes\n",
            (long) sb->st_blksize);
    printf("File size:                %lld bytes\n",
            (long long) sb->st_size);
    printf("Blocks allocated:         %lld\n",
            (long long) sb->st_blocks);

    printf("Last status change:       %s", ctime(&sb->st_ctime));
    printf("Last file access:         %s", ctime(&sb->st_atime));
    printf("Last file modification:   %s", ctime(&sb->st_mtime));
    hline('*');


}

int main(int argc, char *argv[])
{
    struct stat sb = {0};

    if (argc != 2) {
        fprintf(stderr, "Usage: %s pathname\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    if (stat(argv[1], &sb) == -1) {
        perror("stat");
        exit(EXIT_FAILURE);
    }

    stat_display(&sb, "stat");
    memset(&sb, 0, sizeof(struct stat));
    if (lstat(argv[1], &sb) == -1) {
        perror("stat");
        exit(EXIT_FAILURE);
    }
    stat_display(&sb, "lstat");



   exit(EXIT_SUCCESS);
}

 

Output:

 labuser@labuser-virtual-machine:~/velrajk/sample$ touch ../temp/new_s
labuser@labuser-virtual-machine:~/velrajk/sample$ ./a.out ../temp/new_s
********************************************************************************

         Retrieve the file stat details using stat API

         ------------------------------------------------
File type:                regular file
I-node number:            1887181
Mode:                     100664 (octal)
Link count:               1
Ownership:                UID=1000   GID=1000
Preferred I/O block size: 4096 bytes
File size:                11 bytes
Blocks allocated:         8
Last status change:       Fri Jun  7 12:05:50 2019
Last file access:         Fri Jun  7 12:05:50 2019
Last file modification:   Fri Jun  7 12:05:50 2019
********************************************************************************
********************************************************************************

         Retrieve the file stat details using lstat API

         ------------------------------------------------
File type:                symlink
I-node number:            1963069
Mode:                     120777 (octal)
Link count:               1
Ownership:                UID=1000   GID=1000
Preferred I/O block size: 4096 bytes
File size:                3 bytes
Blocks allocated:         0
Last status change:       Thu Jun  6 19:45:36 2019
Last file access:         Thu Jun  6 19:45:38 2019
Last file modification:   Thu Jun  6 19:45:36 2019
********************************************************************************
labuser@labuser-virtual-machine:~/velrajk/sample$
labuser@labuser-virtual-machine:~/velrajk/sample$
labuser@labuser-virtual-machine:~/velrajk/sample$
labuser@labuser-virtual-machine:~/velrajk/sample$ date
Fri Jun  7 12:06:05 IST 2019
labuser@labuser-virtual-machine:~/velrajk/sample$

Monday, 3 June 2019

Skip the String or Char or int using format specifier %*

Format specifiers in C

  •  It is a way to tell the compiler what type of data is in a variable during taking input using scanf() or printing using printf().
    •  EG: %c, %d, %f, etc.
    • printf(char *format, arg1, arg2, …)

printing format:


  • A minus(-) sign tells left alignment.
  • A number after % specifies the minimum field width to be printed if the characters are less than the size of width the remaining space is filled with space and if it is greater than it printed as it is without truncation.
  • A period( . ) symbol seperate field width with the precision.
  •  %%    Prints % character

Program:

/* Skip the String or Char or int using format specifier %*  by Velraj.K
 * Check : http://velrajcoding.blogspot.in
 */

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

int main () {
    int day = 0, year = 0, ret;
    char weekday[20] = {0}, month[20] = {0}, dtm[100]= {0}, time[128] = {0}, meridiem[8] = {0};

    /*
     * The abbreviations am and pm derive from Latin:
     *   AM = Ante meridiem: Before noon
     *   PM = Post meridiem: After noon
     */
    strcpy( dtm, "Saturday March 25 1989 v1Hour before 10 AM" );
    //sscanf( dtm, "%s %*s %d  %d", weekday, month, &day, &year );
    /*
     * %*s  -> Skip the string
     * %*c  -> Skip the character
     * %*d  -> Skip the interger
     */
    ret = sscanf(dtm, "%s %*s %d  %d %*c %s %*s %*d %s", weekday, &day, &year, time, meridiem);



    printf("ret:%d Value: Day:<%d> Year:<%d> Week:<%s> Time:%s Meridiem:%s\n", ret, day, year, weekday, time, meridiem);
    printf("Velraj %n \n", &ret);

    return(0);
} 

Output: 

  /sample$ ./a.out ret:5 Value: Day:25 Year:1989 Week:saturday Time:1Hour Meridiem:AM

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

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 ****************

Friday, 21 December 2018

Sizeof format zu or u

Sizeof format zu or u



  • It is a compile time unary operator which can be used to compute the size of its operand.
  • The result of sizeof is of unsigned integral type which is usually denoted by size_t.
  • sizeof can be applied to any data-type, including primitive types such as integer and floating-point types, pointer types, or compound datatypes such as Structure, union etc.
  • It simply return amount of memory is allocated to that data types.

 

Program:


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

#include <stdio.h>
 

#define STRNAME "Velraj"

int main()
{
        printf("Vel size = %zu int= %zu float = %zu double= %zu 0 = %zu NULL = %zu  \"\" = %zu int * = %zu\n",
                sizeof("vel"), sizeof(int), sizeof(float), sizeof(double), sizeof(0), sizeof(NULL), sizeof(""), sizeof(int *));

        return 0;
}

Output:

   velrajk/sample$ ./a.out
   Vel size = 4 int= 4 float = 4 double= 8 0 = 4 NULL = 8  "" = 1 int * = 8

Thursday, 13 September 2018

count character, line & word in the file using c program

Note:
  •  For getchar should not use char datatype, because it may return EOF.
  • The value for EOF is -1

Program:

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

#define WORD_OUTSIDE 1   /* Word outside */
#define WORD_INSIDE  0   /* Word inside  */

int main(int argc, char *argv[])
{
        /* For getchar should not use char datatype, because it return EOF.
         * The value for EOF is . */
        int   ch = 0, nc = 0, nl = 0, nw = 0, word_in_out;
        FILE  *fp_input = NULL;

        if (argc <=1) {
                printf("Give file name in the command prompt while executing the commmand: \n\n");
                return 0;
        }

        fp_input = fopen(argv[1], "r");
        if (fp_input == NULL) {
                printf("Failed to open the file %d. \n\n", errno);

                perror("Error:");
                return 0;
        }

       word_in_out = WORD_OUTSIDE;
        while ((ch = fgetc(fp_input)) != EOF) {
                ++nc;
                if (ch == '\n') {
                        ++nl;
                }
                if ((ch == ' ') || (ch == '\n') || (ch == '\t')) {
                        word_in_out = WORD_OUTSIDE;
                } else if (word_in_out == WORD_OUTSIDE) {
                        ++nw;
                        word_in_out = WORD_INSIDE;
                }
        }

        printf("Total number of character = %d, Line = %d, word = %d \n",
                       nc, nl, nw);

        return 0;
}

Output:

velraj@velraj-HEC41:~/CProgram$ ./a.out new
Total number of character = 28, Line = 5, word = 7

Wednesday, 1 August 2018

Strncmp usage from working



SYNOPSIS

#include <string.h>
 int strncmp(const char *s1, const char *s2, size_t n);

Description
The C library function int strncmp(const char *str1, const char *str2, size_t n) compares at most the first n bytes of str1 and str2.

RETURN VALUE
       The strcmp() and strncmp() functions return an integer less than, equal to, or greater than zero if s1 (or the first n bytes thereof) is found, respectively,  to  be  less  than,  to
       match, or be greater than s2.

  • strncmp will be usefully only if the both strings are not null terminated, at that time only it will be useful to stop the comparison upto n.
  • if we are using strlen to calculate lenght to give on  n, then strncmp is not useful.
  • strncmp with strlen is as good as strcmp.
  • Right way to use strncmp is to check for max allowed lenght.  we can use max size macro used to declare the string.

Wednesday, 27 June 2018

Convert Error no(errno) into a string value

NAME

       strerror, strerror_r - return string describing error number

SYNOPSIS

 #include <string.h>
       char *strerror(int errnum);
       int strerror_r(int errnum, char *buf, size_t buflen);
                   /* XSI-compliant */
       char *strerror_r(int errnum, char *buf, size_t buflen);
                   /* GNU-specific */
   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
       The XSI-compliant version of strerror_r() is provided if:
       (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE
       Otherwise, the GNU-specific version is provided.
     

DESCRIPTION


  • The strerror() function returns a pointer to a string that describes the error code passed in the argument errnum.
    • For example, if errnum is EINVAL, the returned description will "Invalid argument".
  • This string must not be modified by the application, but may be modified by a subsequent call to strerror()
  • The  strerror_r()  function  is  similar to strerror(), but is thread safe. 

RETURN VALUE

    Return the appropriate error description string, or an "Unknown error nnn" message if the error number is unknown.

Program:

/* error number into an String value program by Velraj.K
   Check : http://velrajcoding.blogspot.in
  */


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

int main()
{
    FILE *fp;

    /* first rename if there is any file */
    rename("file.txt", "newfile.txt");

    /* now let's try to open same file */
    fp = fopen("file.txt", "r");
    if( fp == NULL ) {
        perror("Error: ");
        printf("velraj errno = %d value (%s)\n", errno, strerror(errno));
        return(-1);
    }
    fclose(fp);

    return(0);

}

Output:

sample$ ./a.out
Error: : No such file or directory
velraj errno = 2 value (No such file or directory)


Monday, 4 June 2018

typedef sample

  • typedef can use to give a type a new name. 
  • Following is an example to define a term Velraj for one-byte numbers −
    • typedef unsigned char Velraj;

Program:


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

#include <stdio.h>

#define MAC_BUF_LEN  6

/* This also can bee used to access the single field.
   Here there is no magic, just use unsigned char mac[6] replace with MacAddress mac */
typedef unsigned char MacAddress[MAC_BUF_LEN];

// This typedef used to access the single char filed in mac
typedef unsigned char MacAddress_access;

int main()
{
    MacAddress mac_2 =  {0x00,0x0c,0x29,0x44,0x11,0x33};         // This is corrent this is equivalent to unigned char mac[6]
    MacAddress_access mac[6] = {0x00,0x0c,0xFF,0x44,0x00,0xEE};   // This is wrong because this is equivalent to unsigned char mac[6][6]
    MacAddress *pmac= NULL;  // This is equilaent to unsigned char *mac[6]
//    pmac = &mac_2;

    printf("Size of tMacAddr mac_2 = %lu mac = %02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX  \n", sizeof(mac_2), mac_2[0], mac_2[1], mac_2[2], mac_2[3], mac_2[4], mac_2[5] );
    printf("Base address = %p address + 1 = %p addd +2 = %p \n", &mac_2, &mac_2[1], &mac_2[2]);
    printf("Pointer tMacAddr+1  = %p  pmac[1] Add = %p pmac[2] = %p \n", pmac+1, &pmac[1], &pmac[2]);

    printf("print the mac = %02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX \n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

    return 0;
}

Output:

sample$ ./a.out
Size of tMacAddr mac_2 = 6 mac = 00:0C:29:44:11:33
Base address = 0x7ffc47bce8d0 address + 1 = 0x7ffc47bce8d1 addd +2 = 0x7ffc47bce8d2
Pointer tMacAddr+1  = 0x6  pmac[1] Add = 0x6 pmac[2] = 0xc
print the mac = 00:0C:FF:44:00:EE

 

 

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