Chandra
view release on metacpan or search on metacpan
include/chandra/chandra.h view on Meta::CPAN
Stat_t st;
if (name[0] == '.') {
if (name[1] == '\0') continue;
if (name[1] == '.' && name[2] == '\0') continue;
}
fullpath_sv = newSVpvf("%s/%s", dir, name);
fullpv = SvPV(fullpath_sv, fulllen);
if (PerlLIO_stat(fullpv, &st) == 0) {
if (S_ISREG(st.st_mode)) {
(void)hv_store(files_hv, fullpv, (I32)fulllen,
newSVnv((NV)st.st_mtime), 0);
} else if (S_ISDIR(st.st_mode)) {
_hotreload_scan_recursive(aTHX_ fullpv, files_hv);
}
}
SvREFCNT_dec(fullpath_sv);
}
include/chandra/chandra_log.h view on Meta::CPAN
static void
chandra_log_maybe_rotate(pTHX_ chandra_log_ctx *ctx, const char *path)
{
Stat_t st;
int keep, i;
char from[4096], to[4096];
if (ctx->rotate_max_size <= 0)
return;
if (PerlLIO_stat(path, &st) != 0)
return;
if (st.st_size < ctx->rotate_max_size)
return;
keep = ctx->rotate_keep;
if (keep > CHANDRA_LOG_MAX_KEEP)
keep = CHANDRA_LOG_MAX_KEEP;
/* Delete oldest */
snprintf(to, sizeof(to), "%s.%d", path, keep);
include/chandra/chandra_socket_hub.h view on Meta::CPAN
if (listener_svp && SvOK(*listener_svp)) {
if (select_svp && SvOK(*select_svp))
_sock_select_remove(aTHX_ *select_svp, *listener_svp);
_sock_call_void(aTHX_ *listener_svp, "close");
(void)hv_stores(hv, "_listener", newSV(0));
}
if (token_path_svp && SvOK(*token_path_svp)) {
const char *tp = SvPV_nolen(*token_path_svp);
Stat_t st;
if (PerlLIO_stat(tp, &st) == 0)
(void)PerlLIO_unlink(tp);
}
if (sock_path_svp && SvOK(*sock_path_svp)) {
const char *sp = SvPV_nolen(*sock_path_svp);
Stat_t st;
if (PerlLIO_stat(sp, &st) == 0)
(void)PerlLIO_unlink(sp);
}
/* Clean up TCP discovery file (Windows auto-upgrade) */
{
SV **disc_svp = hv_fetchs(hv, "_discovery_path", 0);
if (disc_svp && SvOK(*disc_svp)) {
const char *dp = SvPV_nolen(*disc_svp);
Stat_t st;
if (PerlLIO_stat(dp, &st) == 0)
(void)PerlLIO_unlink(dp);
}
}
}
#endif /* CHANDRA_SOCKET_HUB_H */
include/chandra/chandra_store.h view on Meta::CPAN
size_t len;
#ifdef _WIN32
/* Use Win32 API to avoid Perl's stat/mkdir macro redefinitions */
DWORD attr = GetFileAttributesA(path);
if (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY))
return 0;
#else
{
struct stat st;
if (stat(path, &st) == 0) return 0;
}
#endif
strncpy(tmp, path, sizeof(tmp) - 1);
tmp[sizeof(tmp) - 1] = '\0';
len = strlen(tmp);
if (len > 0 && tmp[len - 1] == '/') tmp[len - 1] = '\0';
#ifdef _WIN32
/* Also handle backslash separators */
if (len > 0 && tmp[len - 1] == '\\') tmp[len - 1] = '\0';
include/chandra/chandra_store.h view on Meta::CPAN
#ifdef _WIN32
{
DWORD a = GetFileAttributesA(tmp);
if (a == INVALID_FILE_ATTRIBUTES || !(a & FILE_ATTRIBUTE_DIRECTORY))
if (!CreateDirectoryA(tmp, NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
return -1;
}
#else
{
struct stat st;
if (stat(tmp, &st) != 0)
if (mkdir(tmp, mode) != 0 && errno != EEXIST) return -1;
}
#endif
*p =
#ifdef _WIN32
'\\';
#else
'/';
#endif
}
lib/Chandra/HotReload.pm view on Meta::CPAN
# Or integrated with App:
$app->watch('lib/', sub {
my ($changed) = @_;
$app->set_content(rebuild());
$app->refresh;
});
$app->run; # automatically polls during event loop
=head1 DESCRIPTION
Chandra::HotReload provides file-system watching via C<stat()> polling.
Register paths (files or directories) to watch along with callbacks
that are invoked whenever a change is detected.
When integrated with L<Chandra::App> via C<< $app->watch() >>, the
event loop automatically switches to non-blocking mode and polls for
file changes between iterations.
=head1 METHODS
=head2 new(%args)
xs/hotreload.xs view on Meta::CPAN
path = SvPV_nolen(path_sv);
/* Validate callback */
if (!SvOK(callback) || SvROK(callback) == 0 || SvTYPE(SvRV(callback)) != SVt_PVCV) {
croak("watch() requires a callback");
}
/* Check path exists */
{
Stat_t st;
if (PerlLIO_stat(path, &st) != 0) {
croak("watch() path does not exist: %s", path);
}
}
/* Scan files via Perl helper */
{
dSP;
int count;
ENTER; SAVETMPS;
PUSHMARK(SP);
xs/hotreload.xs view on Meta::CPAN
SV *self
SV *path_sv
CODE:
{
const char *path = SvPV_nolen(path_sv);
HV *files_hv = newHV();
Stat_t st;
PERL_UNUSED_VAR(self);
if (PerlLIO_stat(path, &st) == 0) {
if (S_ISREG(st.st_mode)) {
/* Single file */
STRLEN plen = SvCUR(path_sv);
(void)hv_store(files_hv, path, (I32)plen, newSVnv((NV)st.st_mtime), 0);
} else if (S_ISDIR(st.st_mode)) {
/* Recursive C directory walk â no File::Find / eval_pv */
_hotreload_scan_recursive(aTHX_ path, files_hv);
}
}
( run in 0.864 second using v1.01-cache-2.11-cpan-39bf76dae61 )