off_t lseek(int fid, off_t offset, int whence) { off_t rc; FILE *file; #if OS_PARM_CHECK /*-------------------------------------------------------------------*/ /* If the file descriptor is invalid, return error. */ /*-------------------------------------------------------------------*/ if (fid < 0 || fid >= FOPEN_MAX) { set_errno(EBADF); return -1; } if (Files[fid].flags & FCB_DIR) { set_errno(EISDIR); return -1; } #endif /*-------------------------------------------------------------------*/ /* Get exclusive access to upper file system. */ /*-------------------------------------------------------------------*/ semPend(FileSysSem, WAIT_FOREVER); /*-------------------------------------------------------------------*/ /* Return error if file is closed. */ /*-------------------------------------------------------------------*/ file = &Files[fid]; if (file->ioctl == NULL) { set_errno(EBADF); semPost(FileSysSem); return -1; } /*-------------------------------------------------------------------*/ /* Acquire exclusive access to lower file system. */ /*-------------------------------------------------------------------*/ file->acquire(file, F_READ | F_WRITE); /*-------------------------------------------------------------------*/ /* Call file system specific FSEEK routine. */ /*-------------------------------------------------------------------*/ rc = (off_t)file->ioctl(file, FSEEK, (long)offset, whence); /*-------------------------------------------------------------------*/ /* Release exclusive access to file systems and return result. */ /*-------------------------------------------------------------------*/ file->release(file, F_READ | F_WRITE); semPost(FileSysSem); return rc; }
int fcntl(int fid, int cmd, ...) { va_list ap; FILE *file; #if OS_PARM_CHECK /*-------------------------------------------------------------------*/ /* If the file descriptor is invalid, return error. */ /*-------------------------------------------------------------------*/ if (fid < 0 || fid >= FOPEN_MAX) { set_errno(EBADF); return -1; } #endif /*-------------------------------------------------------------------*/ /* Get exclusive access to upper file system. */ /*-------------------------------------------------------------------*/ semPend(FileSysSem, WAIT_FOREVER); /*-------------------------------------------------------------------*/ /* Return error if file is closed. */ /*-------------------------------------------------------------------*/ file = &Files[fid]; if (file->ioctl == NULL) { semPost(FileSysSem); set_errno(EBADF); return -1; } /*-------------------------------------------------------------------*/ /* Based on the command, execute the right instructions. */ /*-------------------------------------------------------------------*/ switch (cmd) { case F_DUPFD: { /*---------------------------------------------------------------*/ /* Use the va_arg mechanism to get the argument. */ /*---------------------------------------------------------------*/ va_start(ap, cmd); fid = va_arg(ap, int); va_end(ap); #if OS_PARM_CHECK /*---------------------------------------------------------------*/ /* If the file descriptor is invalid, return error. */ /*---------------------------------------------------------------*/ if (fid < 0 || fid >= FOPEN_MAX) { semPost(FileSysSem); set_errno(EINVAL); return -1; } #endif /*---------------------------------------------------------------*/ /* Look for free file control block identifier >= fid. */ /*---------------------------------------------------------------*/ for (;;) { FILE *file2 = &Files[fid]; /*-------------------------------------------------------------*/ /* Check if file control block is free. */ /*-------------------------------------------------------------*/ if (file2->ioctl == NULL) { /*-----------------------------------------------------------*/ /* Copy previous file control block to new one. */ /*-----------------------------------------------------------*/ *file2 = *file; /*-----------------------------------------------------------*/ /* Acquire exclusive access to lower file system. */ /*-----------------------------------------------------------*/ file2->acquire(file2, F_READ | F_WRITE); /*-----------------------------------------------------------*/ /* Call file system specific DUP routine. */ /*-----------------------------------------------------------*/ file2->ioctl(file2, DUP); /*-----------------------------------------------------------*/ /* Release exclusive access to lower file system. */ /*-----------------------------------------------------------*/ file2->release(file2, F_READ | F_WRITE); break; } /*-------------------------------------------------------------*/ /* If none are free, set errno and break. */ /*-------------------------------------------------------------*/ if (++fid >= FOPEN_MAX) { set_errno(EMFILE); fid = -1; break; } } /*---------------------------------------------------------------*/ /* Release access to upper file system and return result. */ /*---------------------------------------------------------------*/ semPost(FileSysSem); return fid; } case F_SETFL: { int oflag, r_val; /*---------------------------------------------------------------*/ /* Acquire exclusive access to lower file system. */ /*---------------------------------------------------------------*/ file->acquire(file, F_READ | F_WRITE); /*---------------------------------------------------------------*/ /* Use the va_arg mechanism to get the argument. */ /*---------------------------------------------------------------*/ va_start(ap, cmd); oflag = va_arg(ap, int); va_end(ap); /*---------------------------------------------------------------*/ /* Call specific ioctl to set flag. */ /*---------------------------------------------------------------*/ r_val = (int)file->ioctl(file, SET_FL, oflag); /*---------------------------------------------------------------*/ /* Release exclusive access to lower file system. */ /*---------------------------------------------------------------*/ file->release(file, F_READ | F_WRITE); /*---------------------------------------------------------------*/ /* Release access to upper file system and return result. */ /*---------------------------------------------------------------*/ semPost(FileSysSem); return r_val; } case F_GETFL: { int r_val; /*---------------------------------------------------------------*/ /* Acquire exclusive access to lower file system. */ /*---------------------------------------------------------------*/ file->acquire(file, F_READ); /*---------------------------------------------------------------*/ /* Call specific ioctl to get flag. */ /*---------------------------------------------------------------*/ r_val = (int)file->ioctl(file, GET_FL); /*---------------------------------------------------------------*/ /* Release exclusive access to lower file system. */ /*---------------------------------------------------------------*/ file->release(file, F_READ); /*---------------------------------------------------------------*/ /* Release access to upper file system and return result. */ /*---------------------------------------------------------------*/ semPost(FileSysSem); return r_val; } } /*-------------------------------------------------------------------*/ /* An unsupported command was requested. */ /*-------------------------------------------------------------------*/ set_errno(EINVAL); semPost(FileSysSem); return -1; }
int creatn(const char *path, mode_t mode, size_t size) { int rv = -1; void *dir; FILE *file; #if !_PATH_NO_TRUNC char trunc_path[PATH_MAX + 1]; #endif #if OS_PARM_CHECK /*-------------------------------------------------------------------*/ /* If path is NULL, return -1. */ /*-------------------------------------------------------------------*/ if (path == NULL) { set_errno(EFAULT); return -1; } #endif /*-------------------------------------------------------------------*/ /* Acquire exclusive access to upper file system. */ /*-------------------------------------------------------------------*/ semPend(FileSysSem, WAIT_FOREVER); /*-------------------------------------------------------------------*/ /* Find a free file control block and initialize it. */ /*-------------------------------------------------------------------*/ for (file = &Files[0]; file->ioctl; ++file) { /*-----------------------------------------------------------------*/ /* If none are free, return error. */ /*-----------------------------------------------------------------*/ if (file == &Files[FOPEN_MAX - 1]) { set_errno(EMFILE); semPost(FileSysSem); return -1; } } FsInitFCB(file, FCB_FILE); /*-------------------------------------------------------------------*/ /* Ensure path is valid. */ /*-------------------------------------------------------------------*/ dir = FSearch(file, &path, PARENT_DIR); if (dir == NULL) goto end; /*-------------------------------------------------------------------*/ /* If path too long, return error if no truncation, else truncate. */ /*-------------------------------------------------------------------*/ if (strlen(path) > PATH_MAX) { #if _PATH_NO_TRUNC set_errno(ENAMETOOLONG); goto end; #else strncpy(trunc_path, path, PATH_MAX); trunc_path[PATH_MAX] = '\0'; path = trunc_path; #endif } /*-------------------------------------------------------------------*/ /* Acquire exclusive access to lower file system. */ /*-------------------------------------------------------------------*/ file->acquire(file, F_READ | F_WRITE); /*-------------------------------------------------------------------*/ /* Call file system specific CREATN routine. */ /*-------------------------------------------------------------------*/ rv = (int)file->ioctl(file, CREATN, path, mode, size, dir); /*-------------------------------------------------------------------*/ /* Release exclusive access to lower file system. */ /*-------------------------------------------------------------------*/ file->release(file, F_READ | F_WRITE); /*-------------------------------------------------------------------*/ /* Free control block if error, else set return value. */ /*-------------------------------------------------------------------*/ end: if (rv == -1) file->ioctl = NULL; else rv = file - &Files[0]; /*-------------------------------------------------------------------*/ /* Release exclusive access to upper file system and return result. */ /*-------------------------------------------------------------------*/ semPost(FileSysSem); return rv; }
int write(int fid, const void *buf, unsigned int nbytes) { int written; FILE *file; #if OS_PARM_CHECK /*-------------------------------------------------------------------*/ /* Ensure file descriptor is valid. */ /*-------------------------------------------------------------------*/ if (fid < 0 || fid >= FOPEN_MAX) { set_errno(EBADF); return -1; } /*-------------------------------------------------------------------*/ /* Return error if buffer pointer is invalid. */ /*-------------------------------------------------------------------*/ if (buf == NULL) { Files[fid].errcode = EFAULT; set_errno(EFAULT); return -1; } #endif /*-------------------------------------------------------------------*/ /* Acquire exclusive write access to stream. */ /*-------------------------------------------------------------------*/ file = &Files[fid]; file->acquire(file, F_WRITE); /*-------------------------------------------------------------------*/ /* Return error if file is closed. */ /*-------------------------------------------------------------------*/ if (file->ioctl == NULL) { set_errno(EBADF); file->release(file, F_WRITE); return -1; } /*-------------------------------------------------------------------*/ /* Call file system specific write routine. */ /*-------------------------------------------------------------------*/ written = file->write(file, buf, nbytes); /*-------------------------------------------------------------------*/ /* Set file's errno if less than requested number was written. */ /*-------------------------------------------------------------------*/ if (written < (int)nbytes) { file->errcode = get_errno(); if (written == 0) written = -1; } /*-------------------------------------------------------------------*/ /* Release exclusive write access to stream. */ /*-------------------------------------------------------------------*/ file->release(file, F_WRITE); /*-------------------------------------------------------------------*/ /* Return -1 or actual number of bytes read. */ /*-------------------------------------------------------------------*/ return written; }
int read(int fid, void *buf, unsigned int nbytes) { int hchar = 0, read = 0; FILE *file; /*-------------------------------------------------------------------*/ /* If number of requested bytes is zero, return zero. */ /*-------------------------------------------------------------------*/ if (nbytes == 0) return 0; #if OS_PARM_CHECK /*-------------------------------------------------------------------*/ /* Ensure file descriptor is valid. */ /*-------------------------------------------------------------------*/ if (fid < 0 || fid >= FOPEN_MAX) { set_errno(EBADF); return -1; } /*-------------------------------------------------------------------*/ /* Return error if buffer pointer is invalid. */ /*-------------------------------------------------------------------*/ if (buf == NULL) { Files[fid].errcode = EFAULT; set_errno(EFAULT); return -1; } #endif /*-------------------------------------------------------------------*/ /* Acquire exclusive read access to file. */ /*-------------------------------------------------------------------*/ file = &Files[fid]; file->acquire(file, F_READ); /*-------------------------------------------------------------------*/ /* Return error if file is closed. */ /*-------------------------------------------------------------------*/ if (file->ioctl == NULL) { set_errno(EBADF); file->release(file, F_READ); return -1; } /*-------------------------------------------------------------------*/ /* If available, read pushed-back character first. */ /*-------------------------------------------------------------------*/ if (file->hold_char) { ui8 *cp = buf; *cp = (ui8)file->hold_char; buf = cp + 1; file->hold_char = 0; hchar = 1; --nbytes; } /*-------------------------------------------------------------------*/ /* Check if there are more characters to read. */ /*-------------------------------------------------------------------*/ if (nbytes) { /*-----------------------------------------------------------------*/ /* Pass read request to file system or device driver. */ /*-----------------------------------------------------------------*/ read = file->read(file, buf, nbytes); /*-----------------------------------------------------------------*/ /* Read error is disregarded iff pushed-back character was read. */ /*-----------------------------------------------------------------*/ if (read == -1) { if (hchar) read = 0; else file->errcode = get_errno(); } } /*-------------------------------------------------------------------*/ /* Release exclusive read access to file. */ /*-------------------------------------------------------------------*/ file->release(file, F_READ); /*-------------------------------------------------------------------*/ /* Return number of bytes successfully read or -1. */ /*-------------------------------------------------------------------*/ return read + hchar; }