The following are more examples of all three approaches (static, shared, and dynamically loaded libraries). File libhello.c is a trivial library, with libhello.h as its header. File demo_use.c is a trivial caller of the library. This is followed by commented scripts (script_static and script_dynamic) showing how to use the library as a static and shared library. This is followed by demo_dynamic.c and script_dynamic, which show how to use the shared library as a dynamically loaded library.
File libhello.c
/* libhello.c - demonstrate library use. */
#include <stdio.h>
void hello(void) {
printf("Hello, library world.\n");
}
//------------------------------------------------------------------
File libhello.h
/* libhello.h - demonstrate library use. */
void hello(void);
//------------------------------------------------------------------
File demo_use.c
/* demo_use.c -- demonstrate direct use of the "hello" routine */
#include <libhello.h>
int main(void) {
hello();
return 0;
}
//------------------------------------------------------------------
File script_static
#!/bin/sh
# Static library demo
# Create static library's object file, libhello-static.o.
# I'm using the name libhello-static to clearly
# differentiate the static library from the
# dynamic library examples, but you don't need to use
# "-static" in the names of your
# object files or static libraries.
gcc -Wall -g -c -o libhello-static.o libhello.c
//------------------------------------------------------------------
# Create static library.
ar rcs libhello-static.a libhello-static.o
//------------------------------------------------------------------
# At this point we could just copy libhello-static.a
# somewhere else to use it.
# For demo purposes, we'll just keep the library
# in the current directory.
# Compile demo_use program file.
gcc -Wall -g -c demo_use.c -o demo_use.o
//------------------------------------------------------------------
# Create demo_use program; -L. causes "." to be searched during
# creation of the program. Note that this command causes
# the relevant object file in libhello-static.a to be
# incorporated into file demo_use_static.
gcc -g -o demo_use_static demo_use.o -L. -lhello-static
//------------------------------------------------------------------
# Execute the program.
./demo_use_static
//------------------------------------------------------------------
//------------------------------------------------------------------
File script_shared
#!/bin/sh
# Shared library demo
# Create shared library's object file, libhello.o.
gcc -fPIC -Wall -g -c libhello.c
//------------------------------------------------------------------
# Create shared library.
# Use -lc to link it against C library, since libhello
# depends on the C library.
gcc -g -shared -Wl,-soname,libhello.so.0 \
-o libhello.so.0.0 libhello.o -lc
//------------------------------------------------------------------
# At this point we could just copy libhello.so.0.0 into
# some directory, say /usr/local/lib.
# Now we need to call ldconfig to fix up the symbolic links.
# Set up the soname. We could just execute:
# ln -sf libhello.so.0.0 libhello.so.0
# but let's let ldconfig figure it out.
/sbin/ldconfig -n .
//------------------------------------------------------------------
# Set up the linker name.
# In a more sophisticated setting, we'd need to make
# sure that if there was an existing linker name,
# and if so, check if it should stay or not.
ln -sf libhello.so.0 libhello.so
//------------------------------------------------------------------
# Compile demo_use program file.
gcc -Wall -g -c demo_use.c -o demo_use.o
//------------------------------------------------------------------
# Create program demo_use.
# The -L. causes "." to be searched during creation
# of the program; note that this does NOT mean that "."
# will be searched when the program is executed.
gcc -g -o demo_use demo_use.o -L. -lhello
//------------------------------------------------------------------
# Execute the program. Note that we need to tell the program
# where the shared library is, using LD_LIBRARY_PATH.
LD_LIBRARY_PATH="." ./demo_use
//------------------------------------------------------------------
//------------------------------------------------------------------
File demo_dynamic.c
/* demo_dynamic.c -- demonstrate dynamic loading and
use of the "hello" routine */
/* Need dlfcn.h for the routines to
dynamically load libraries */
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
/* Note that we don't have to include "libhello.h".
However, we do need to specify something related;
we need to specify a type that will hold the value
we're going to get from dlsym(). */
/* The type "simple_demo_function" describes a function that
takes no arguments, and returns no value: */
typedef void (*simple_demo_function)(void);
int main(void) {
const char *error;
void *module;
simple_demo_function demo_function;
/* Load dynamically loaded library */
module = dlopen("libhello.so", RTLD_LAZY);
if (!module) {
fprintf(stderr, "Couldn't open libhello.so: %s\n",
dlerror());
exit(1);
}
/* Get symbol */
dlerror();
demo_function = dlsym(module, "hello");
if ((error = dlerror())) {
fprintf(stderr, "Couldn't find hello: %s\n", error);
exit(1);
}
/* Now call the function in the DL library */
(*demo_function)();
/* All done, close things cleanly */
dlclose(module);
return 0;
}
//------------------------------------------------------------------
File script_dynamic
#!/bin/sh
# Dynamically loaded library demo
# Presume that libhello.so and friends have
# been created (see dynamic example).
# Compile demo_dynamic program file into an object file.
gcc -Wall -g -c demo_dynamic.c
//------------------------------------------------------------------
# Create program demo_use.
# Note that we don't have to tell it where to search for DL libraries,
# since the only special library this program uses won't be
# loaded until after the program starts up.
# However, we DO need the option -ldl to include the library
# that loads the DL libraries.
gcc -g -o demo_dynamic demo_dynamic.o -ldl
//------------------------------------------------------------------
# Execute the program. Note that we need to tell the
# program where get the dynamically loaded library,
# using LD_LIBRARY_PATH.
LD_LIBRARY_PATH="." ./demo_dynamic
//------------------------------------------------------------------
Showing posts with label C Code. Show all posts
Showing posts with label C Code. Show all posts
Monday, December 28, 2009
Monday, December 21, 2009
UDP Listener/Receiver with libevent
UDP Listener/Receiver with libevent
Timer with lib event
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// The program listens on multiple udp sockets simultaneously
// and calling the event on them.
// Date : 26 - Nov -2009
// Author: Prakhar Dubey (prakharprakhar@gmail.com)
// Compile: g++ event_test.c -o event_test -levent
// Execture: ./event_test 0 10
// Listen on 10 udp ports starting from 6000 to 6009.
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#define UDP_PORT 6000
#include <iostream>
#include <event.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
int g_count = 0;
struct timeval stTv;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// TIMER FUNCTION
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
void timer_function(int x, short int y, void *pargs)
{
printf("nn**********Count is %dnn",g_count);
g_count = 0 ;
event_add((struct event*)pargs,&stTv);
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Event Function
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
void func_for_eve1(int x, short int y, void *pargs)
{
unsigned int unFromAddrLen;
int nByte = 0;
char aReqBuffer[512];
struct sockaddr_in stFromAddr;
unFromAddrLen = sizeof(stFromAddr);
if ((nByte = recvfrom(x, aReqBuffer, sizeof(aReqBuffer), 0,
(struct sockaddr *)&stFromAddr, &unFromAddrLen)) == -1)
{
printf("error occured while receivingn");
}
//printf("Function called buffer is %sn",aReqBuffer);
g_count++;
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// MAIN
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
int main(int argc, char **argv)
{
struct event_base *base ;
struct event g_Timer;
int val1,val2;
if(argc == 3)
{
val1 = atoi(argv[1]);
val2 = atoi(argv[2]);
printf("Value is %d %dn",val1,val2);
}
else return 0;
struct event g_eve[val2-val1];
int udpsock_fd[val2-val1];
struct sockaddr_in stAddr[val2-val1];
base = event_init();
for(int i=0; i< val2-val1 ; i++)
{
if ((udpsock_fd[i] = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
printf("ERROR - unable to create socket:n");
exit(-1);
}
//Start : Set flags in non-blocking mode
int nReqFlags = fcntl(udpsock_fd[i], F_GETFL, 0);
if (nReqFlags< 0)
{
printf("ERROR - cannot set socket options");
}
if (fcntl(udpsock_fd[i], F_SETFL, nReqFlags | O_NONBLOCK) < 0)
{
printf("ERROR - cannot set socket options");
}
// End: Set flags in non-blocking mode
memset(&stAddr[i], 0, sizeof(struct sockaddr_in));
//stAddr.sin_addr.s_addr = inet_addr("192.168.64.1555552");
stAddr[i].sin_addr.s_addr = INADDR_ANY; //listening on local ip
stAddr[i].sin_port = htons(UDP_PORT+i+val1);
stAddr[i].sin_family = AF_INET;
int nOptVal = 1;
if (setsockopt(udpsock_fd[i], SOL_SOCKET, SO_REUSEADDR,
(const void *)&nOptVal, sizeof(nOptVal)))
{
printf("ERROR - socketOptions: Error at Setsockopt");
}
if (bind(udpsock_fd[i], (struct sockaddr *)&stAddr[i], sizeof(stAddr[i])) != 0)
{
printf("Error: Unable to bind the default IP n");
exit(-1);
}
event_set(&g_eve[i], udpsock_fd[i], EV_READ | EV_PERSIST, func_for_eve1, &g_eve[i]);
event_add(&g_eve[i], NULL);
}
/////////////TIMER START///////////////////////////////////
stTv.tv_sec = 3;
stTv.tv_usec = 0;
event_set(&g_Timer, -1, EV_TIMEOUT , timer_function, &g_Timer);
event_add(&g_Timer, &stTv);
////////////TIMER END/////////////////////////////////////
event_base_dispatch(base);
return 0;
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Timer with lib event
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// The program listens on multiple udp sockets simultaneously
// and calling the event on them.
// Date : 26 - Nov -2009
// Author: Prakhar Dubey (prakharprakhar@gmail.com)
// Compile: g++ event_test.c -o event_test -levent
// Execture: ./event_test 0 10
// Listen on 10 udp ports starting from 6000 to 6009.
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#define UDP_PORT 6000
#include <iostream>
#include <event.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
int g_count = 0;
struct timeval stTv;
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// TIMER FUNCTION
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
void timer_function(int x, short int y, void *pargs)
{
printf("nn**********Count is %dnn",g_count);
g_count = 0 ;
event_add((struct event*)pargs,&stTv);
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Event Function
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
void func_for_eve1(int x, short int y, void *pargs)
{
unsigned int unFromAddrLen;
int nByte = 0;
char aReqBuffer[512];
struct sockaddr_in stFromAddr;
unFromAddrLen = sizeof(stFromAddr);
if ((nByte = recvfrom(x, aReqBuffer, sizeof(aReqBuffer), 0,
(struct sockaddr *)&stFromAddr, &unFromAddrLen)) == -1)
{
printf("error occured while receivingn");
}
//printf("Function called buffer is %sn",aReqBuffer);
g_count++;
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// MAIN
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
int main(int argc, char **argv)
{
struct event_base *base ;
struct event g_Timer;
int val1,val2;
if(argc == 3)
{
val1 = atoi(argv[1]);
val2 = atoi(argv[2]);
printf("Value is %d %dn",val1,val2);
}
else return 0;
struct event g_eve[val2-val1];
int udpsock_fd[val2-val1];
struct sockaddr_in stAddr[val2-val1];
base = event_init();
for(int i=0; i< val2-val1 ; i++)
{
if ((udpsock_fd[i] = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
printf("ERROR - unable to create socket:n");
exit(-1);
}
//Start : Set flags in non-blocking mode
int nReqFlags = fcntl(udpsock_fd[i], F_GETFL, 0);
if (nReqFlags< 0)
{
printf("ERROR - cannot set socket options");
}
if (fcntl(udpsock_fd[i], F_SETFL, nReqFlags | O_NONBLOCK) < 0)
{
printf("ERROR - cannot set socket options");
}
// End: Set flags in non-blocking mode
memset(&stAddr[i], 0, sizeof(struct sockaddr_in));
//stAddr.sin_addr.s_addr = inet_addr("192.168.64.1555552");
stAddr[i].sin_addr.s_addr = INADDR_ANY; //listening on local ip
stAddr[i].sin_port = htons(UDP_PORT+i+val1);
stAddr[i].sin_family = AF_INET;
int nOptVal = 1;
if (setsockopt(udpsock_fd[i], SOL_SOCKET, SO_REUSEADDR,
(const void *)&nOptVal, sizeof(nOptVal)))
{
printf("ERROR - socketOptions: Error at Setsockopt");
}
if (bind(udpsock_fd[i], (struct sockaddr *)&stAddr[i], sizeof(stAddr[i])) != 0)
{
printf("Error: Unable to bind the default IP n");
exit(-1);
}
event_set(&g_eve[i], udpsock_fd[i], EV_READ | EV_PERSIST, func_for_eve1, &g_eve[i]);
event_add(&g_eve[i], NULL);
}
/////////////TIMER START///////////////////////////////////
stTv.tv_sec = 3;
stTv.tv_usec = 0;
event_set(&g_Timer, -1, EV_TIMEOUT , timer_function, &g_Timer);
event_add(&g_Timer, &stTv);
////////////TIMER END/////////////////////////////////////
event_base_dispatch(base);
return 0;
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UDP Sender C Program
A Program which sends udp packet to a defined port PORT.
Set SRV_IP of the receiving server,
Number of Packets = NPACK * 1000 * 1000
#define SRV_IP "127.0.0.1"
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h>
#define BUFLEN 512
#define NPACK 10
#define PORT 6000
void diep(char *s)
{
perror(s);
exit(1);
}
int main(void)
{
struct sockaddr_in si_other;
long int j;
int fd, slen=sizeof(si_other);
char buf[BUFLEN];
int i;
{
if ((fd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
diep("socket");
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
if (inet_aton(SRV_IP, &si_other.sin_addr)==0)
{
fprintf(stderr, "inet_aton() failedn");
exit(1);
}
}
for (j=0; j<NPACK * 1000 * 1000; j++)
{
sprintf(buf, "512 length string you can type here anything this is so and so packetn");
if (sendto(fd, buf, BUFLEN, 0, &si_other, slen)==-1)
diep("sendto()");
}
close(fd);
return 0;
}
Set SRV_IP of the receiving server,
Number of Packets = NPACK * 1000 * 1000
#define SRV_IP "127.0.0.1"
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h>
#define BUFLEN 512
#define NPACK 10
#define PORT 6000
void diep(char *s)
{
perror(s);
exit(1);
}
int main(void)
{
struct sockaddr_in si_other;
long int j;
int fd, slen=sizeof(si_other);
char buf[BUFLEN];
int i;
{
if ((fd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
diep("socket");
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
if (inet_aton(SRV_IP, &si_other.sin_addr)==0)
{
fprintf(stderr, "inet_aton() failedn");
exit(1);
}
}
for (j=0; j<NPACK * 1000 * 1000; j++)
{
sprintf(buf, "512 length string you can type here anything this is so and so packetn");
if (sendto(fd, buf, BUFLEN, 0, &si_other, slen)==-1)
diep("sendto()");
}
close(fd);
return 0;
}
sscanf with expression
Using expression with sscanf
int main()
{
char rangestr = "10.32.125.224 - 220.12.32.52";
char ip1[16], ip2[16];
retval = sscanf(rangestr, "%[^'-'] - %s", ip1,ip2);
printf ("return calue = %d ip1 = %s, ip2 = %s",retval,ip1,ip2);
return 0;
}
%[^'-'] = From '^' start read till '-' character
int main()
{
char rangestr = "10.32.125.224 - 220.12.32.52";
char ip1[16], ip2[16];
retval = sscanf(rangestr, "%[^'-'] - %s", ip1,ip2);
printf ("return calue = %d ip1 = %s, ip2 = %s",retval,ip1,ip2);
return 0;
}
%[^'-'] = From '^' start read till '-' character
Syslog Example
Start logging with syslog, system logging utility.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
int main(void) {
int i;
setlogmask (LOG_UPTO (LOG_NOTICE));
openlog ("exampleprog", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER);
for (i = 0;i<20000;i++)
{
syslog (LOG_NOTICE, "Program started by User %d", getuid ());
syslog (LOG_INFO, "A tree falls in a forest");
}
setlogmask (LOG_UPTO (LOG_INFO));
for (i = 0;i<20000;i++)
{
syslog (LOG_NOTICE, "Program started by User %d", getuid ());
syslog (LOG_INFO, "A tree falls in a forest");
}
closelog ();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
int main(void) {
int i;
setlogmask (LOG_UPTO (LOG_NOTICE));
openlog ("exampleprog", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER);
for (i = 0;i<20000;i++)
{
syslog (LOG_NOTICE, "Program started by User %d", getuid ());
syslog (LOG_INFO, "A tree falls in a forest");
}
setlogmask (LOG_UPTO (LOG_INFO));
for (i = 0;i<20000;i++)
{
syslog (LOG_NOTICE, "Program started by User %d", getuid ());
syslog (LOG_INFO, "A tree falls in a forest");
}
closelog ();
return 0;
}
Signal Handling
An example of signal handling in C.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void
termination_handler (int signum)
{
printf("signal called number %dn", signum);
if(signum == SIGUSR1)
signal (SIGUSR1, termination_handler);
//if(signum == SIGINT)
//signal (SIGINT, termination_handler);
if(signum == SIGUSR2)
signal (SIGUSR2, termination_handler);
}
int main (void)
{
{
signal (SIGUSR1, termination_handler);
perror("??");
signal (SIGUSR2, termination_handler);
perror("??");
//signal (SIGINT, termination_handler);
//perror("??");
}
while(1)
{
sleep(100);
printf("");
}
}
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void
termination_handler (int signum)
{
printf("signal called number %dn", signum);
if(signum == SIGUSR1)
signal (SIGUSR1, termination_handler);
//if(signum == SIGINT)
//signal (SIGINT, termination_handler);
if(signum == SIGUSR2)
signal (SIGUSR2, termination_handler);
}
int main (void)
{
{
signal (SIGUSR1, termination_handler);
perror("??");
signal (SIGUSR2, termination_handler);
perror("??");
//signal (SIGINT, termination_handler);
//perror("??");
}
while(1)
{
sleep(100);
printf("");
}
}
Saturday, August 22, 2009
A simple example of strtok
Tokenizing a string is always a cumbersome process and most of times results in a buggy code.
Here by presents a very simple example of strtok,
Output:
tokenizing 3/4/5/**6*7 with strtok_r()
token = 3
token = 4
token = 5
token = 6
token = 7
The strtok() function uses a static buffer while parsing, so it's not thread safe. Use strtok_r() if this matters to you.
Here by presents a very simple example of strtok,
#include<stdio.h>
#include<string.h>
int main() {
char *token;
char *lasts;
char buf[50] ;
strcpy(buf,"3/4/5/**6*7");
printf("\ntokenizing %s with strtok_r():\n", buf);
if ((token = strtok_r(buf, "*/", &lasts)) != NULL) {
printf("token = %s\n", token);
while ((token = strtok_r(NULL, "*/", &lasts)) != NULL) {
printf("token = %s\n", token);
}
}
}
Output:
tokenizing 3/4/5/**6*7 with strtok_r()
token = 3
token = 4
token = 5
token = 6
token = 7
The strtok() function uses a static buffer while parsing, so it's not thread safe. Use strtok_r() if this matters to you.
Subscribe to:
Posts (Atom)