Move fs.basename and fs.dirname into the path library, create errors.h

This commit is contained in:
Jeremy Baxter 2023-08-10 08:14:05 +12:00
parent 18597a772e
commit 7ff02fbbb1
6 changed files with 142 additions and 95 deletions

View file

@ -9,6 +9,7 @@ OBJS = csto.o \
lextra.o \ lextra.o \
lfs.o \ lfs.o \
ljson.o \ ljson.o \
lpath.o \
lprocess.o \ lprocess.o \
lsocket.o \ lsocket.o \
util.o util.o
@ -28,12 +29,13 @@ libcallisto.so: ${LIBS} ${OBJS}
csto.o: csto.c callisto.h csto.o: csto.c callisto.h
callisto.o: callisto.c callisto.h callisto.o: callisto.c callisto.h
lcl.o: lcl.c callisto.h lcl.o: lcl.c callisto.h util.h
lextra.o: lextra.c callisto.h lextra.o: lextra.c callisto.h util.h
lenviron.o: lenviron.c callisto.h lenviron.o: lenviron.c callisto.h
lfs.o: lfs.c callisto.h lfs.o: lfs.c callisto.h errors.h util.h
ljson.o: ljson.c callisto.h ljson.o: ljson.c callisto.h
lprocess.o: lprocess.c callisto.h lpath.o: lpath.c callisto.h errors.h util.h
lprocess.o: lprocess.c callisto.h util.h
lsocket.o: lsocket.c callisto.h lsocket.o: lsocket.c callisto.h
util.o: util.c util.o: util.c

View file

@ -17,6 +17,7 @@ static const luaL_Reg loadedlibs[] = {
{CALLISTO_JSONLIBNAME, luaopen_json}, {CALLISTO_JSONLIBNAME, luaopen_json},
{CALLISTO_MATHLIBNAME, luaopen_math}, {CALLISTO_MATHLIBNAME, luaopen_math},
{CALLISTO_OSLIBNAME, luaopen_os}, {CALLISTO_OSLIBNAME, luaopen_os},
{CALLISTO_PATHLIBNAME, luaopen_path},
{CALLISTO_PROCLIBNAME, luaopen_process}, {CALLISTO_PROCLIBNAME, luaopen_process},
{CALLISTO_SOCKLIBNAME, luaopen_socket}, {CALLISTO_SOCKLIBNAME, luaopen_socket},
{NULL, NULL} {NULL, NULL}

View file

@ -24,6 +24,7 @@
#define CALLISTO_JSONLIBNAME "json" #define CALLISTO_JSONLIBNAME "json"
#define CALLISTO_MATHLIBNAME "math" #define CALLISTO_MATHLIBNAME "math"
#define CALLISTO_OSLIBNAME "os" #define CALLISTO_OSLIBNAME "os"
#define CALLISTO_PATHLIBNAME "path"
#define CALLISTO_PROCLIBNAME "process" #define CALLISTO_PROCLIBNAME "process"
#define CALLISTO_SOCKLIBNAME "socket" #define CALLISTO_SOCKLIBNAME "socket"
@ -34,6 +35,9 @@ int luaopen_environ(lua_State *);
int luaopen_extra(lua_State *); int luaopen_extra(lua_State *);
int luaopen_fs(lua_State *); int luaopen_fs(lua_State *);
int luaopen_json(lua_State *); int luaopen_json(lua_State *);
/* luaopen_math and luaopen_os
* are provided by Lua */
int luaopen_path(lua_State *);
int luaopen_process(lua_State *); int luaopen_process(lua_State *);
int luaopen_socket(lua_State *); int luaopen_socket(lua_State *);

32
errors.h Normal file
View file

@ -0,0 +1,32 @@
/* Error messages */
#ifndef _ERRORS_H_
#define _ERRORS_H_
#define E_PATHNAMETOOLONG "pathname too long"
#define E_WORKDIRNOTVALID "working directory is no longer valid"
#define E_COMPNOTEXIST "component of path does not exist"
#define E_DIRNOTEMPTY "directory not empty"
#define E_MOUNTPOINT "directory is busy"
#define E_NOSUCHDEST "no such file or directory"
#define E_FTRAVERSE "failed to traverse directory"
#define E_NOSUCHDIR "no such directory"
#define E_STICKYDIR "permission denied (sticky directory)"
#define E_INTFAULT "internal error (EFAULT)"
#define E_MVPARENT "cannot move a parent directory of pathname"
#define E_FEXISTS "file exists"
#define E_MAXLINK "maximum link count reached"
#define E_NOSPACE "insufficient space left on file system"
#define E_NOTADIR "pathname or a component of pathname is not a directory"
#define E_SYMLINK "could not translate pathname; too many symbolic links"
#define E_DIFFFS "pathnames are on different file systems"
#define E_DIRDOT "last component of path is '.'"
#define E_ISADIR "cannot move a file to the name of a directory"
#define E_IOERR "I/O error"
#define E_NOMEM "insufficent memory"
#define E_QUOTA "file system quota reached"
#define E_PERM "permission denied"
#define E_ROFS "read-only file system"
#endif

92
lfs.c
View file

@ -21,97 +21,9 @@
#include <lauxlib.h> #include <lauxlib.h>
#include "callisto.h" #include "callisto.h"
#include "errors.h"
#include "util.h" #include "util.h"
/* Error messages */
#define E_PATHNAMETOOLONG "pathname too long"
#define E_WORKDIRNOTVALID "working directory is no longer valid"
#define E_COMPNOTEXIST "component of path does not exist"
#define E_DIRNOTEMPTY "directory not empty"
#define E_MOUNTPOINT "directory is busy"
#define E_NOSUCHDEST "no such file or directory"
#define E_FTRAVERSE "failed to traverse directory"
#define E_NOSUCHDIR "no such directory"
#define E_STICKYDIR "permission denied (sticky directory)"
#define E_INTFAULT "internal error (EFAULT)"
#define E_MVPARENT "cannot move a parent directory of pathname"
#define E_FEXISTS "file exists"
#define E_MAXLINK "maximum link count reached"
#define E_NOSPACE "insufficient space left on file system"
#define E_NOTADIR "pathname or a component of pathname is not a directory"
#define E_SYMLINK "could not translate pathname; too many symbolic links"
#define E_DIFFFS "pathnames are on different file systems"
#define E_DIRDOT "last component of path is '.'"
#define E_ISADIR "cannot move a file to the name of a directory"
#define E_IOERR "I/O error"
#define E_NOMEM "insufficent memory"
#define E_QUOTA "file system quota reached"
#define E_PERM "permission denied"
#define E_ROFS "read-only file system"
/***
* Returns the last component of the given pathname,
* removing any trailing '/' characters. If the given
* path consists entirely of '/' characters, the string
* `"/"` is returned. If *path* is an empty string,
* the string `"."` is returned.
*
* This function may return nil if the given
* pathname exceeds the system's path length
* limit (On most Linux systems this will be 4096).
*
* @function basename
* @usage fs.basename(arg[0])
* @tparam string path The path to process.
*/
static int
fs_basename(lua_State *L)
{
const char *ret;
char *path; /* parameter 1 (string) */
path = strndup(luaL_checkstring(L, 1), lua_rawlen(L, 1));
ret = basename(path);
if (ret == NULL && errno == ENAMETOOLONG) /* check if path is too long */
return lfail(L, E_PATHNAMETOOLONG);
lua_pushstring(L, ret);
return 1;
}
/***
* Returns the parent directory of the pathname
* given. Any trailing '/' characters are not
* counted as part of the directory name.
* If the given path is an empty string or contains
* no '/' characters, the string `"."` is returned,
* signifying the current directory.
*
* This function may return nil if the given
* pathname exceeds the system's path length
* limit (On most Linux systems this will be 4096).
*
* @function dirname
* @usage fs.dirname(arg[0])
* @tparam string path The path to process.
*/
static int
fs_dirname(lua_State *L)
{
const char *ret;
char *path; /* parameter 1 (string) */
path = strndup(luaL_checkstring(L, 1), lua_rawlen(L, 1));
ret = dirname(path);
if (ret == NULL && errno == ENAMETOOLONG) /* check if path is too long */
return lfail(L, E_PATHNAMETOOLONG);
lua_pushstring(L, ret);
return 1;
}
/*** /***
* Returns true if the given pathname exists * Returns true if the given pathname exists
* in the file system, or returns false if it * in the file system, or returns false if it
@ -606,8 +518,6 @@ fs_workdir(lua_State *L)
} }
static const luaL_Reg fslib[] = { static const luaL_Reg fslib[] = {
{"basename", fs_basename},
{"dirname", fs_dirname},
{"exists", fs_exists}, {"exists", fs_exists},
{"mkdir", fs_mkdir}, {"mkdir", fs_mkdir},
{"move", fs_move}, {"move", fs_move},

98
lpath.c Normal file
View file

@ -0,0 +1,98 @@
/***
* File system path manipulation.
* @module path
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <lua.h>
#include <lauxlib.h>
#include "callisto.h"
#include "errors.h"
#include "util.h"
/***
* Returns the last component of the given pathname,
* removing any trailing '/' characters. If the given
* path consists entirely of '/' characters, the string
* `"/"` is returned. If *path* is an empty string,
* the string `"."` is returned.
*
* This function may return nil if the given
* pathname exceeds the system's path length
* limit (On most Linux systems this will be 4096).
*
* @function basename
* @usage path.basename(arg[0])
* @tparam string path The path to process.
*/
static int
path_basename(lua_State *L)
{
const char *ret;
char *path; /* parameter 1 (string) */
path = strndup(luaL_checkstring(L, 1), lua_rawlen(L, 1));
ret = basename(path);
if (ret == NULL && errno == ENAMETOOLONG) /* check if path is too long */
return lfail(L, E_PATHNAMETOOLONG);
lua_pushstring(L, ret);
return 1;
}
/***
* Returns the parent directory of the pathname
* given. Any trailing '/' characters are not
* counted as part of the directory name.
* If the given path is an empty string or contains
* no '/' characters, the string `"."` is returned,
* signifying the current directory.
*
* This function may return nil if the given
* pathname exceeds the system's path length
* limit (On most Linux systems this will be 4096).
*
* @function dirname
* @usage path.dirname(arg[0])
* @tparam string path The path to process.
*/
static int
path_dirname(lua_State *L)
{
const char *ret;
char *path; /* parameter 1 (string) */
path = strndup(luaL_checkstring(L, 1), lua_rawlen(L, 1));
ret = dirname(path);
if (ret == NULL && errno == ENAMETOOLONG) /* check if path is too long */
return lfail(L, E_PATHNAMETOOLONG);
lua_pushstring(L, ret);
return 1;
}
static const luaL_Reg pathlib[] = {
{"basename", path_basename},
{"dirname", path_dirname},
{NULL, NULL}
};
int
luaopen_path(lua_State *L)
{
luaL_newlib(L, pathlib);
return 1;
}