/* Copyright (C) 2008 Emmanuel Varoquaux
This file is part of XOS.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see . */
#include "fcntl.h"
#include "xos.h"
#include
#include
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")));