#include "fcntl.h"
#include "xos.h"
#include <stdarg.h>
#include <errno.h>
int __attribute__ ((weak, visibility ("default"))) fcntl(int fd, int cmd, ...)
{
va_list ap;
long arg;
va_start(ap, cmd);
arg = va_arg(ap, long);
va_end(ap);
return __syscall_fcntl(fd, cmd, arg);
}
typeof (fcntl) __fcntl __attribute__ ((alias ("fcntl")));
int __attribute__ ((weak, visibility ("default"))) open(const char *path, int oflag, ...)
{
int flags;
int fd;
struct _xos_stat_struct statbuf;
int errnum;
flags = 0;
switch (oflag & O_ACCMODE) {
case O_RDONLY:
flags |= _XOS_O_READ;
break;
case O_RDWR:
flags |= _XOS_O_READ | _XOS_O_WRITE;
break;
case O_WRONLY:
flags |= _XOS_O_WRITE;
break;
}
if ((fd = __syscall_open(path, flags)) != -1) {
if (oflag & O_CREAT && oflag & O_EXCL) {
errnum = EEXIST;
goto error_close;
}
}
else {
if (oflag & O_CREAT && errno == ENOENT) {
if (__syscall_create(path) == -1)
return -1;
if ((fd = __syscall_open(path, flags)) == -1)
return -1;
}
else
return -1;
}
if ((oflag & O_ACCMODE) == O_RDWR || (oflag & O_ACCMODE) == O_WRONLY) {
if (__syscall_stat(fd, &statbuf) == -1) {
errnum = errno;
goto error_close;
}
if (statbuf.type == _XOS_FT_DIR) {
errnum = EISDIR;
goto error_close;
}
if (oflag & O_TRUNC) {
if (__syscall_stat(fd, &statbuf) == -1) {
errnum = errno;
goto error_close;
}
if (statbuf.type == _XOS_FT_REG) {
if (__syscall_close(fd) == -1)
return -1;
if (__syscall_remove(path) == -1)
return -1;
if (__syscall_create(path) == -1)
return -1;
if ((fd = __syscall_open(path, flags)) == -1)
return -1;
}
}
}
return fd;
error_close:
__syscall_close(fd);
errno = errnum;
return -1;
}
typeof (open) __open __attribute__ ((alias ("open")));
int __attribute__ ((weak, visibility ("default"))) creat(const char *path, mode_t mode)
{
return __open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
}
typeof (creat) __creat __attribute__ ((alias ("creat")));