metal/mtce-common/src/common/nodeEvent.cpp

349 lines
11 KiB
C++

/*
* Copyright (c) 2013, 2015 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
/**
* @file
* Wind River CGCS Platform common iNotify utilities
*/
#include "nodeEvent.h"
#include "nodeBase.h"
// The following are legal, implemented events that user-space can watch for
// -------------------------------------------------------------------------
// #define IN_ACCESS 0x00000001 /* File was accessed */
// #define IN_MODIFY 0x00000002 /* File was modified */
// #define IN_ATTRIB 0x00000004 /* Metadata changed */
// #define IN_CLOSE_WRITE 0x00000008 /* Writtable file was closed */
// #define IN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */
// #define IN_OPEN 0x00000020 /* File was opened */
// #define IN_MOVED_FROM 0x00000040 /* File was moved from X */
// #define IN_MOVED_TO 0x00000080 /* File was moved to Y */
// #define IN_CREATE 0x00000100 /* Subfile was created */
// #define IN_DELETE 0x00000200 /* Subfile was deleted */
// #define IN_DELETE_SELF 0x00000400 /* Self was deleted */
// The following are legal events. they are sent as needed to any watch
// #define IN_UNMOUNT 0x00002000 /* Backing fs was unmounted */
// #define IN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */
// #define IN_IGNORED 0x00008000 /* File was ignored */
// Helper events //
// #define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) /* close */
// #define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* moves */
// Special flags
// #define IN_ISDIR 0x40000000 /* event occurred against dir */
// #define IN_ONESHOT 0x80000000 /* only send event once */
/* Display information from inotify_event structure */
const char * get_inotify_event_str (int mask )
{
if (mask & IN_ACCESS) return("IN_ACCESS ");
if (mask & IN_ATTRIB) return("IN_ATTRIB ");
if (mask & IN_CLOSE_NOWRITE) return("IN_CLOSE_NOWRITE ");
if (mask & IN_CLOSE_WRITE) return("IN_CLOSE_WRITE ");
if (mask & IN_CREATE) return("IN_CREATE ");
if (mask & IN_DELETE) return("IN_DELETE ");
if (mask & IN_DELETE_SELF) return("IN_DELETE_SELF ");
if (mask & IN_IGNORED) return("IN_IGNORED ");
if (mask & IN_ISDIR) return("IN_ISDIR ");
if (mask & IN_MODIFY) return("IN_MODIFY ");
if (mask & IN_MOVE_SELF) return("IN_MOVE_SELF ");
if (mask & IN_MOVED_FROM) return("IN_MOVED_FROM ");
if (mask & IN_MOVED_TO) return("IN_MOVED_TO ");
if (mask & IN_OPEN) return("IN_OPEN ");
if (mask & IN_Q_OVERFLOW) return("IN_Q_OVERFLOW ");
if (mask & IN_UNMOUNT) return("IN_UNMOUNT ");
return ("None");
}
int set_inotify_watch_file ( const char * file , int & fd , int & wd )
{
int rc = PASS ;
/* Close if already set */
set_inotify_close ( fd , wd );
fd = inotify_init();
if ( fd < 0 )
{
elog ("iNotify init error (%d:%m)\n", errno );
rc = FAIL;
}
else
{
wd = inotify_add_watch ( fd, file, IN_MODIFY | IN_CREATE | IN_DELETE );
if ( wd < 0 )
{
elog ("failed adding watch on %s (%d:%m)\n", file, errno );
rc = FAIL ;
}
else
{
ilog ("watching %s\n", file );
}
}
return (rc);
}
int set_inotify_watch ( const char * dir , int & fd , int & wd )
{
int rc = PASS ;
fd = inotify_init();
if ( fd < 0 )
{
elog ("inotify init error (%d:%m)\n", errno);
rc = FAIL;
}
else
{
ilog ("watching %s\n", dir );
wd = inotify_add_watch ( fd, dir , IN_MODIFY |
IN_CREATE |
IN_DELETE |
IN_MOVE );
if ( wd < 0 )
{
elog ("failed adding watch on %s (%d:%m)\n", dir, errno );
rc = FAIL ;
}
}
return (rc);
}
int set_inotify_watch_events ( const char * dir , int & fd , int & wd, int events )
{
int rc = PASS ;
fd = inotify_init();
if ( fd < 0 )
{
elog ("inotify init error (%d:%m)\n", errno );
rc = FAIL;
}
else
{
ilog ("watching %s\n", dir );
wd = inotify_add_watch ( fd, dir , events );
if ( wd < 0 )
{
elog ("failed adding watch on %s (%d:%m)\n", dir, errno);
rc = FAIL ;
}
}
return (rc);
}
bool valid_file ( char * name )
{
string temp = name ;
std::size_t found ;
found = temp.find(".swx",0) ;
if ( found != std::string::npos )
{
dlog1 ("%s file is not valid\n", temp.c_str() );
return (false);
}
found = temp.find(".swp",0) ;
if ( found != std::string::npos )
{
dlog1 ("%s file is not valid\n", temp.c_str() );
return (false);
}
dlog ("%s file is valid\n", temp.c_str() );
return (true);
}
int get_inotify_events ( int fd, int event_mask )
{
int l = 0 ;
int i = 0 ;
char buf [EVENT_BUF_LEN] ;
int status = 0 ;
memset (buf, 0 , EVENT_BUF_LEN );
if ( ( l = read (fd, buf, EVENT_BUF_LEN ) > 0 ))
{
/* Read returns the list of change events.
* Deal with all the change events and then reload.
*/
while ( i < l )
{
struct inotify_event *event_ptr = (struct inotify_event *)&buf[i];
dlog ("iNotify Event Mask:%8x Requested Mask:%8x\n", event_ptr->mask, event_mask );
if ( event_ptr->mask & event_mask )
{
status |= (event_ptr->mask & event_mask) ;
}
if ( event_ptr->mask & IN_IGNORED )
{
wlog ("Watch file is now being ignored (%x) !!!\n", status );
status |= IN_IGNORED ;
}
i += EVENT_SIZE + event_ptr->len;
}
}
return(status);
}
bool get_inotify_events ( int fd )
{
int l = 0 ;
int i = 0 ;
char buf [EVENT_BUF_LEN] ;
bool status = false ;
memset (buf, 0 , EVENT_BUF_LEN );
if ( ( l = read (fd, buf, EVENT_BUF_LEN ) > 0 ))
{
/* Read returns the list of change events.
* Deal with all the change events and then reload.
*/
while ( i < l )
{
struct inotify_event *event_ptr = (struct inotify_event *)&buf[i];
dlog ("iNotify Event Mask:%08x\n", event_ptr->mask);
if ( event_ptr->len )
{
if (( event_ptr->mask & IN_CREATE ) ||
( event_ptr->mask & IN_MOVED_TO ))
{
if ( valid_file ( event_ptr->name ) == true )
{
if ( !(event_ptr->mask & IN_ISDIR) )
{
dlog( "New file %s created or moved into\n", event_ptr->name );
status = true ;
}
}
}
else if (( event_ptr->mask & IN_DELETE ) ||
( event_ptr->mask & IN_MOVED_FROM ))
{
if ( valid_file ( event_ptr->name ) == true )
{
if ( !(event_ptr->mask & IN_ISDIR) )
{
dlog( "%s deleted or removed.\n", event_ptr->name );
status = true ;
}
}
}
else if ( event_ptr->mask & IN_MODIFY )
{
if ( valid_file ( event_ptr->name ) == true )
{
if ( !(event_ptr->mask & IN_ISDIR) )
{
dlog( "%s modified.\n", event_ptr->name );
status = true ;
}
}
}
else
{
dlog ("Unhandled iNotify Event Mask:%08x\n", event_ptr->mask);
}
}
i += EVENT_SIZE + event_ptr->len;
}
}
return(status);
}
static string null_str = "" ;
/* Returns the number of events found */
int get_inotify_events ( int fd, inotify_event_queue_type & event_queue )
{
int l = 0 ;
int i = 0 ;
char buf [EVENT_BUF_LEN] ;
memset (buf, 0 , EVENT_BUF_LEN );
event_queue.num = 0 ; /* default to no events */
if ( ( l = read (fd, buf, EVENT_BUF_LEN ) > 0 ))
{
/* Read returns the list of change events.
* Deal with all the change events and then reload.
*/
while ( i < l )
{
struct inotify_event *event_ptr = (struct inotify_event *)&buf[i];
dlog ("iNotify Event Mask:%08x\n", event_ptr->mask);
if ( event_ptr->len )
{
if (( event_ptr->mask & IN_CREATE ) ||
( event_ptr->mask & IN_MOVED_TO ))
{
if ( valid_file ( event_ptr->name ) == true )
{
if ( !(event_ptr->mask & IN_ISDIR) )
{
dlog( "%s created\n", event_ptr->name );
event_queue.item[event_queue.num].event = IN_CREATE ;
snprintf ( &event_queue.item[event_queue.num].name[0], EVENT_BUF_LEN, "%s", event_ptr->name );
event_queue.num++ ;
}
}
}
else if (( event_ptr->mask & IN_DELETE ) ||
( event_ptr->mask & IN_MOVED_FROM ))
{
if ( valid_file ( event_ptr->name ) == true )
{
if ( !(event_ptr->mask & IN_ISDIR) )
{
dlog( "%s deleted\n", event_ptr->name );
event_queue.item[event_queue.num].event = IN_DELETE ;
snprintf ( &event_queue.item[event_queue.num].name[0], EVENT_BUF_LEN, "%s", event_ptr->name );
event_queue.num++ ;
}
}
}
else if ( event_ptr->mask & IN_MODIFY )
{
if ( valid_file ( event_ptr->name ) == true )
{
if ( !(event_ptr->mask & IN_ISDIR) )
{
dlog( "%s modified\n", event_ptr->name );
event_queue.item[event_queue.num].event = IN_MODIFY ;
snprintf ( &event_queue.item[event_queue.num].name[0], EVENT_BUF_LEN, "%s", event_ptr->name );
event_queue.num++ ;
}
}
}
else
{
dlog ("Unhandled iNotify Event Mask:%08x\n", event_ptr->mask);
}
}
i += EVENT_SIZE + event_ptr->len;
}
}
return (event_queue.num) ;
}
void set_inotify_close ( int & fd, int & wd )
{
/* cleanup */
if ( fd )
{
inotify_rm_watch( fd, wd );
close (fd);
fd = 0 ;
wd = 0 ;
}
}