/*
Copyright (c) 1998--2006 Benhur Stein
This file is part of Pajé.
Pajé is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
Pajé is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
for more details.
You should have received a copy of the GNU Lesser General Public License
along with Pajé; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
*/
//#include "rastro_public.h"
//#include "rastro_private.h"
#include "rastro_write_functions.h"
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/time.h>
#include <errno.h>
#include <sys/param.h> /* for MAXHOSTNAMELEN */
#include "list.h"
list_t list;
bool list_init=false;
#ifndef THREADED
rst_buffer_t *rst_global_buffer;
#else
int rst_key_initialized = 0;
pthread_key_t rst_key;
#endif
int rst_debug_mask = 0;
char rst_dirname[FILENAME_MAX];
void rst_destroy_buffer(void *p)
{
rst_buffer_t *ptr = (rst_buffer_t *) p;
if (ptr != NULL) {
int fd;
rst_event_ptr(ptr, RST_EVENT_STOP);
rst_flush(ptr);
free(ptr->rst_buffer);
fd = RST_FD(ptr);
close(fd);
//free(ptr);
}
}
// Extrai argumentos para a biblioteca
void extract_arguments(int *argcp, char ***argvp)
{
char **argv;
int argc;
int arg, used, unused;
char **p1, **p2, **plast;
char *cepar;
argv = *argvp;
argc = *argcp;
arg = used = unused = 1;
bzero(rst_dirname, sizeof rst_dirname);
while (arg < argc) {
if ( strncmp(argv[arg], "-rst-", 5) == 0 ) {
cepar = argv[arg] + 5;
if ( !strcmp(cepar, "dir") ) {
strcpy(rst_dirname, argv[++arg]);
if (opendir(rst_dirname) == NULL ) {
printf("Diretorio invalido\n");
exit(0);
}
if ( (rst_dirname[strlen(rst_dirname) - 1] != '/') )
rst_dirname[strlen(rst_dirname)] = '/';
}
if ( !strcmp(cepar, "dm") ) {
rst_debug_mask = atoi(argv[++arg]);
}
unused = ++arg;
}
else {
if (unused > used ) {
p1 = argv + used;
p2 = argv + unused;
plast = argv + argc;
argc -= (unused - used);
while ( p2 < plast )
*p1++ = *p2++;
unused = used;
}
arg = ++used;
}
}
if ( unused > used)
argc = used;
*argcp = argc;
argv[argc] = NULL;
}
// Inicializa biblioteca em um nodo
void rst_initialize(u_int64_t id1, u_int64_t id2, int *argc, char ***argv)
{
if ( argv != NULL )
extract_arguments(argc, argv);
rst_init(id1, id2);
}
// Inicializa a biblioteca em uma thread
void rst_init(u_int64_t id1, u_int64_t id2)
{
rst_buffer_t *ptr;
ptr = (rst_buffer_t *) malloc(sizeof(rst_buffer_t));
rst_init_ptr(ptr, id1, id2);
}
// Inicializacao com buffer pre-alocado
void rst_init_ptr(rst_buffer_t *ptr, u_int64_t id1, u_int64_t id2)
{
int fd;
char fname[30];
char hostname[MAXHOSTNAMELEN+1];
if ( ptr == NULL ) {
fprintf(stderr, "[rastro] error inicializing - invalid pointer\n");
return;
}
#ifdef THREADED
if (!rst_key_initialized) {
pthread_key_create(&rst_key, rst_destroy_buffer);
rst_key_initialized = 1;
}
#endif
if(!list_init){
list_initialize(&list, list_copy, list_cmp, list_destroy);
list_init=true;
}
RST_SET_PTR(ptr);
ptr->rst_buffer_size = 100000;
ptr->rst_buffer = malloc(ptr->rst_buffer_size);
RST_RESET(ptr);
sprintf(fname, "rastro-%lld-%lld.rst",/* dirname,*/ id1, id2);
fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (fd == -1) {
fprintf(stderr, "[rastro] cannot open file %s: %s\n",
fname, strerror(errno));
return;
}
list_insert_after(&list, NULL, (void *)ptr );
RST_SET_FD(ptr, fd);
// this will force first event to register sync time
RST_SET_T0(ptr, 0);
gethostname(hostname, sizeof(hostname));
XCAT(rst_event_,LETRA_UINT64,LETRA_STRING,_ptr)(ptr, RST_EVENT_INIT, id1, id2, hostname);
}
// Grava buffer no arquivo de traco
void rst_flush(rst_buffer_t * ptr)
{
size_t nbytes;
size_t n;
nbytes = RST_BUF_COUNT(ptr);
n = write(RST_FD(ptr), RST_BUF_DATA(ptr), nbytes);
if (n != nbytes) {
fprintf(stderr, "[rastro] error writing rastro file\n");
}
RST_RESET(ptr);
}
// Termina biblioteca em nodo ou thread
void rst_finalize(void)
{
rst_buffer_t *ptr = RST_PTR;
list_remove(&list, (void *)ptr);
rst_destroy_buffer(ptr);
free(ptr);
}
// Termina biblioteca em nodo ou thread com ptr
void rst_finalize_ptr(rst_buffer_t *ptr)
{
list_remove(&list, (void *)ptr);
rst_destroy_buffer(ptr);
}
void rst_flush_all(void)
{
position_t pos;
rst_buffer_t *ptr;
for(pos=list.sent->next; pos != list.sent; pos=pos->next ){
ptr= (rst_buffer_t *)pos->data;
rst_flush(ptr);
}
//list_finalize(&list);
}
// Registra evento somente com tipo
void rst_event(u_int16_t type)
{
rst_buffer_t *ptr = RST_PTR;
/*...2 para finalizar esse rastro que so tem o tipo...*/
rst_startevent(ptr, type << 18 | 0x20000);
rst_endevent(ptr);
}
// Registra evento somente com tipo com ptr
void rst_event_ptr(rst_buffer_t *ptr, u_int16_t type)
{
if ( ptr == NULL ) {
printf("[rastro] ptr invalido\n");
return;
}
/*...2 para finalizar esse rastro que so tem o tipo...*/
rst_startevent(ptr, type << 18 | 0x20000);
rst_endevent(ptr);
}
syntax highlighted by Code2HTML, v. 0.9.1