Getting File Descriptor in C API

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Getting File Descriptor in C API

Cathal Garvey
Hey all; new member and lua user here so be patient. :)

I'm a newbie C programmer, a fairly experienced Pythonista, and I'm
getting into Lua. So please tailor your answers or analogies to my
competence-levels!

I've been trying to write a C function in order to expose the
posix_fadvise function into Lua, for a specific use-case involving a
device (openpcr.org) that exposes its internal state through a virtual
file on a virtual usb-device. So I *do* have a good reason to disable
disk caching! That'll solve the usual FAQ #1: Don't mess with caching.

What I have looks like this:

<Code>

static int l_posix_fadvise (lua_State *L) {
  int *validfile, *validstart, *validend, *validadvise;
  int nargs = lua_gettop(L);
  const lua_Integer fileno = lua_tointegerx(L, 1, validfile);
  const lua_Integer start = lua_tointegerx(L, 2, validstart);
  const lua_Integer end = lua_tointegerx(L, 3, validend);
  const lua_Integer advise = lua_tointegerx(L, 4, validadvise);
  if (!(*validfile & *validstart & *validend & *validadvise)) {
    lua_pushstring(L, "Incorrect args: all arguments must be numbers.");
    lua_error(L);
  }
  int result = posix_fadvise((int) fileno, (int) start, (int) end,
(int) advise); lua_pushinteger(L, result);
  return 1;
};

</Code>

..this was based on the assumption that file descriptors were always
integers; I'm a C beginner so I've only seen "open" and not "fopen",
which returns a "FILE*" instead.

Problem is, posix_fadvise needs an integer file descriptor, not a FILE*
file descriptor.

I can see from the Lua source that it uses "LStream", and the "f"
property of LStream contains the FILE* returned by fopen?

I also know that if I can access that FILE* item (as a FILE*), then I
can use fileno() to get the file descriptor number, which I can pass to
posix_fadvise?

So, how do I extract the LStream or FILE* data from lua into my C
function? Do I cast a userdata into an LStream like (LStream)
getuserdata? Is there another way to get the file descriptor as an
integer from within lua, so it'll work with my above function without
alteration?

Thanks in advance,
Cathal

signature.asc (853 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Getting File Descriptor in C API

Cathal Garvey
Hi again,
Sorry for the double post. I thought I'd exhausted my ability to search for answers, then discovered the luaposix source had my answer: casting the userdata as a FILE* pointer.

Now, I have a new problem which is all C: fileno won't load from stdio.h, even if I #define __USE_POSIX as the file appears to suggest..

I don't expect answers to my new problem as it's not Lua specific but would still be grateful! :)

Cathal Garvey <[hidden email]> wrote:
Hey all; new member and lua user here so be patient. :)

I'm a newbie C programmer, a fairly experienced Pythonista, and I'm
getting into Lua. So please tailor your answers or analogies to my
competence-levels!

I've been trying to write a C function in order to expose the
posix_fadvise function into Lua, for a specific use-case involving a
device (openpcr.org) that exposes its internal state through a virtual
file on a virtual usb-device. So I *do* have a good reason to disable
disk caching! That'll solve the usual FAQ #1: Don't mess with caching.

What I have looks like this:

<Code>

static int l_posix_fadvise (lua_State *L) {
int *validfile, *validstart, *validend, *validadvise;
int nargs = lua_gettop(L);
const lua_Integer fileno = lua_tointegerx(L, 1, validfile);
const lua_Integer start = lua_tointegerx(L, 2, validstart);
const lua_Integer end = lua_tointegerx(L, 3, validend);
const lua_Integer advise = lua_tointegerx(L, 4, validadvise);
if (!(*validfile & *validstart & *validend & *validadvise)) {
lua_pushstring(L, "Incorrect args: all arguments must be numbers.");
lua_error(L);
}
int result = posix_fadvise((int) fileno, (int) start, (int) end,
(int) advise); lua_pushinteger(L, result);
return 1;
};

</Code>

..this was based on the assumption that file descriptors were always
integers; I'm a C beginner so I've only seen "open" and not "fopen",
which returns a "FILE*" instead.

Problem is, posix_fadvise needs an integer file descriptor, not a FILE*
file descriptor.

I can see from the Lua source that it uses "LStream", and the "f"
property of LStream contains the FILE* returned by fopen?

I also know that if I can access that FILE* item (as a FILE*), then I
can use fileno() to get the file descriptor number, which I can pass to
posix_fadvise?

So, how do I extract the LStream or FILE* data from lua into my C
function? Do I cast a userdata into an LStream like (LStream)
getuserdata? Is there another way to get the file descriptor as an
integer from within lua, so it'll work with my above function without
alteration?

Thanks in advance,
Cathal

--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
Reply | Threaded
Open this post in threaded view
|

Re: Getting File Descriptor in C API

Craig Barnes
> Now, I have a new problem which is all C: fileno won't load from stdio.h,
> even if I #define __USE_POSIX as the file appears to suggest..
>
> I don't expect answers to my new problem as it's not Lua specific but would
> still be grateful! :)

Try this:

   #define _POSIX_C_SOURCE 1

Reply | Threaded
Open this post in threaded view
|

Re: Getting File Descriptor in C API

Cathal Garvey
Thank you craig, that solved it! :)
(Well, that and not shadowing the function by accidentally naming an int "fileno"..)

Craig Barnes <[hidden email]> wrote:
> Now, I have a new problem which is all C: fileno won't load from stdio.h,
even if I #define __USE_POSIX as the file appears to suggest..

I don't expect answers to my new problem as it's not Lua specific but would
still be grateful! :)

Try this:

#define _POSIX_C_SOURCE 1


--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
Reply | Threaded
Open this post in threaded view
|

Re: Getting File Descriptor in C API

Cathal Garvey
Thanks to Craig for the help: I've added the fruits of this fumbling to
a fork of luaposix, found here:
https://github.com/cathalgarvey/luaposix

If you can build and install that, you'll have a new function:
posix.fadvise. Plus, the 6 constants defined for use with same:
POSIX_FADV_XXXX.

Have made pull request, hope to see it in mainline.

Thanks to the devs of lua for making a language that's easily
extendable, so a newcomer to lua can write a new module before he's
written the use-case! :)

On Mon, 25 Nov 2013 20:51:40 +0000
"Cathal Garvey (Phone)" <[hidden email]> wrote:

> Thank you craig, that solved it! :)
> (Well, that and not shadowing the function by accidentally naming an
> int "fileno"..)
>
> Craig Barnes <[hidden email]> wrote:
> >> Now, I have a new problem which is all C: fileno won't load from
> >stdio.h,
> >> even if I #define __USE_POSIX as the file appears to suggest..
> >>
> >> I don't expect answers to my new problem as it's not Lua specific
> >> but
> >would
> >> still be grateful! :)
> >
> >Try this:
> >
> >   #define _POSIX_C_SOURCE 1
>


signature.asc (853 bytes) Download Attachment