| 1 | /* |
| 2 | Copyright (c) 2000, 2010, Oracle and/or its affiliates |
| 3 | |
| 4 | This program is free software; you can redistribute it and/or modify |
| 5 | it under the terms of the GNU General Public License as published by |
| 6 | the Free Software Foundation; version 2 of the License. |
| 7 | |
| 8 | This program is distributed in the hope that it will be useful, |
| 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 11 | GNU General Public License for more details. |
| 12 | |
| 13 | You should have received a copy of the GNU General Public License |
| 14 | along with this program; if not, write to the Free Software |
| 15 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
| 16 | |
| 17 | #include "mysys_priv.h" |
| 18 | #include "mysys_err.h" |
| 19 | |
| 20 | /* |
| 21 | Seek to a position in a file. |
| 22 | |
| 23 | ARGUMENTS |
| 24 | File fd The file descriptor |
| 25 | my_off_t pos The expected position (absolute or relative) |
| 26 | int whence A direction parameter and one of |
| 27 | {SEEK_SET, SEEK_CUR, SEEK_END} |
| 28 | myf MyFlags MY_THREADSAFE must be set in case my_seek may be mixed |
| 29 | with my_pread/my_pwrite calls and fd is shared among |
| 30 | threads. |
| 31 | |
| 32 | DESCRIPTION |
| 33 | The my_seek function is a wrapper around the system call lseek and |
| 34 | repositions the offset of the file descriptor fd to the argument |
| 35 | offset according to the directive whence as follows: |
| 36 | SEEK_SET The offset is set to offset bytes. |
| 37 | SEEK_CUR The offset is set to its current location plus offset bytes |
| 38 | SEEK_END The offset is set to the size of the file plus offset bytes |
| 39 | |
| 40 | RETURN VALUE |
| 41 | my_off_t newpos The new position in the file. |
| 42 | MY_FILEPOS_ERROR An error was encountered while performing |
| 43 | the seek. my_errno is set to indicate the |
| 44 | actual error. |
| 45 | */ |
| 46 | |
| 47 | my_off_t my_seek(File fd, my_off_t pos, int whence, myf MyFlags) |
| 48 | { |
| 49 | os_off_t newpos= -1; |
| 50 | DBUG_ENTER("my_seek" ); |
| 51 | DBUG_PRINT("my" ,("fd: %d Pos: %llu Whence: %d MyFlags: %lu" , |
| 52 | fd, (ulonglong) pos, whence, MyFlags)); |
| 53 | DBUG_ASSERT(pos != MY_FILEPOS_ERROR); /* safety check */ |
| 54 | |
| 55 | /* |
| 56 | Make sure we are using a valid file descriptor! |
| 57 | */ |
| 58 | DBUG_ASSERT(fd != -1); |
| 59 | #ifdef _WIN32 |
| 60 | newpos= my_win_lseek(fd, pos, whence); |
| 61 | #else |
| 62 | newpos= lseek(fd, pos, whence); |
| 63 | #endif |
| 64 | if (newpos == (os_off_t) -1) |
| 65 | { |
| 66 | my_errno= errno; |
| 67 | if (MyFlags & MY_WME) |
| 68 | my_error(EE_CANT_SEEK, MYF(0), my_filename(fd), my_errno); |
| 69 | DBUG_PRINT("error" , ("lseek: %llu errno: %d" , (ulonglong) newpos, errno)); |
| 70 | DBUG_RETURN(MY_FILEPOS_ERROR); |
| 71 | } |
| 72 | if ((my_off_t) newpos != pos) |
| 73 | { |
| 74 | DBUG_PRINT("exit" ,("pos: %llu" , (ulonglong) newpos)); |
| 75 | } |
| 76 | DBUG_RETURN((my_off_t) newpos); |
| 77 | } /* my_seek */ |
| 78 | |
| 79 | |
| 80 | /* Tell current position of file */ |
| 81 | /* ARGSUSED */ |
| 82 | |
| 83 | my_off_t my_tell(File fd, myf MyFlags) |
| 84 | { |
| 85 | os_off_t pos; |
| 86 | DBUG_ENTER("my_tell" ); |
| 87 | DBUG_PRINT("my" ,("fd: %d MyFlags: %lu" ,fd, MyFlags)); |
| 88 | DBUG_ASSERT(fd >= 0); |
| 89 | #if defined (HAVE_TELL) && !defined (_WIN32) |
| 90 | pos= tell(fd); |
| 91 | #else |
| 92 | pos= my_seek(fd, 0L, MY_SEEK_CUR,0); |
| 93 | #endif |
| 94 | if (pos == (os_off_t) -1) |
| 95 | { |
| 96 | my_errno= errno; |
| 97 | if (MyFlags & MY_WME) |
| 98 | my_error(EE_CANT_SEEK, MYF(0), my_filename(fd), my_errno); |
| 99 | DBUG_PRINT("error" , ("tell: %llu errno: %d" , (ulonglong) pos, my_errno)); |
| 100 | } |
| 101 | DBUG_PRINT("exit" ,("pos: %llu" , (ulonglong) pos)); |
| 102 | DBUG_RETURN((my_off_t) pos); |
| 103 | } /* my_tell */ |
| 104 | |