PAPI  5.4.0.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pit_server.c File Reference
Include dependency graph for pit_server.c:

Go to the source code of this file.

Macros

#define DFLT_SERVICE   "PIT" /* Programmable Interdimensional Timer */
 
#define INVALID_DESC   -1 /* Invalid file descriptor. */
 
#define MAXCONNQLEN   3 /* Max nbr of connection requests to queue. */
 
#define MAXTCPSCKTS   2 /* One TCP socket for IPv4 & one for IPv6. */
 
#define MAXUDPSCKTS   2 /* One UDP socket for IPv4 & one for IPv6. */
 
#define VALIDOPTS   "vh:p:" /* Valid command options. */
 
#define USAGE
 
#define CHK(expr)
 

Functions

static int openSckt (const char *service, const char *protocol, int desc[], size_t *descSize)
 
static void pit (int tSckt[], size_t tScktSize, int uSckt[], size_t uScktSize)
 
int main (int argc, char *argv[])
 

Variables

int false = 0
 
int true = 1
 
static char hostBfr [NI_MAXHOST]
 
static const char * pgmName
 
static char servBfr [NI_MAXSERV]
 
static int verbose = 0
 
struct timeval tm
 
char timeStr [40]
 
char service_name [20]
 
int need
 

Macro Definition Documentation

#define CHK (   expr)
Value:
do \
{ \
if ( (expr) == -1 ) \
{ \
fprintf( stderr, \
"%s (line %d): System call ERROR - %s.\n", \
__LINE__, \
strerror( errno ) ); \
exit( 1 ); \
} /* End IF system call failed. */ \
} while ( false )
int errno
static const char * pgmName
Definition: pit_server.c:81
void exit()
if(gettimeofday(&tp,(struct timezone *) NULL)==-1) perror("gettimeofday")

Definition at line 102 of file pit_server.c.

#define DFLT_SERVICE   "PIT" /* Programmable Interdimensional Timer */

Definition at line 54 of file pit_server.c.

#define INVALID_DESC   -1 /* Invalid file descriptor. */

Definition at line 56 of file pit_server.c.

#define MAXCONNQLEN   3 /* Max nbr of connection requests to queue. */

Definition at line 57 of file pit_server.c.

#define MAXTCPSCKTS   2 /* One TCP socket for IPv4 & one for IPv6. */

Definition at line 58 of file pit_server.c.

#define MAXUDPSCKTS   2 /* One UDP socket for IPv4 & one for IPv6. */

Definition at line 59 of file pit_server.c.

#define USAGE
Value:
{ \
fprintf( stderr, \
"Usage: %s [-v] -p service \n", \
exit( 127 ); \
} /* End USAGE macro. */
static const char * pgmName
Definition: pit_server.c:81
void exit()

Definition at line 91 of file pit_server.c.

#define VALIDOPTS   "vh:p:" /* Valid command options. */

Definition at line 60 of file pit_server.c.

Function Documentation

int main ( int  argc,
char *  argv[] 
)

Definition at line 129 of file pit_server.c.

131 {
132  int opt;
133  int tSckt[ MAXTCPSCKTS ]; /* Array of TCP socket descriptors. */
134  size_t tScktSize = MAXTCPSCKTS; /* Size of uSckt (# of elements). */
135  int uSckt[ MAXUDPSCKTS ]; /* Array of UDP socket descriptors. */
136  size_t uScktSize = MAXUDPSCKTS; /* Size of uSckt (# of elements). */
137 
139  /*
140  ** Set the program name (w/o directory prefix).
141  */
142  pgmName = strrchr( argv[ 0 ], '/' );
143  pgmName = pgmName == NULL ? argv[ 0 ] : pgmName + 1;
144  /*
145  ** Process command options.
146  */
147  opterr = 0; /* Turns off "invalid option" error messages. */
148  while ( ( opt = getopt( argc, argv, VALIDOPTS ) ) >= 0 )
149  {
150  switch ( opt )
151  {
152  case 'v': /* Verbose mode. */
153  {
154  verbose = true;
155  break;
156  }
157  case 'p': /* Get the port number */
158  {
160  need++;
161  break;
162  }
163  default:
164  {
165  USAGE;
166  }
167  } /* End SWITCH on command option. */
168  } /* End WHILE processing options. */
169 
170  if(need < 1)
171  {
172  USAGE;
173  exit;
174  }
175  /*
176  ** Open both a TCP and UDP socket, for both IPv4 & IPv6, on which to receive
177  ** service requests.
178  */
179  if ( ( openSckt( service_name, "tcp", tSckt, &tScktSize ) < 0 ) ||
180  ( openSckt( service_name, "udp", uSckt, &uScktSize ) < 0 ) )
181  {
182  exit( 1 );
183  }
184  /*
185  ** Run the Programmable Interdimensional Timer server.
186  */
187  if ( ( tScktSize > 0 ) || ( uScktSize > 0 ) )
188  {
189  pit( tSckt, /* pit() never returns. */
190  tScktSize,
191  uSckt,
192  uScktSize );
193  }
194  /*
195  ** Since pit() never returns, execution only gets here if no sockets were
196  ** created.
197  */
198  if ( verbose )
199  {
200  fprintf( stderr,
201  "%s: No sockets opened... terminating.\n",
202  pgmName );
203  }
204  return 0;
205 } /* End main() */
static const char * pgmName
Definition: pit_server.c:81
int verbose
Definition: fileop.c:79
int need
Definition: pit_server.c:87
#define MAXTCPSCKTS
Definition: pit_server.c:58
char service_name[20]
Definition: pit_server.c:86
int int argc
Definition: iozone.c:1609
char ** argv
Definition: iozone.c:1610
static void pit(int tSckt[], size_t tScktSize, int uSckt[], size_t uScktSize)
Definition: pit_server.c:490
static int openSckt(const char *service, const char *protocol, int desc[], size_t *descSize)
Definition: pit_server.c:232
strcpy(filename, default_filename)
#define MAXUDPSCKTS
Definition: pit_server.c:59
#define VALIDOPTS
Definition: pit_server.c:60
void exit()
#define DFLT_SERVICE
Definition: pit_server.c:54
char * optarg
#define USAGE
Definition: pit_server.c:91

Here is the call graph for this function:

static int openSckt ( const char *  service,
const char *  protocol,
int  desc[],
size_t *  descSize 
)
static

Definition at line 232 of file pit_server.c.

236 {
237  struct addrinfo *ai;
238  int aiErr;
239  struct addrinfo *aiHead;
240  struct addrinfo hints = { .ai_flags = AI_PASSIVE, /* Server mode. */
241  .ai_family = PF_UNSPEC }; /* IPv4 or IPv6. */
242  size_t maxDescs = *descSize;
243  /*
244  ** Initialize output parameters. When the loop completes, *descSize is 0.
245  */
246  while ( *descSize > 0 )
247  {
248  desc[ --( *descSize ) ] = INVALID_DESC;
249  }
250  /*
251  ** Check which protocol is selected (only TCP and UDP are valid).
252  */
253  if ( strcmp( protocol, "tcp" ) == 0 ) /* TCP protocol. */
254  {
255  hints.ai_socktype = SOCK_STREAM;
256  hints.ai_protocol = IPPROTO_TCP;
257  }
258  else if ( strcmp( protocol, "udp" ) == 0 ) /* UDP protocol. */
259  {
260  hints.ai_socktype = SOCK_DGRAM;
261  hints.ai_protocol = IPPROTO_UDP;
262  }
263  else /* Invalid protocol. */
264  {
265  fprintf( stderr,
266  "%s (line %d): ERROR - Unknown transport "
267  "layer protocol \"%s\".\n",
268  pgmName,
269  __LINE__,
270  protocol );
271  return -1;
272  }
273  /*
274  ** Look up the service's "well-known" port number. Notice that NULL is being
275  ** passed for the 'node' parameter, and that the AI_PASSIVE flag is set in
276  ** 'hints'. Thus, the program is requesting passive address information.
277  ** The network address is initialized to :: (all zeros) for IPv6 records, or
278  ** 0.0.0.0 for IPv4 records.
279  */
280  if ( ( aiErr = getaddrinfo( NULL,
281  service,
282  &hints,
283  &aiHead ) ) != 0 )
284  {
285  fprintf( stderr,
286  "%s (line %d): ERROR - %s.\n",
287  pgmName,
288  __LINE__,
289  gai_strerror( aiErr ) );
290  return -1;
291  }
292  /*
293  ** For each of the address records returned, attempt to set up a passive
294  ** socket.
295  */
296  for ( ai = aiHead;
297  ( ai != NULL ) && ( *descSize < maxDescs );
298  ai = ai->ai_next )
299  {
300  if ( verbose )
301  {
302  /*
303  ** Display the current address info. Start with the protocol-
304  ** independent fields first.
305  */
306  fprintf( stderr,
307  "Setting up a passive socket based on the "
308  "following address info:\n"
309  " ai_flags = %#02X\n"
310  " ai_family = %d (PF_INET = %d, PF_INET6 = %d)\n"
311  " ai_socktype = %d (SOCK_STREAM = %d, SOCK_DGRAM = %d)\n"
312  " ai_protocol = %d (IPPROTO_TCP = %d, IPPROTO_UDP = %d)\n"
313  " ai_addrlen = %d (sockaddr_in = %lu, "
314  "sockaddr_in6 = %lu)\n",
315  ai->ai_flags,
316  ai->ai_family,
317  PF_INET,
318  PF_INET6,
319  ai->ai_socktype,
320  SOCK_STREAM,
321  SOCK_DGRAM,
322  ai->ai_protocol,
323  IPPROTO_TCP,
324  IPPROTO_UDP,
325  ai->ai_addrlen,
326  sizeof( struct sockaddr_in ),
327  sizeof( struct sockaddr_in6 ) );
328  /*
329  ** Now display the protocol-specific formatted socket address. Note
330  ** that the program is requesting that getnameinfo(3) convert the
331  ** host & service into numeric strings.
332  */
333  getnameinfo( ai->ai_addr,
334  ai->ai_addrlen,
335  hostBfr,
336  sizeof( hostBfr ),
337  servBfr,
338  sizeof( servBfr ),
339  NI_NUMERICHOST | NI_NUMERICSERV );
340  switch ( ai->ai_family )
341  {
342  case PF_INET: /* IPv4 address record. */
343  {
344  struct sockaddr_in *p = (struct sockaddr_in*) ai->ai_addr;
345  fprintf( stderr,
346  " ai_addr = sin_family: %d (AF_INET = %d, "
347  "AF_INET6 = %d)\n"
348  " sin_addr: %s\n"
349  " sin_port: %s\n",
350  p->sin_family,
351  AF_INET,
352  AF_INET6,
353  hostBfr,
354  servBfr );
355  break;
356  } /* End CASE of IPv4. */
357  case PF_INET6: /* IPv6 address record. */
358  {
359  struct sockaddr_in6 *p = (struct sockaddr_in6*) ai->ai_addr;
360  fprintf( stderr,
361  " ai_addr = sin6_family: %d (AF_INET = %d, "
362  "AF_INET6 = %d)\n"
363  " sin6_addr: %s\n"
364  " sin6_port: %s\n"
365  " sin6_flowinfo: %d\n"
366  " sin6_scope_id: %d\n",
367  p->sin6_family,
368  AF_INET,
369  AF_INET6,
370  hostBfr,
371  servBfr,
372  p->sin6_flowinfo,
373  p->sin6_scope_id );
374  break;
375  } /* End CASE of IPv6. */
376  default: /* Can never get here, but just for completeness. */
377  {
378  fprintf( stderr,
379  "%s (line %d): ERROR - Unknown protocol family (%d).\n",
380  pgmName,
381  __LINE__,
382  ai->ai_family );
383  freeaddrinfo( aiHead );
384  return -1;
385  } /* End DEFAULT case (unknown protocol family). */
386  } /* End SWITCH on protocol family. */
387  } /* End IF verbose mode. */
388  /*
389  ** Create a socket using the info in the addrinfo structure.
390  */
391  CHK( desc[ *descSize ] = socket( ai->ai_family,
392  ai->ai_socktype,
393  ai->ai_protocol ) );
394  /*
395  ** Here is the code that prevents "IPv4 mapped addresses", as discussed
396  ** in Section 22.1.3.1. If an IPv6 socket was just created, then set the
397  ** IPV6_V6ONLY socket option.
398  */
399  if ( ai->ai_family == PF_INET6 )
400  {
401 #if defined( IPV6_V6ONLY )
402  /*
403  ** Disable IPv4 mapped addresses.
404  */
405  int v6Only = 1;
406  CHK( setsockopt( desc[ *descSize ],
407  IPPROTO_IPV6,
408  IPV6_V6ONLY,
409  &v6Only,
410  sizeof( v6Only ) ) );
411 #else
412  /*
413  ** IPV6_V6ONLY is not defined, so the socket option can't be set and
414  ** thus IPv4 mapped addresses can't be disabled. Print a warning
415  ** message and close the socket. Design note: If the
416  ** #if...#else...#endif construct were removed, then this program
417  ** would not compile (because IPV6_V6ONLY isn't defined). That's an
418  ** acceptable approach; IPv4 mapped addresses are certainly disabled
419  ** if the program can't build! However, since this program is also
420  ** designed to work for IPv4 sockets as well as IPv6, I decided to
421  ** allow the program to compile when IPV6_V6ONLY is not defined, and
422  ** turn it into a run-time warning rather than a compile-time error.
423  ** IPv4 mapped addresses are still disabled because _all_ IPv6 traffic
424  ** is disabled (all IPv6 sockets are closed here), but at least this
425  ** way the server can still service IPv4 network traffic.
426  */
427  fprintf( stderr,
428  "%s (line %d): WARNING - Cannot set IPV6_V6ONLY socket "
429  "option. Closing IPv6 %s socket.\n",
430  pgmName,
431  __LINE__,
432  ai->ai_protocol == IPPROTO_TCP ? "TCP" : "UDP" );
433  CHK( close( desc[ *descSize ] ) );
434  continue; /* Go to top of FOR loop w/o updating *descSize! */
435 #endif /* IPV6_V6ONLY */
436  } /* End IF this is an IPv6 socket. */
437  /*
438  ** Bind the socket. Again, the info from the addrinfo structure is used.
439  */
440  CHK( bind( desc[ *descSize ],
441  ai->ai_addr,
442  ai->ai_addrlen ) );
443  /*
444  ** If this is a TCP socket, put the socket into passive listening mode
445  ** (listen is only valid on connection-oriented sockets).
446  */
447  if ( ai->ai_socktype == SOCK_STREAM )
448  {
449  CHK( listen( desc[ *descSize ],
450  MAXCONNQLEN ) );
451  }
452  /*
453  ** Socket set up okay. Bump index to next descriptor array element.
454  */
455  *descSize += 1;
456  } /* End FOR each address info structure returned. */
457  /*
458  ** Dummy check for unused address records.
459  */
460  if ( verbose && ( ai != NULL ) )
461  {
462  fprintf( stderr,
463  "%s (line %d): WARNING - Some address records were "
464  "not processed due to insufficient array space.\n",
465  pgmName,
466  __LINE__ );
467  } /* End IF verbose and some address records remain unprocessed. */
468  /*
469  ** Clean up.
470  */
471  freeaddrinfo( aiHead );
472  return 0;
473 } /* End openSckt() */
int close(int fd)
Definition: appio.c:175
static const char * pgmName
Definition: pit_server.c:81
int verbose
Definition: fileop.c:79
#define CHK(expr)
Definition: pit_server.c:102
#define INVALID_DESC
Definition: pit_server.c:56
static char servBfr[NI_MAXSERV]
Definition: pit_server.c:82
static char hostBfr[NI_MAXHOST]
Definition: pit_server.c:80
listen(s, 10)
#define MAXCONNQLEN
Definition: pit_server.c:57

Here is the call graph for this function:

Here is the caller graph for this function:

static void pit ( int  tSckt[],
size_t  tScktSize,
int  uSckt[],
size_t  uScktSize 
)
static

Definition at line 490 of file pit_server.c.

494 {
495  char bfr[ 256 ];
496  ssize_t count;
497  struct pollfd *desc;
498  size_t descSize = tScktSize + uScktSize;
499  int idx;
500  int newSckt;
501  struct sockaddr *sadr;
502  socklen_t sadrLen;
503  struct sockaddr_storage sockStor;
504  int status;
505  size_t timeLen;
506  time_t timeVal;
507  ssize_t wBytes;
508  unsigned long long secs;
509  int ret;
510  /*
511  ** Allocate memory for the poll(2) array.
512  */
513  desc = malloc( descSize * sizeof( struct pollfd ) );
514  if ( desc == NULL )
515  {
516  fprintf( stderr,
517  "%s (line %d): ERROR - %s.\n",
518  pgmName,
519  __LINE__,
520  strerror( ENOMEM ) );
521  exit( 1 );
522  }
523  /*
524  ** Initialize the poll(2) array.
525  */
526  for ( idx = 0; idx < descSize; idx++ )
527  {
528  desc[ idx ].fd = idx < tScktSize ? tSckt[ idx ]
529  : uSckt[ idx - tScktSize ];
530  desc[ idx ].events = POLLIN;
531  desc[ idx ].revents = 0;
532  }
533  /*
534  ** Main PIT server loop. Handles both TCP & UDP requests. This is
535  ** an interative server, and all requests are handled directly within the
536  ** main loop.
537  */
538  while ( true ) /* Do forever. */
539  {
540  /*
541  ** Wait for activity on one of the sockets. The DO..WHILE construct is
542  ** used to restart the system call in the event the process is
543  ** interrupted by a signal.
544  */
545  do
546  {
547  status = poll( desc,
548  descSize,
549  -1 /* Wait indefinitely for input. */ );
550  } while ( ( status < 0 ) && ( errno == EINTR ) );
551  CHK( status ); /* Check for a bona fide system call error. */
552  /*
553  ** Get the current time.
554  */
555 #if defined(Windows)
556  LARGE_INTEGER freq,counter;
557  double wintime,bigcounter;
558  /* For Windows the time_of_day() is useless. It increments in 55 milli
559  * second increments. By using the Win32api one can get access to the
560  * high performance measurement interfaces. With this one can get back
561  * into the 8 to 9 microsecond resolution.
562  */
563  QueryPerformanceFrequency(&freq);
564  QueryPerformanceCounter(&counter);
565  bigcounter=(double)counter.HighPart *(double)0xffffffff +
566  (double)counter.LowPart;
567  wintime = (double)(bigcounter/(double)freq.LowPart);
568  secs = (long long)(wintime * 1000000);
569 #else
570  ret = gettimeofday( &tm,0 );
571  secs = ((unsigned long long)tm.tv_sec * 1000000)
572  + (unsigned long long)tm.tv_usec;
573 #endif
574 
575  ret = sprintf(timeStr,"%llu",secs);
576  timeLen = strlen( timeStr );
577  /*
578  ** Process sockets with input available.
579  */
580  for ( idx = 0; idx < descSize; idx++ )
581  {
582  switch ( desc[ idx ].revents )
583  {
584  case 0: /* No activity on this socket; try the next. */
585  continue;
586  case POLLIN: /* Network activity. Go process it. */
587  break;
588  default: /* Invalid poll events. */
589  {
590  fprintf( stderr,
591  "%s (line %d): ERROR - Invalid poll event (%#02X).\n",
592  pgmName,
593  __LINE__,
594  desc[ idx ].revents );
595  exit( 1 );
596  }
597  } /* End SWITCH on returned poll events. */
598  /*
599  ** Determine if this is a TCP request or UDP request.
600  */
601  if ( idx < tScktSize )
602  {
603  /*
604  ** TCP connection requested. Accept it. Notice the use of
605  ** the sockaddr_storage data type.
606  */
607  sadrLen = sizeof( sockStor );
608  sadr = (struct sockaddr*) &sockStor;
609  CHK( newSckt = accept( desc[ idx ].fd,
610  sadr,
611  &sadrLen ) );
612  CHK( shutdown( newSckt, /* Server never recv's anything. */
613  SHUT_RD ) );
614  if ( verbose )
615  {
616  /*
617  ** Display the socket address of the remote client. Begin with
618  ** the address-independent fields.
619  */
620  fprintf( stderr,
621  "Sockaddr info for new TCP client:\n"
622  " sa_family = %d (AF_INET = %d, AF_INET6 = %d)\n"
623  " addr len = %d (sockaddr_in = %lu, "
624  "sockaddr_in6 = %lu)\n",
625  sadr->sa_family,
626  AF_INET,
627  AF_INET6,
628  sadrLen,
629  sizeof( struct sockaddr_in ),
630  sizeof( struct sockaddr_in6 ) );
631  /*
632  ** Display the address-specific fields.
633  */
634  getnameinfo( sadr,
635  sadrLen,
636  hostBfr,
637  sizeof( hostBfr ),
638  servBfr,
639  sizeof( servBfr ),
640  NI_NUMERICHOST | NI_NUMERICSERV );
641  /*
642  ** Notice that we're switching on an address family now, not a
643  ** protocol family.
644  */
645  switch ( sadr->sa_family )
646  {
647  case AF_INET: /* IPv4 address. */
648  {
649  struct sockaddr_in *p = (struct sockaddr_in*) sadr;
650  fprintf( stderr,
651  " sin_addr = sin_family: %d\n"
652  " sin_addr: %s\n"
653  " sin_port: %s\n",
654  p->sin_family,
655  hostBfr,
656  servBfr );
657  break;
658  } /* End CASE of IPv4. */
659  case AF_INET6: /* IPv6 address. */
660  {
661  struct sockaddr_in6 *p = (struct sockaddr_in6*) sadr;
662  fprintf( stderr,
663  " sin6_addr = sin6_family: %d\n"
664  " sin6_addr: %s\n"
665  " sin6_port: %s\n"
666  " sin6_flowinfo: %d\n"
667  " sin6_scope_id: %d\n",
668  p->sin6_family,
669  hostBfr,
670  servBfr,
671  p->sin6_flowinfo,
672  p->sin6_scope_id );
673  break;
674  } /* End CASE of IPv6. */
675  default: /* Can never get here, but for completeness. */
676  {
677  fprintf( stderr,
678  "%s (line %d): ERROR - Unknown address "
679  "family (%d).\n",
680  pgmName,
681  __LINE__,
682  sadr->sa_family );
683  break;
684  } /* End DEFAULT case (unknown address family). */
685  } /* End SWITCH on address family. */
686  } /* End IF verbose mode. */
687  /*
688  ** Send the PIT to the client.
689  */
690  wBytes = timeLen;
691  while ( wBytes > 0 )
692  {
693  do
694  {
695  count = write( newSckt,
696  timeStr,
697  wBytes );
698  } while ( ( count < 0 ) && ( errno == EINTR ) );
699  CHK( count ); /* Check for an error. */
700  wBytes -= count;
701  } /* End WHILE there is data to send. */
702  CHK( close( newSckt ) );
703  } /* End IF this was a TCP connection request. */
704  else
705  {
706  /*
707  ** This is a UDP socket, and a datagram is available. The funny
708  ** thing about UDP requests is that this server doesn't require any
709  ** client input; but it can't send the PIT unless it knows a client
710  ** wants the data, and the only way that can occur with UDP is if
711  ** the server receives a datagram from the client. Thus, the
712  ** server must receive _something_, but the content of the datagram
713  ** is irrelevant. Read in the datagram. Again note the use of
714  ** sockaddr_storage to receive the address.
715  */
716  sadrLen = sizeof( sockStor );
717  sadr = (struct sockaddr*) &sockStor;
718  CHK( count = recvfrom( desc[ idx ].fd,
719  bfr,
720  sizeof( bfr ),
721  0,
722  sadr,
723  &sadrLen ) );
724  /*
725  ** Display whatever was received on stdout.
726  */
727  if ( verbose )
728  {
729  ssize_t rBytes = count;
730  fprintf( stderr,
731  "%s: UDP datagram received (%ld bytes).\n",
732  pgmName,
733  count );
734  while ( count > 0 )
735  {
736  fputc( bfr[ rBytes - count-- ],
737  stdout );
738  }
739  if ( bfr[ rBytes-1 ] != '\n' )
740  fputc( '\n', stdout ); /* Newline also flushes stdout. */
741  /*
742  ** Display the socket address of the remote client. Address-
743  ** independent fields first.
744  */
745  fprintf( stderr,
746  "Remote client's sockaddr info:\n"
747  " sa_family = %d (AF_INET = %d, AF_INET6 = %d)\n"
748  " addr len = %d (sockaddr_in = %lu, "
749  "sockaddr_in6 = %lu)\n",
750  sadr->sa_family,
751  AF_INET,
752  AF_INET6,
753  sadrLen,
754  sizeof( struct sockaddr_in ),
755  sizeof( struct sockaddr_in6 ) );
756  /*
757  ** Display the address-specific information.
758  */
759  getnameinfo( sadr,
760  sadrLen,
761  hostBfr,
762  sizeof( hostBfr ),
763  servBfr,
764  sizeof( servBfr ),
765  NI_NUMERICHOST | NI_NUMERICSERV );
766  switch ( sadr->sa_family )
767  {
768  case AF_INET: /* IPv4 address. */
769  {
770  struct sockaddr_in *p = (struct sockaddr_in*) sadr;
771  fprintf( stderr,
772  " sin_addr = sin_family: %d\n"
773  " sin_addr: %s\n"
774  " sin_port: %s\n",
775  p->sin_family,
776  hostBfr,
777  servBfr );
778  break;
779  } /* End CASE of IPv4 address. */
780  case AF_INET6: /* IPv6 address. */
781  {
782  struct sockaddr_in6 *p = (struct sockaddr_in6*) sadr;
783  fprintf( stderr,
784  " sin6_addr = sin6_family: %d\n"
785  " sin6_addr: %s\n"
786  " sin6_port: %s\n"
787  " sin6_flowinfo: %d\n"
788  " sin6_scope_id: %d\n",
789  p->sin6_family,
790  hostBfr,
791  servBfr,
792  p->sin6_flowinfo,
793  p->sin6_scope_id );
794  break;
795  } /* End CASE of IPv6 address. */
796  default: /* Can never get here, but for completeness. */
797  {
798  fprintf( stderr,
799  "%s (line %d): ERROR - Unknown address "
800  "family (%d).\n",
801  pgmName,
802  __LINE__,
803  sadr->sa_family );
804  break;
805  } /* End DEFAULT case (unknown address family). */
806  } /* End SWITCH on address family. */
807  } /* End IF verbose mode. */
808  /*
809  ** Send the PIT to the client.
810  */
811  wBytes = timeLen;
812  while ( wBytes > 0 )
813  {
814  do
815  {
816  count = sendto( desc[ idx ].fd,
817  timeStr,
818  wBytes,
819  0,
820  sadr, /* Address & address length */
821  sadrLen ); /* received in recvfrom(). */
822  } while ( ( count < 0 ) && ( errno == EINTR ) );
823  CHK( count ); /* Check for a bona fide error. */
824  wBytes -= count;
825  } /* End WHILE there is data to send. */
826  } /* End ELSE a UDP datagram is available. */
827  desc[ idx ].revents = 0; /* Clear the returned poll events. */
828  } /* End FOR each socket descriptor. */
829  } /* End WHILE forever. */
830 } /* End pit() */
sprintf(splash[splash_line++],"\tIozone: Performance Test of File I/O\n")
int errno
int close(int fd)
Definition: appio.c:175
static const char * pgmName
Definition: pit_server.c:81
int verbose
Definition: fileop.c:79
int fd
Definition: iozone.c:1291
#define CHK(expr)
Definition: pit_server.c:102
int count
Definition: iozone.c:22422
static double
Definition: fileop.c:1281
long long ret
Definition: iozone.c:1346
static char servBfr[NI_MAXSERV]
Definition: pit_server.c:82
ssize_t write(int fd, const void *buf, size_t count)
Definition: appio.c:298
static char hostBfr[NI_MAXHOST]
Definition: pit_server.c:80
long long
Definition: iozone.c:19827
struct timeval tm
Definition: pit_server.c:84
long long status
Definition: iozone.c:1335
char timeStr[40]
Definition: pit_server.c:85
void exit()

Here is the call graph for this function:

Here is the caller graph for this function:

Variable Documentation

int false = 0

Definition at line 64 of file pit_server.c.

char hostBfr[NI_MAXHOST]
static

Definition at line 80 of file pit_server.c.

int need

Definition at line 87 of file pit_server.c.

const char* pgmName
static

Definition at line 81 of file pit_server.c.

char servBfr[NI_MAXSERV]
static

Definition at line 82 of file pit_server.c.

char service_name[20]

Definition at line 86 of file pit_server.c.

char timeStr[40]

Definition at line 85 of file pit_server.c.

struct timeval tm

Definition at line 84 of file pit_server.c.

int true = 1

Definition at line 65 of file pit_server.c.

int verbose = 0
static

Definition at line 83 of file pit_server.c.