Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new interface for creating uninitalized or zero stat objects #10

Merged
merged 2 commits into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 0 additions & 92 deletions .github/workflows/cygwin.yml

This file was deleted.

6 changes: 6 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Revision history for {{$dist->name}}

{{$NEXT}}
- Passing no arguments to new will now return an
uninitialized stat object (gh#9, gh#10)
- Passing undef to clone will now return a stat
object with the memory set to all zeros,
previously the behavior was undefined and could
crash (gh#10)

0.02 2021-05-31 05:48:05 -0600
- Work around possible bug in Perl stat function
Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# FFI::C::Stat ![static](https://github.com/PerlFFI/FFI-C-Stat/workflows/static/badge.svg) ![linux](https://github.com/PerlFFI/FFI-C-Stat/workflows/linux/badge.svg) ![windows](https://github.com/PerlFFI/FFI-C-Stat/workflows/windows/badge.svg) ![macos](https://github.com/PerlFFI/FFI-C-Stat/workflows/macos/badge.svg) ![cygwin](https://github.com/PerlFFI/FFI-C-Stat/workflows/cygwin/badge.svg) ![msys2-mingw](https://github.com/PerlFFI/FFI-C-Stat/workflows/msys2-mingw/badge.svg)
# FFI::C::Stat ![static](https://github.com/PerlFFI/FFI-C-Stat/workflows/static/badge.svg) ![linux](https://github.com/PerlFFI/FFI-C-Stat/workflows/linux/badge.svg) ![windows](https://github.com/PerlFFI/FFI-C-Stat/workflows/windows/badge.svg) ![macos](https://github.com/PerlFFI/FFI-C-Stat/workflows/macos/badge.svg) ![msys2-mingw](https://github.com/PerlFFI/FFI-C-Stat/workflows/msys2-mingw/badge.svg)

Object-oriented FFI interface to native stat and lstat

Expand Down Expand Up @@ -46,10 +46,12 @@ $ffi->attach( my_cfunction => ['stat'] => 'void' );
```perl
my $stat = FFI::C::Stat->new(*HANDLE, %options);
my $stat = FFI::C::Stat->new($filename, %options);
my $stat = FFI::C::Stat->new;
```

You can create a new instance of this class by calling the new method and passing in
either a file or directory handle, or by passing in the filename path.
either a file or directory handle, or by passing in the filename path. If you do
not pass anything then an uninitialized stat will be returned.

Options:

Expand Down Expand Up @@ -91,6 +93,10 @@ $ffi->attach( my_cfunction => [] => 'opaque' => sub {
});
```

The behavior of passing in `undef` prior to version 0.03 was undefined and could cause a
crash. In version 0.03 and later passing in `undef` will return a stat object with all
of the bits set to zero (0).

# PROPERTIES

## dev
Expand Down Expand Up @@ -203,7 +209,7 @@ Graham Ollis <plicease@cpan.org>

# COPYRIGHT AND LICENSE

This software is copyright (c) 2021 by Graham Ollis.
This software is copyright (c) 2021-2023 by Graham Ollis.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
3 changes: 1 addition & 2 deletions dist.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name = FFI-C-Stat
author = Graham Ollis <plicease@cpan.org>
license = Perl_5
copyright_holder = Graham Ollis
copyright_year = 2021-2022
copyright_year = 2021-2023
version = 0.02

[@Author::Plicease]
Expand All @@ -18,7 +18,6 @@ workflow = static
workflow = linux
workflow = windows
workflow = macos
workflow = cygwin
workflow = msys2-mingw

[Author::Plicease::Core]
Expand Down
25 changes: 20 additions & 5 deletions ffi/stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,27 @@ stat___fstat(int fd)
}

struct stat *
stat__clone(struct stat *self)
stat___new(void)
{
struct stat *other;
other = malloc(sizeof(struct stat));
memcpy(other, self, sizeof(struct stat));
return other;
struct stat *self;
self = malloc(sizeof(struct stat));
return self;
}

struct stat *
stat__clone(struct stat *other)
{
struct stat *self;
self = malloc(sizeof(struct stat));
if(other == NULL)
{
memset(self, 0, sizeof(struct stat));
}
else
{
memcpy(self, other, sizeof(struct stat));
}
return self;
}

dev_t
Expand Down
11 changes: 10 additions & 1 deletion lib/FFI/C/Stat.pm
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,19 @@ $ffi->mangler(sub { "stat__$_[0]" });
$ffi->attach( '_stat' => ['string'] => 'opaque' );
$ffi->attach( '_fstat' => ['int', ] => 'opaque' );
$ffi->attach( '_lstat' => ['string'] => 'opaque' );
$ffi->attach( '_new' => [] => 'opaque' );

=head1 CONSTRUCTORS

=head2 new

my $stat = FFI::C::Stat->new(*HANDLE, %options);
my $stat = FFI::C::Stat->new($filename, %options);
my $stat = FFI::C::Stat->new;

You can create a new instance of this class by calling the new method and passing in
either a file or directory handle, or by passing in the filename path.
either a file or directory handle, or by passing in the filename path. If you do
not pass anything then an uninitialized stat will be returned.

Options:

Expand All @@ -87,6 +90,8 @@ sub new
{ $ptr = _fstat(fileno($file)) }
elsif(!is_ref($file) && defined $file)
{ $ptr = $options{symlink} ? _lstat($file) : _stat($file) }
elsif(!defined $file)
{ $ptr = _new() }
else
{ Carp::croak("Tried to stat something whch is neither a glob reference nor a plain string") }

Expand Down Expand Up @@ -120,6 +125,10 @@ Perl:
return FFI::C::Stat->clone($ptr);
});

The behavior of passing in C<undef> prior to version 0.03 was undefined and could cause a
crash. In version 0.03 and later passing in C<undef> will return a stat object with all
of the bits set to zero (0).

=cut

$ffi->attach( clone => ['opaque'] => 'opaque' => sub {
Expand Down
18 changes: 18 additions & 0 deletions t/ffi_c_stat.t
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ is(
'clone a stat',
);

is(
FFI::C::Stat->clone(undef),
object {
call [ isa => 'FFI::C::Stat' ] => T();
call $_ => D() for @props;
},
'clone undef',
);

{
my $other = FFI::C::Stat->new('corpus/xx.txt');
is(
Expand Down Expand Up @@ -122,4 +131,13 @@ if($Config{d_symlink} eq 'define')

unlink 'testlink';

is(
FFI::C::Stat->new,
object {
call [ isa => 'FFI::C::Stat' ] => T();
call $_ => D() for @props;
},
'create uninitalized stat',
);

done_testing;
Loading