/* 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")));