18922761a6
Signed-off-by: Dean Troyer <dtroyer@gmail.com>
349 lines
11 KiB
C++
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 ;
|
|
}
|
|
}
|
|
|