Beispiel #1
0
/*
 * Arguments: path (string)
 * Returns: [boolean]
 */
static int
sys_rmdir (lua_State *L)
{
  const char *path = luaL_checkstring(L, 1);
  int res;

#ifndef _WIN32
  sys_vm_leave(L);
  res = rmdir(path);
  sys_vm_enter(L);
#else
  {
    void *os_path = utf8_to_filename(path);
    if (!os_path)
      return sys_seterror(L, ERROR_NOT_ENOUGH_MEMORY);

    sys_vm_leave(L);
    res = is_WinNT
     ? !RemoveDirectoryW(os_path)
     : !RemoveDirectoryA(os_path);

    free(os_path);
    sys_vm_enter(L);
  }
#endif
  if (!res) {
    lua_pushboolean(L, 1);
    return 1;
  }
  return sys_seterror(L, 0);
}
Beispiel #2
0
EVQ_API int
evq_add_dirwatch (struct event_queue *evq, struct event *ev, const char *path)
{
    const DWORD flags = FILE_NOTIFY_CHANGE_FILE_NAME
     | FILE_NOTIFY_CHANGE_DIR_NAME
     | FILE_NOTIFY_CHANGE_ATTRIBUTES
     | FILE_NOTIFY_CHANGE_SIZE
     | FILE_NOTIFY_CHANGE_LAST_WRITE
     | FILE_NOTIFY_CHANGE_CREATION
     | FILE_NOTIFY_CHANGE_SECURITY;
    const unsigned int filter = (ev->flags >> EVENT_EOF_SHIFT_RES)
     ? FILE_NOTIFY_CHANGE_LAST_WRITE : flags;
    HANDLE fd;

    ev->flags &= ~EVENT_EOF_MASK_RES;

    {
	void *os_path = utf8_to_filename(path);
	if (!os_path)
	    return -1;

	fd = is_WinNT
	 ? FindFirstChangeNotificationW(os_path, FALSE, filter)
	 : FindFirstChangeNotificationA(os_path, FALSE, filter);

	free(os_path);
    }
    if (fd == NULL || fd == INVALID_HANDLE_VALUE)
	return -1;

    ev->fd = fd;
    return evq_add(evq, ev);
}
Beispiel #3
0
/*
 * Arguments: path (string), [permissions (number)]
 * Returns: [boolean]
 */
static int
sys_mkdir (lua_State *L)
{
  const char *path = luaL_checkstring(L, 1);
  int res;

#ifndef _WIN32
  mode_t perm = (mode_t) lua_tointeger(L, 2);

  sys_vm_leave(L);
  res = mkdir(path, perm);
  sys_vm_enter(L);
#else
  {
    void *os_path = utf8_to_filename(path);
    if (!os_path)
      return sys_seterror(L, ERROR_NOT_ENOUGH_MEMORY);

    sys_vm_leave(L);
    res = is_WinNT
     ? !CreateDirectoryW(os_path, NULL)
     : !CreateDirectoryA(os_path, NULL);

    free(os_path);
    sys_vm_enter(L);
  }
#endif
  if (!res) {
    lua_pushboolean(L, 1);
    return 1;
  }
  return sys_seterror(L, 0);
}
Beispiel #4
0
/*
 * Arguments: [path (string)]
 * Returns: [boolean | pathname (string)]
 */
static int
sys_curdir (lua_State *L)
{
  const char *path = lua_tostring(L, 1);

  if (path) {
    int res;
#ifndef _WIN32
    res = chdir(path);
#else
    {
      void *os_path = utf8_to_filename(path);
      if (!os_path)
        return sys_seterror(L, ERROR_NOT_ENOUGH_MEMORY);

      res = is_WinNT
       ? !SetCurrentDirectoryW(os_path)
       : !SetCurrentDirectoryA(os_path);

      free(os_path);
    }
#endif
    if (!res) {
      lua_pushboolean(L, 1);
      return 1;
    }
  } else {
#ifndef _WIN32
    char dir[MAX_PATHNAME];

    if (getcwd(dir, MAX_PATHNAME)) {
      lua_pushstring(L, dir);
      return 1;
    }
#else
    WCHAR os_dir[MAX_PATHNAME];
    const int n = is_WinNT
     ? GetCurrentDirectoryW(MAX_PATHNAME, os_dir)
     : GetCurrentDirectoryA(MAX_PATHNAME, (char *) os_dir);

    if (n != 0 && n < MAX_PATHNAME) {
      void *dir = filename_to_utf8(os_dir);
      if (!dir)
        return sys_seterror(L, ERROR_NOT_ENOUGH_MEMORY);

      lua_pushstring(L, dir);
      free(dir);
      return 1;
    }
#endif
  }
  return sys_seterror(L, 0);
}
Beispiel #5
0
/*
 * Arguments: path (string)
 * Returns: [total_bytes (number), available_bytes (number),
 *	free_bytes (number)]
 */
static int
sys_statfs (lua_State *L)
{
  const char *path = luaL_checkstring(L, 1);
  int64_t ntotal, navail, nfree;
  int res;

#ifndef _WIN32
  struct statvfs buf;

  sys_vm_leave(L);
  res = statvfs(path, &buf);
  sys_vm_enter(L);

  ntotal = buf.f_blocks * buf.f_frsize;
  nfree = buf.f_bfree * buf.f_bsize;
  navail = buf.f_bavail * buf.f_bsize;
#else
  ULARGE_INTEGER na, nt, nf;

  SetErrorMode(SEM_FAILCRITICALERRORS);  /* for floppy disks */
  {
    void *os_path = utf8_to_filename(path);
    if (!os_path)
      return sys_seterror(L, ERROR_NOT_ENOUGH_MEMORY);

    sys_vm_leave(L);
    res = is_WinNT
     ? !GetDiskFreeSpaceExW(os_path, &na, &nt, &nf)
     : !GetDiskFreeSpaceExA(os_path, &na, &nt, &nf);

    free(os_path);
    sys_vm_enter(L);
  }

  ntotal = (int64_t) nt.QuadPart;
  nfree = (int64_t) nf.QuadPart;
  navail = (int64_t) na.QuadPart;
#endif
  if (!res) {
    lua_pushnumber(L, (lua_Number) ntotal);
    lua_pushnumber(L, (lua_Number) navail);
    lua_pushnumber(L, (lua_Number) nfree);
    return 3;
  }
  return sys_seterror(L, 0);
}
Beispiel #6
0
/*
 * Arguments: fd_udata, path (string), [permissions (number)]
 * Returns: [fd_udata]
 */
static int
sys_create (lua_State *L)
{
  fd_t fd, *fdp = checkudata(L, 1, FD_TYPENAME);
  const char *path = luaL_checkstring(L, 2);
#ifndef _WIN32
  mode_t perm = (mode_t) luaL_optinteger(L, 3, SYS_FILE_PERMISSIONS);
#endif

#ifndef _WIN32
  sys_vm_leave(L);
  fd = creat(path, perm);
  sys_vm_enter(L);
#else
  {
    const int flags = GENERIC_WRITE;
    const DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE
     | FILE_SHARE_DELETE;
    const DWORD creation = CREATE_ALWAYS;
    const DWORD attr = FILE_ATTRIBUTE_NORMAL
     | SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION;

    void *os_path = utf8_to_filename(path);
    if (!os_path)
      return sys_seterror(L, ERROR_NOT_ENOUGH_MEMORY);

    sys_vm_leave(L);
    fd = is_WinNT
     ? CreateFileW(os_path, flags, share, NULL, creation, attr, NULL)
     : CreateFileA(os_path, flags, share, NULL, creation, attr, NULL);

    free(os_path);
    sys_vm_enter(L);
  }
#endif

  if (fd != (fd_t) -1) {
    *fdp = fd;
    lua_settop(L, 1);
    return 1;
  }
  return sys_seterror(L, 0);
}
Beispiel #7
0
/*
 * Arguments: path (string)
 * Returns: [string]
 */
static int
sys_realpath (lua_State *L)
{
  const char *path = luaL_checkstring(L, 1);

#ifndef _WIN32
  char real[PATH_MAX];

  if (realpath(path, real)) {
    lua_pushstring(L, real);
    return 1;
  }
#else
  void *os_path = utf8_to_filename(path);
  if (!os_path)
    return sys_seterror(L, ERROR_NOT_ENOUGH_MEMORY);

  {
    WCHAR os_real[MAX_PATHNAME];
    const int n = is_WinNT
     ? GetFullPathNameW(os_path, MAX_PATHNAME, os_real, NULL)
     : GetFullPathNameA(os_path, MAX_PATHNAME, (char *) os_real, NULL);

    free(os_path);

    if (n != 0 && n < MAX_PATHNAME) {
      void *real = filename_to_utf8(os_real);
      if (!real)
        return sys_seterror(L, ERROR_NOT_ENOUGH_MEMORY);

      lua_pushstring(L, real);
      free(real);
      return 1;
    }
  }
#endif
  return sys_seterror(L, 0);
}
Beispiel #8
0
/*
 * Arguments: existing_path (string), new_path (string)
 * Returns: [boolean]
 */
static int
sys_rename (lua_State *L)
{
  const char *old = luaL_checkstring(L, 1);
  const char *new = luaL_checkstring(L, 2);
  int res;

#ifndef _WIN32
  sys_vm_leave(L);
  res = rename(old, new);
  sys_vm_enter(L);
#else
  {
    void *os_old = utf8_to_filename(old);
    void *os_new = utf8_to_filename(new);
    if (!os_old || !os_new) {
      free(os_old);
      free(os_new);
      return sys_seterror(L, ERROR_NOT_ENOUGH_MEMORY);
    }

    sys_vm_leave(L);
    res = is_WinNT
     ? !MoveFileW(os_old, os_new)
     : !MoveFileA(os_old, os_new);

    free(os_old);
    free(os_new);
    sys_vm_enter(L);
  }
#endif

  if (!res) {
    lua_pushboolean(L, 1);
    return 1;
  }
  return sys_seterror(L, 0);
}
Beispiel #9
0
/*
 * Arguments: ..., directory (string)
 */
static int
sys_dir_open (lua_State *L, const int idx, struct dir *dp)
{
  const char *dir = luaL_checkstring(L, idx);

#ifndef _WIN32
  if (dp->data)
    closedir(dp->data);

  sys_vm_leave(L);
  dp->data = opendir(*dir == '\0' ? "/" : dir);
  sys_vm_enter(L);

  if (dp->data) return 1;
#else
  char *filename = (char *) dp->data.cFileName;

  if (*dir == '\0' || (*dir == '/' && dir[1] == '\0')) {
    /* list drive letters */
    *filename++ = 'A' - 1;
    *filename++ = ':';
    *filename++ = '\\';
    *filename = '\0';

    dp->is_root = 1;
    return 1;
  } else {
    const int len = lua_rawlen(L, idx);

    /* build search path */
    if (len >= MAX_PATH - 2)  /* concat "\\*" */
      return 0;
    memcpy(filename, dir, len);
    filename += len - 1;
    if (*filename != '\\' && *filename != '/')
      *(++filename) = '\\';
    *(++filename) = '*';
    *(++filename) = '\0';

    if (dp->h != INVALID_HANDLE_VALUE)
      FindClose(dp->h);

    {
      void *os_path = utf8_to_filename((char *) dp->data.cFileName);
      if (!os_path)
        return sys_seterror(L, ERROR_NOT_ENOUGH_MEMORY);

      sys_vm_leave(L);
      dp->h = is_WinNT
       ? FindFirstFileW(os_path, &dp->data)
       : FindFirstFileA(os_path, (WIN32_FIND_DATAA *) &dp->data);

      free(os_path);
      sys_vm_enter(L);
    }

    if (dp->h != INVALID_HANDLE_VALUE) {
      dp->is_root = 0;
      return 1;
    }
  }
#endif
  return sys_seterror(L, 0);
}
Beispiel #10
0
/*
 * Arguments: path (string), [more_info (boolean)]
 * Returns: [is_directory (boolean), is_file (boolean),
 *	is_read (boolean), is_write (boolean), is_execute (boolean),
 *	[is_link (boolean), size (number),
 *	access_time (number), modify_time (number), create_time (number)]]
 */
static int
sys_stat (lua_State *L)
{
  const char *path = luaL_checkstring(L, 1);
  const int more_info = lua_toboolean(L, 2);
#ifndef _WIN32
  struct stat st;
#else
  struct _stat st;
#endif
  int res;

  sys_vm_leave(L);
#ifndef _WIN32
  res = stat(path, &st);
#else
  {
    void *os_path = utf8_to_filename(path);
    if (!os_path)
      return sys_seterror(L, ERROR_NOT_ENOUGH_MEMORY);

    res = is_WinNT ? _wstat(os_path, &st) : _stat(os_path, &st);

    free(os_path);
  }
#endif
  sys_vm_enter(L);

  if (!res) {
    /* is directory? */
    lua_pushboolean(L,
#ifndef _WIN32
     S_ISDIR(st.st_mode)
#else
     st.st_mode & _S_IFDIR
#endif
    );
    /* is regular file? */
    lua_pushboolean(L,
#ifndef _WIN32
     S_ISREG(st.st_mode)
#else
     st.st_mode & _S_IFREG
#endif
    );
    /* can anyone read from file? */
    lua_pushboolean(L,
#ifndef _WIN32
     st.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)
#else
     st.st_mode & _S_IREAD
#endif
    );
    /* can anyone write to file? */
    lua_pushboolean(L,
#ifndef _WIN32
     st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)
#else
     st.st_mode & _S_IWRITE
#endif
    );
    /* can anyone execute the file? */
    lua_pushboolean(L,
#ifndef _WIN32
     st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)
#else
     st.st_mode & _S_IEXEC
#endif
    );
    if (more_info) {
      /* is link? */
#ifndef _WIN32
      lua_pushboolean(L, S_ISLNK(st.st_mode));
#else
      DWORD attr;
      {
        void *os_path = utf8_to_filename(path);
        if (!os_path)
          return sys_seterror(L, ERROR_NOT_ENOUGH_MEMORY);

        attr = is_WinNT
         ? GetFileAttributesW(os_path)
         : GetFileAttributesA(os_path);

        free(os_path);
      }
      lua_pushboolean(L,
       attr > 0 && (attr & FILE_ATTRIBUTE_REPARSE_POINT));
#endif
      lua_pushnumber(L, (lua_Number) st.st_size);  /* size in bytes */
      lua_pushnumber(L, (lua_Number) st.st_atime);  /* access time */
      lua_pushnumber(L, (lua_Number) st.st_mtime);  /* modification time */
      lua_pushnumber(L, (lua_Number) st.st_ctime);  /* creation time */
      return 10;
    }
    return 5;
  }
  return sys_seterror(L, 0);
}
Beispiel #11
0
/*
 * Arguments: fd_udata, path (string), [mode (string: "r", "w", "rw"),
 *	permissions (number), options (string) ...]
 * Returns: [fd_udata]
 */
static int
sys_open (lua_State *L)
{
    fd_t fd, *fdp = checkudata(L, 1, FD_TYPENAME);
    const char *path = luaL_checkstring(L, 2);
    const char *mode = lua_tostring(L, 3);
#ifndef _WIN32
    mode_t perm = (mode_t) luaL_optinteger(L, 4, SYS_FILE_PERMISSIONS);
#else
    int append = 0;
#endif
    int flags = O_RDONLY, i;

#undef OPT_START
#define OPT_START	5

    if (mode) {
	switch (mode[0]) {
	case 'w': flags = O_WRONLY; break;
	case 'r': if (mode[1] == 'w') flags = O_RDWR;
	}
    }
#ifndef _WIN32
    for (i = lua_gettop(L); i >= OPT_START; --i) {
	flags |= fdopt_flags[luaL_checkoption(L, i, NULL, fdopt_names)];
    }

    sys_vm_leave();
    fd = open(path, flags, perm);
    sys_vm_enter();
#else
    {
	DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE;
	DWORD creation = OPEN_EXISTING;
	DWORD attr = FILE_ATTRIBUTE_NORMAL
	 | SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION;

	for (i = lua_gettop(L); i >= OPT_START; --i) {
	    const char *opt = lua_tostring(L, i);
	    if (opt)
		switch (opt[0]) {
		case 'a':	/* append */
		    append = 1;
		    break;
		case 'c':	/* creat */
		    creation &= ~OPEN_EXISTING;
		    creation |= CREATE_ALWAYS;
		    break;
		case 'e':	/* excl */
		    share = 0;
		    break;
		case 'r':	/* random */
		    attr |= FILE_FLAG_RANDOM_ACCESS;
		    break;
		case 's':	/* sync */
		    attr |= FILE_FLAG_WRITE_THROUGH;
		    break;
		case 't':	/* trunc */
		    creation &= ~OPEN_EXISTING;
		    creation |= TRUNCATE_EXISTING;
		    break;
		}
	}

	{
	    void *os_path = utf8_to_filename(path);
	    if (!os_path)
		return sys_seterror(L, ERROR_NOT_ENOUGH_MEMORY);

	    sys_vm_leave();
	    fd = is_WinNT
	     ? CreateFileW(os_path, flags, share, NULL, creation, attr, NULL)
	     : CreateFileA(os_path, flags, share, NULL, creation, attr, NULL);

	    free(os_path);
	    sys_vm_enter();
	}
    }
#endif
    if (fd != (fd_t) -1) {
	*fdp = fd;
#ifdef _WIN32
	if (append) {
	    LONG off_hi = 0L;
	    SetFilePointer(fd, 0L, &off_hi, SEEK_END);
	}
#endif
	lua_settop(L, 1);
	return 1;
    }
    return sys_seterror(L, 0);
}