f51d42 | 2012-07-25 | Bill Welliver | | /*! @module System
*/
/*! @module Wnotify
*!
*! An interface to Windows filesystem change information.
*!
*/
#include "global.h"
#include "interpret.h"
#include "module.h"
#include "program.h"
#include "stralloc.h"
#include "svalue.h"
#include "threads.h"
#include "object.h"
#include "pike_types.h"
#include "builtin_functions.h"
#include "wnotify_config.h"
#define ADD_ICONST(name) do { \
add_integer_constant(#name, name, 0); \
} while(0);
#ifdef HAVE_FILEAPI_H
#include <FileAPI.h>
#endif /* HAVE_FILEAPI_H */
#ifdef HAVE_WINDOWS_H
#include <windows.h>
#endif /* HAVE_WINDOWS_H */
#ifdef HAVE_WINBASE_H
#include <winbase.h>
#endif /* HAVE_WINBASE_H */
#ifndef MAX_LEN
#define MAX_LEN 255
#endif /* !MAX_LEN */
DECLARATIONS
#ifdef HAVE_FINDFIRSTCHANGENOTIFICATION
/*! @class NotificationHandle
*/
PIKECLASS NotificationHandle
{
CVAR HANDLE handle;
PIKEVAR string path;
PIKEVAR int watch_subtree;
PIKEVAR int filter;
PIKEVAR int triggered;
/*! @decl create(string path, int watch_subtree, int filter)
*/
PIKEFUN void create(string path, int watch_subtree, int filter)
{
HANDLE h;
THIS->path = path;
add_ref(path);
THIS->watch_subtree = watch_subtree;
THIS->filter = filter;
if(string_has_null(path))
{
pop_n_elems(args);
Pike_error("NotificationHandle: path cannot contain null.\n");
}
if((1 << path->size_shift)>1)
{
pop_n_elems(args);
Pike_error("NotificationHandle: path cannot be a wide string.\n");
}
if(THIS->path->len > MAX_LEN)
{
pop_n_elems(args);
Pike_error("NotificationHandle: length of path is too long.\n");
}
h = FindFirstChangeNotification(path->str, (BOOL)THIS->watch_subtree, (DWORD)THIS->filter);
if(h == INVALID_HANDLE_VALUE)
{
pop_n_elems(args);
Pike_error("NotificationHandle: failed to create handle.\n");
}
else
THIS->handle = h;
pop_n_elems(args);
return;
}
/*! @decl int get_error()
*/
PIKEFUN int get_error()
{
DWORD e;
e = GetLastError();
push_int(e);
}
PIKEFUN void read_change()
{
BOOL res;
if(!THIS->triggered)
{
Pike_error("NotificationHandle.read_change(): no change event triggered.\n");
}
/* res = ReadDirectoryChangesW(THIS->handle, ); */
}
INIT
{
}
EXIT
{
if(THIS->path) free_string(THIS->path);
if(THIS->handle) FindCloseChangeNotification(THIS->handle);
}
}
/*! @class EventPoller
*/
PIKECLASS EventPoller
{
/* Do not meddle with this array; it must be kept in sync with the handles array. */
PIKEVAR array phandles
flags ID_PRIVATE;
CVAR HANDLE * handles;
CVAR int handles_size;
CVAR int handles_used;
/*! @decl void add_handle(NotificationHandle handle)
*/
PIKEFUN void add_handle(object handle)
{
void * h;
int s, i, n;
struct array * ph;
HANDLE nh;
HANDLE * handles;
h = get_storage(handle, NotificationHandle_program);
if(!h)
{
pop_stack();
Pike_error("add_handle: invalid object type.\n");
}
ph = append_array(THIS->phandles, &Pike_sp[-args]);
THIS->phandles = ph;
nh = OBJ2_NOTIFICATIONHANDLE(handle)->handle;
if(THIS->handles_size <= THIS->handles_used)
{
s = n = THIS->handles_size || 1;
s*=2;
handles = realloc(THIS->handles, sizeof(HANDLE) * s);
if(!handles)
{
pop_stack();
Pike_error("add_handle: failed to allocate memory.\n");
}
THIS->handles = handles;
}
THIS->handles[THIS->handles_used++] = nh;
pop_stack();
}
|