/* Copyright (C) 2014 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */ /* * File llseek.c. * * Copyright (C) 2000 Martin Str@"omberg . * * This software may be used freely so long as this copyright notice is * left intact. There is no warranty on this software. * */ #include #include #include #include #include #include #include #include #include offset_t llseek( int handle, offset_t offset, int whence ) { __dpmi_regs r = {0}; int has_props; __FSEXT_Function *func = __FSEXT_get_function(handle); if (func) { int rv; if (__FSEXT_func_wrapper(func, __FSEXT_llseek, &rv, handle, offset, whence)) return rv; } has_props = __has_fd_properties(handle); /* Directory? If so, we're done. */ if (has_props && (__fd_properties[handle]->flags & FILE_DESC_DIRECTORY)) return 0; /* POSIX doesn't allow seek on a pipe. */ if (has_props && (__fd_properties[handle]->flags & FILE_DESC_PIPE)) { errno = ESPIPE; return -1; } r.h.ah = 0x42; r.h.al = whence; r.x.bx = handle; r.x.cx = offset >> 16; r.x.dx = offset & 0xffff; __dpmi_int(0x21, &r); if (r.x.flags & 1) { errno = __doserr_to_errno(r.x.ax); return -1; } if (!has_props || (__fd_properties[handle]->flags & FILE_DESC_DONT_FILL_EOF_GAP) == 0) { if (offset > 0) { if (!has_props) has_props = (__set_fd_properties(handle, NULL, 0) == 0); if (has_props) __set_fd_flags(handle, FILE_DESC_ZERO_FILL_EOF_GAP); } else if (has_props && (whence == SEEK_SET || whence == SEEK_END)) __clear_fd_flags(handle, FILE_DESC_ZERO_FILL_EOF_GAP); } return ((((unsigned)r.x.dx ) << 16) + r.x.ax); }