This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.
The fourth edition targets Lua 5.3 and is available at Amazon and other bookstores.
By buying the book, you also help to support the Lua project.

26.1 – C Functions

As a first example, let us see how to implement a simplified version of a function that returns the sine of a given number (a more professional implementation should check whether its argument is a number):

```    static int l_sin (lua_State *L) {
double d = lua_tonumber(L, 1);  /* get argument */
lua_pushnumber(L, sin(d));  /* push result */
return 1;  /* number of results */
}
```
Any function registered with Lua must have this same prototype, defined as `lua_CFunction` in `lua.h`:
```    typedef int (*lua_CFunction) (lua_State *L);
```
From the point of view of C, a C function gets as its single argument the Lua state and returns (in C) an integer with the number of values it is returning (in Lua). Therefore, the function does not need to clear the stack before pushing its results. After it returns, Lua automatically removes whatever is in the stack below the results.

Before we can use this function from Lua, we must register it. We do this magic with `lua_pushcfunction`: It gets a pointer to a C function and creates a value of type `"function"` to represent this function inside Lua. A quick-and-dirty way to test `l_sin` is to put its code directly into the file `lua.c` and add the following lines right after the call to `lua_open`:

```    lua_pushcfunction(l, l_sin);
lua_setglobal(l, "mysin");
```
The first line pushes a value of type function. The second line assigns it to the global variable `mysin`. After these modifications, you rebuild your Lua executable; then you can use the new function `mysin` in your Lua programs. In the next section, we will discuss better ways to link new C functions with Lua.

For a more professional sine function, we must check the type of its argument. Here, the auxiliary library helps us. The `luaL_checknumber` function checks whether a given argument is a number: In case of errors, it throws an informative error message; otherwise, it returns the number. The modification in our function is minimal:

```    static int l_sin (lua_State *L) {
double d = luaL_checknumber(L, 1);
lua_pushnumber(L, sin(d));
return 1;  /* number of results */
}
```
With the above definition, if you call `mysin('a')`, you get the message
```    bad argument #1 to `mysin' (number expected, got string)
```
Notice how `luaL_checknumber` automatically fills the message with the argument number (1), the function name (`"mysin"`), the expected parameter type (`"number"`), and the actual parameter type (`"string"`).

As a more complex example, let us write a function that returns the contents of a given directory. Lua does not provide this function in its standard libraries, because ANSI C does not have functions for this job. Here, we will assume that we have a POSIX compliant system. Our function, `dir`, gets as argument a string with the directory path and returns an array with the directory entries. For instance, a call `dir("/home/lua")` may return the table `{".", "..", "src", "bin", "lib"}`. In case of errors, the function returns nil plus a string with the error message.

```    #include <dirent.h>
#include <errno.h>

static int l_dir (lua_State *L) {
DIR *dir;
struct dirent *entry;
int i;
const char *path = luaL_checkstring(L, 1);

/* open directory */
dir = opendir(path);
if (dir == NULL) {  /* error opening the directory? */
lua_pushnil(L);  /* return nil and ... */
lua_pushstring(L, strerror(errno));  /* error message */
return 2;  /* number of results */
}

/* create result table */
lua_newtable(L);
i = 1;
while ((entry = readdir(dir)) != NULL) {
lua_pushnumber(L, i++);  /* push key */
lua_pushstring(L, entry->d_name);  /* push value */
lua_settable(L, -3);
}

closedir(dir);
return 1;  /* table is already on top */
}
```
The `luaL_checkstring` function, from the auxiliary library, is the equivalent of `luaL_checknumber` for strings.

(In extreme conditions, that implementation of `l_dir` may cause a small memory leak. Three of the Lua functions it calls can fail due to insufficient memory: `lua_newtable`, `lua_pushstring`, and `lua_settable`. If any of these calls fails, it will raise an error and interrupt `l_dir`, which therefore will not call `closedir`. As we discussed earlier, on most programs this is not a big problem: If the program runs out of memory, the best it can do is to shut down anyway. Nevertheless, in Chapter 29 we will see an alternative implementation for a directory function that avoids this problem.)