Browse Source

open syscall O_DIR flag

master
Mathieu Serandour 6 months ago
parent
commit
3ea2428cd7
  1. 85
      blib/include/dirent.h
  2. 6
      blib/include/types.h
  3. 110
      blib/include/unistd.h
  4. 95
      blib/src/dirent.c
  5. 26
      kernel/int/syscall.c
  6. 1
      kernel/int/syscall.h

85
blib/include/dirent.h

@ -22,12 +22,12 @@
#ifndef _DIRENT_H
#define _DIRENT_H 1
#ifdef ISSOU_CA_DOIT_PAS_ETRE_DEFINI_CA
#include "unistd.h"
#include <unistd.h>
#include <stddef.h>
#include <types.h>
typedef unsigned long long ino_t;
struct dirent {
ino_t d_ino;
@ -43,27 +43,23 @@ typedef struct DIR DIR;
/* File types for `d_type'. */
enum
{
DT_UNKNOWN = 0,
# define DT_UNKNOWN DT_UNKNOWN
DT_FIFO = 1,
# define DT_FIFO DT_FIFO
DT_CHR = 2,
# define DT_CHR DT_CHR
DT_DIR = 4,
# define DT_DIR DT_DIR
DT_BLK = 6,
# define DT_BLK DT_BLK
DT_REG = 8,
# define DT_REG DT_REG
DT_LNK = 10,
# define DT_LNK DT_LNK
DT_SOCK = 12,
# define DT_SOCK DT_SOCK
DT_WHT = 14
# define DT_WHT DT_WHT
};
// unknown
#define DT_UNKNOWN 0
// directory
#define DT_DIR 3
// block device
#define DT_BLK 4
// regular file
#define DT_REG 5
// syb link
#define DT_LNK 6
// socket
#define DT_SOCK 7
/* Convert between stat structure types and directory types. */
@ -108,18 +104,19 @@ extern struct dirent *readdir (DIR *__dirp);
/* Rewind DIRP to the beginning of the directory. */
extern void rewinddir (DIR *__dirp) __THROW;
extern void rewinddir (DIR *__dirp);
/* Seek to position POS on DIRP. */
extern void seekdir (DIR *__dirp, long int __pos) __THROW;
extern void seekdir (DIR *__dirp, long int __pos);
/* Return the current position of DIRP. */
extern long int telldir (DIR *__dirp) __THROW;
extern long int telldir (DIR *__dirp);
/* Return the file descriptor used by DIRP. */
extern int dirfd (DIR *__dirp) __THROW;
extern int dirfd (DIR *__dirp);
/* `MAXNAMLEN' is the BSD name for what POSIX calls `NAME_MAX'. */
@ -129,8 +126,6 @@ extern int dirfd (DIR *__dirp) __THROW;
# define MAXNAMLEN 255
#endif
#define __need_size_t
#include <stddef.h>
/* Scan the directory DIR, calling SELECTOR on each directory entry.
Entries for which SELECT returns nonzero are individually malloc'd,
@ -139,37 +134,29 @@ extern int dirfd (DIR *__dirp) __THROW;
This function is a cancellation point and therefore not marked with
__THROW. */
# ifndef __USE_FILE_OFFSET64
/*
POSIX 2008
extern int scandir (const char *__restrict __dir,
struct dirent ***__restrict __namelist,
int (*__selector) (const struct dirent *),
int (*__cmp) (const struct dirent **,
const struct dirent **));
/* Similar to `scandir' but a relative DIR name is interpreted relative
to the directory for which DFD is a descriptor.
This function is a cancellation point and therefore not marked with
__THROW. */
extern int scandirat (int __dfd, const char *__restrict __dir,
struct dirent ***__restrict __namelist,
int (*__selector) (const struct dirent *),
int (*__cmp) (const struct dirent **,
const struct dirent **))
__nonnull ((2, 3));
*/
/* Read directory entries from FD into BUF, reading at most NBYTES.
Reading starts at offset *BASEP, and *BASEP is updated with the new
position after reading. Returns the number of bytes read; zero when at
end of directory; or -1 for errors. */
/*
POSIX.1
extern __ssize_t getdirentries (int __fd, char *__restrict __buf,
size_t __nbytes,
__off_t *__restrict __basep)
__THROW __nonnull ((2, 4));
__off_t *__restrict __basep);
*/
#endif
#endif /* dirent.h */
#endif /* dirent.h */

6
blib/include/types.h

@ -0,0 +1,6 @@
#pragma once
typedef unsigned long long ino_t;
typedef unsigned long long off_t;

110
blib/include/unistd.h

@ -3,91 +3,7 @@
#include <stdint.h>
#include <stddef.h>
/* Get values of POSIX options:
If these symbols are defined, the corresponding features are
always available. If not, they may be available sometimes.
The current values can be obtained with `sysconf'.
_POSIX_JOB_CONTROL Job control is supported.
_POSIX_SAVED_IDS Processes have a saved set-user-ID
and a saved set-group-ID.
_POSIX_REALTIME_SIGNALS Real-time, queued signals are supported.
_POSIX_PRIORITY_SCHEDULING Priority scheduling is supported.
_POSIX_TIMERS POSIX.4 clocks and timers are supported.
_POSIX_ASYNCHRONOUS_IO Asynchronous I/O is supported.
_POSIX_PRIORITIZED_IO Prioritized asynchronous I/O is supported.
_POSIX_SYNCHRONIZED_IO Synchronizing file data is supported.
_POSIX_FSYNC The fsync function is present.
_POSIX_MAPPED_FILES Mapping of files to memory is supported.
_POSIX_MEMLOCK Locking of all memory is supported.
_POSIX_MEMLOCK_RANGE Locking of ranges of memory is supported.
_POSIX_MEMORY_PROTECTION Setting of memory protections is supported.
_POSIX_MESSAGE_PASSING POSIX.4 message queues are supported.
_POSIX_SEMAPHORES POSIX.4 counting semaphores are supported.
_POSIX_SHARED_MEMORY_OBJECTS POSIX.4 shared memory objects are supported.
_POSIX_THREADS POSIX.1c pthreads are supported.
_POSIX_THREAD_ATTR_STACKADDR Thread stack address attribute option supported.
_POSIX_THREAD_ATTR_STACKSIZE Thread stack size attribute option supported.
_POSIX_THREAD_SAFE_FUNCTIONS Thread-safe functions are supported.
_POSIX_THREAD_PRIORITY_SCHEDULING
POSIX.1c thread execution scheduling supported.
_POSIX_THREAD_PRIO_INHERIT Thread priority inheritance option supported.
_POSIX_THREAD_PRIO_PROTECT Thread priority protection option supported.
_POSIX_THREAD_PROCESS_SHARED Process-shared synchronization supported.
_POSIX_PII Protocol-independent interfaces are supported.
_POSIX_PII_XTI XTI protocol-indep. interfaces are supported.
_POSIX_PII_SOCKET Socket protocol-indep. interfaces are supported.
_POSIX_PII_INTERNET Internet family of protocols supported.
_POSIX_PII_INTERNET_STREAM Connection-mode Internet protocol supported.
_POSIX_PII_INTERNET_DGRAM Connectionless Internet protocol supported.
_POSIX_PII_OSI ISO/OSI family of protocols supported.
_POSIX_PII_OSI_COTS Connection-mode ISO/OSI service supported.
_POSIX_PII_OSI_CLTS Connectionless ISO/OSI service supported.
_POSIX_POLL Implementation supports `poll' function.
_POSIX_SELECT Implementation supports `select' and `pselect'.
_XOPEN_REALTIME X/Open realtime support is available.
_XOPEN_REALTIME_THREADS X/Open realtime thread support is available.
_XOPEN_SHM Shared memory interface according to XPG4.2.
_XBS5_ILP32_OFF32 Implementation provides environment with 32-bit
int, long, pointer, and off_t types.
_XBS5_ILP32_OFFBIG Implementation provides environment with 32-bit
int, long, and pointer and off_t with at least
64 bits.
_XBS5_LP64_OFF64 Implementation provides environment with 32-bit
int, and 64-bit long, pointer, and off_t types.
_XBS5_LPBIG_OFFBIG Implementation provides environment with at
least 32 bits int and long, pointer, and off_t
with at least 64 bits.
If any of these symbols is defined as -1, the corresponding option is not
true for any file. If any is defined as other than -1, the corresponding
option is true for all files. If a symbol is not defined at all, the value
for a specific file can be obtained from `pathconf' and `fpathconf'.
_POSIX_CHOWN_RESTRICTED Only the super user can use `chown' to change
the owner of a file. `chown' can only be used
to change the group ID of a file to a group of
which the calling process is a member.
_POSIX_NO_TRUNC Pathname components longer than
NAME_MAX generate an error.
_POSIX_VDISABLE If defined, if the value of an element of the
`c_cc' member of `struct termios' is
_POSIX_VDISABLE, no character will have the
effect associated with that element.
_POSIX_SYNC_IO Synchronous I/O may be performed.
_POSIX_ASYNC_IO Asynchronous I/O may be performed.
_POSIX_PRIO_IO Prioritized Asynchronous I/O may be performed.
Support for the Large File Support interface is not generally available.
If it is available the following constants are defined to one.
_LFS64_LARGEFILE Low-level I/O supports large files.
_LFS64_STDIO Standard I/O supports large files.
*/
#include <types.h>
/* Standard file descriptors. */
#define STDIN_FILENO 0 /* Standard input. */
@ -96,8 +12,6 @@
#define __need_size_t
#define __need_NULL
#include <stddef.h>
typedef int pid_t;
@ -569,7 +483,6 @@ int getentropy (void *__buffer, size_t __length) __wur
#endif
typedef uint64_t off_t;
/* Values for the WHENCE argument to lseek. */
@ -688,6 +601,24 @@ extern pid_t getpid (void);
extern pid_t getppid (void);
typedef enum open_flags {
O_RDONLY = 0,
O_WRONLY = 1,
O_RDWR = 2,
O_CREAT = 4,
O_EXCL = 8,
O_TRUNC = 16,
O_APPEND = 32,
O_NONBLOCK = 64,
O_DIRECTORY = 128,
O_NOFOLLOW = 256,
O_DIRECT = 512,
O_NOATIME = 1024,
O_CLOEXEC = 2048,
O_DIR = 4096,
} open_flags_t;
/* Invoke `system call' number SYSNO, passing it the remaining arguments.
This is completely system-dependent, and not often useful.
@ -713,10 +644,9 @@ typedef enum mode_t {
IFDIR = 0x4000,
} mode_t;
int open (const char *pathname, int flags, mode_t mode);
int open (const char *pathname, int flags, mode_t mode);
#endif /* unistd.h */

95
blib/src/dirent.c

@ -1,12 +1,99 @@
#include "dirent.h"
#include <dirent.h>
#include <alloc.h>
#include <stdio.h>
typedef struct DIR {
int fd;
struct dirent* dirent;
// number of elements
size_t len;
// next element to be
// read by vfs_readdir
size_t cur;
struct dirent dirent[0];
// struct dirent dirent_buf;
} DIR;
DIR *opendir (const char* name) {
int fd = open(name, 0, 0);
if(fd < 0) {
return NULL;
}
// read the dir
size_t size = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
if(size % sizeof(struct dirent) != 0) {
return NULL;
}
DIR* dir = malloc(sizeof(DIR) + size);
if(!dir) {
// out of memory
return NULL;
}
size_t n = read(fd, dir->dirent, size);
if(n != size) {
// read error
free(dir);
return NULL;
}
// fill the other fields
dir->fd = fd;
dir->len = size;
dir->cur = 0;
return dir;
}
int closedir (DIR* dirp) {
int fd = dirp->fd;
free(dirp);
return close(fd);
}
struct dirent *readdir (DIR* dirp) {
if(dirp->cur >= dirp->len) {
return NULL;
}
struct dirent* dirent = &dirp->dirent[dirp->cur];
dirp->cur++;
return dirent;
}
void rewinddir (DIR* dirp) {
dirp->cur = 0;
}
void seekdir (DIR* dirp, long int pos) {
dirp->cur = (size_t)pos;
}
/* Return the current position of DIRP. */
long int telldir (DIR* dirp) {
return (long int)dirp->cur;
}
DIR *opendir (const char *__name) {
}
/* Return the file descriptor used by DIRP. */
int dirfd (DIR* dirp) {
return dirp->fd;
}

26
kernel/int/syscall.c

@ -325,14 +325,8 @@ static uint64_t sc_open(process_t* proc, void* args, size_t args_sz) {
file_handle_t* h = vfs_open_file(a->path);
if(h) {
proc->fds[fd].file = h;
proc->fds[fd].type = FD_FILE;
}
else {
// not a file, try opening as a directory
if(a->flags & O_DIR) {
// opening as a directory
struct DIR* dir = vfs_opendir(path);
@ -342,10 +336,24 @@ static uint64_t sc_open(process_t* proc, void* args, size_t args_sz) {
proc->fds[fd].type = FD_DIR;
}
else {
sc_warn("failed to open", args, args_sz);
sc_warn("failed to open dir", args, args_sz);
free(path);
return -1;
}
}
else {
file_handle_t* h = vfs_open_file(a->path);
if(!h) {
sc_warn("failed to open file", args, args_sz);
free(path);
return -1;
}
proc->fds[fd].file = h;
proc->fds[fd].type = FD_FILE;
}

1
kernel/int/syscall.h

@ -58,6 +58,7 @@ typedef enum open_flags {
O_DIRECT = 512,
O_NOATIME = 1024,
O_CLOEXEC = 2048,
O_DIR = 4096,
} open_flags_t;

Loading…
Cancel
Save