/* * Cross Development System for Atari ST * Copyright (c) 1988, Memorial University of Newfoundland * * Tries to emulate unix open3. The mode argument is ignored, and O_NDELAY * doesn't do anything. Also O_APPEND does not garentee that things will * be written to the end - all we can do is seek to the end to start with. * * The above comments are no longer (necessarily) accurate; this file * has been extensively modified by jrd, ers, jrb, and others. See ChangeLog * for some of the details. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "symdir.h" #include "lib.h" int __umask = 0; #ifdef __STDC__ int open(const char *_path, int flags, ...) #else int open(_path, flags) const char *_path; int flags; #endif { int fd, ifd; int exists; char path[FILENAME_MAX]; unsigned short create_mode = 0; int name_munged; struct _device *dev; unsigned int mode; va_list argp; va_start(argp,flags); mode = ((unsigned int)(va_arg(argp, int))) & ~__umask; /* convert Unix style filename to GEMDOS style */ /* if the name gets munged, _unx2dos will return _NM_CHANGE, * and will copy the original name to the global array __link_name[] */ name_munged = _unx2dos(_path, path); if (name_munged == _NM_DEV && (dev = _dev_dosname(path)) && dev->open) { return (*dev->open)(path, flags, mode); } switch (flags & 0x3) { case O_RDONLY: fd = Fopen(path, O_RDONLY); break; case O_WRONLY: case O_RDWR: fd = 0; exists = Fattrib(path, 0, 0) >= 0; if (flags & O_CREAT) { if ((flags & O_EXCL) && exists) fd = - EEXIST; } else if (!exists) fd = - ENOENT; if (!fd) { if ((flags & O_TRUNC) || !exists) { if (!(mode & S_IREAD)) create_mode |= FA_HIDDEN; if (!(mode & S_IWRITE)) create_mode |= FA_RDONLY; fd = Fcreate(path, create_mode); if (fd >= 0) { if (name_munged == _NM_CHANGE) _make_autolink(path, __link_name); if ((flags & 0x3) == O_RDWR) { (void) Fclose(fd); fd = Fopen(path, O_RDWR); } } } else { if ((fd = Fopen(path, flags & 0x3)) >= 0 && (flags & O_APPEND)) (void) lseek(fd, 0L, SEEK_END); } } break; default: fd = - EINVAL; } if (fd < __SMALLEST_VALID_HANDLE) { errno = - fd; fd = __SMALLEST_VALID_HANDLE - 1; return fd; } ifd = __OPEN_INDEX(fd); assert(( ((ifd >= 0) && (ifd < __NHANDLES)) && (__open_stat[ifd].status == FH_UNKNOWN) )); if(flags & O_NDELAY) __open_stat[ifd].nodelay = 1; if(flags & O_APPEND) __open_stat[ifd].append = 1; if(flags & O_PIPE) __open_stat[ifd].pipe = 1; if((__open_stat[ifd].filename = strdup(path)) == NULL) { int tmp = errno; __open_stat[ifd].status = FH_UNKNOWN; (void)close(fd); if((!exists) && (flags & O_CREAT)) /* if we created a file */ (void)unlink(path); errno = tmp; fd = __SMALLEST_VALID_HANDLE - 1; } return fd; } int creat(name, mode) const char *name; unsigned mode; { return open(name, O_WRONLY|O_CREAT|O_TRUNC, mode); } /* umask -- change default file creation mask */ int umask(complmode) int complmode; { int old_umask = __umask; __umask = complmode; return old_umask; }