• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * This file has no copyright assigned and is placed in the Public Domain.
3  * This file is part of the mingw-w64 runtime package.
4  * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5  */
6 #include <stdio.h>
7 #include <io.h>
8 #include <errno.h>
9 #include <windows.h>
10 #include <internal.h>
11 
12 struct oserr_map {
13   unsigned long oscode; /* OS values */
14   int errnocode; /* System V codes */
15 };
16 
17 typedef union doubleint {
18   __int64 bigint;
19   struct {
20     unsigned long lowerhalf;
21     long upperhalf;
22   } twoints;
23 } DINT;
24 
25 #define _IOYOURBUF      0x0100
26 #define _IOSETVBUF      0x0400
27 #define _IOFEOF         0x0800
28 #define _IOFLRTN        0x1000
29 #define _IOCTRLZ        0x2000
30 #define _IOCOMMIT       0x4000
31 
32 /* General use macros */
33 
34 #define inuse(s)        ((s)->_flag & (_IOREAD|_IOWRT|_IORW))
35 #define mbuf(s)         ((s)->_flag & _IOMYBUF)
36 #define nbuf(s)         ((s)->_flag & _IONBF)
37 #define ybuf(s)         ((s)->_flag & _IOYOURBUF)
38 #define bigbuf(s)       ((s)->_flag & (_IOMYBUF|_IOYOURBUF))
39 #define anybuf(s)       ((s)->_flag & (_IOMYBUF|_IONBF|_IOYOURBUF))
40 
41 #define _INTERNAL_BUFSIZ    4096
42 #define _SMALL_BUFSIZ       512
43 
44 #define FOPEN           0x01    /* file handle open */
45 #define FEOFLAG         0x02    /* end of file has been encountered */
46 #define FCRLF           0x04    /* CR-LF across read buffer (in text mode) */
47 #define FPIPE           0x08    /* file handle refers to a pipe */
48 #define FNOINHERIT      0x10    /* file handle opened _O_NOINHERIT */
49 #define FAPPEND         0x20    /* file handle opened O_APPEND */
50 #define FDEV            0x40    /* file handle refers to device */
51 #define FTEXT           0x80    /* file handle is in text mode */
52 
53 static struct oserr_map local_errtab[] = {
54   { ERROR_INVALID_FUNCTION, EINVAL }, { ERROR_FILE_NOT_FOUND, ENOENT },
55   { ERROR_PATH_NOT_FOUND, ENOENT }, { ERROR_TOO_MANY_OPEN_FILES, EMFILE },
56   { ERROR_ACCESS_DENIED, EACCES }, { ERROR_INVALID_HANDLE, EBADF },
57   { ERROR_ARENA_TRASHED, ENOMEM }, { ERROR_NOT_ENOUGH_MEMORY, ENOMEM },
58   { ERROR_INVALID_BLOCK, ENOMEM }, { ERROR_BAD_ENVIRONMENT, E2BIG },
59   { ERROR_BAD_FORMAT, ENOEXEC }, { ERROR_INVALID_ACCESS, EINVAL },
60   { ERROR_INVALID_DATA, EINVAL }, { ERROR_INVALID_DRIVE, ENOENT },
61   { ERROR_CURRENT_DIRECTORY, EACCES }, { ERROR_NOT_SAME_DEVICE, EXDEV },
62   { ERROR_NO_MORE_FILES, ENOENT }, { ERROR_LOCK_VIOLATION, EACCES },
63   { ERROR_BAD_NETPATH, ENOENT }, { ERROR_NETWORK_ACCESS_DENIED, EACCES },
64   { ERROR_BAD_NET_NAME, ENOENT }, { ERROR_FILE_EXISTS, EEXIST },
65   { ERROR_CANNOT_MAKE, EACCES }, { ERROR_FAIL_I24, EACCES },
66   { ERROR_INVALID_PARAMETER, EINVAL }, { ERROR_NO_PROC_SLOTS, EAGAIN },
67   { ERROR_DRIVE_LOCKED, EACCES }, { ERROR_BROKEN_PIPE, EPIPE },
68   { ERROR_DISK_FULL, ENOSPC }, { ERROR_INVALID_TARGET_HANDLE, EBADF },
69   { ERROR_INVALID_HANDLE, EINVAL }, { ERROR_WAIT_NO_CHILDREN, ECHILD },
70   { ERROR_CHILD_NOT_COMPLETE, ECHILD }, { ERROR_DIRECT_ACCESS_HANDLE, EBADF },
71   { ERROR_NEGATIVE_SEEK, EINVAL }, { ERROR_SEEK_ON_DEVICE, EACCES },
72   { ERROR_DIR_NOT_EMPTY, ENOTEMPTY }, { ERROR_NOT_LOCKED, EACCES },
73   { ERROR_BAD_PATHNAME, ENOENT }, { ERROR_MAX_THRDS_REACHED, EAGAIN },
74   { ERROR_LOCK_FAILED, EACCES }, { ERROR_ALREADY_EXISTS, EEXIST },
75   { ERROR_FILENAME_EXCED_RANGE, ENOENT }, { ERROR_NESTING_NOT_ALLOWED, EAGAIN },
76   { ERROR_NOT_ENOUGH_QUOTA, ENOMEM }, { 0, -1 }
77 };
78 
79 void mingw_dosmaperr (unsigned long oserrno);
80 
fseeko64(FILE * stream,_off64_t offset,int whence)81 int fseeko64 (FILE* stream, _off64_t offset, int whence)
82 {
83   fpos_t pos;
84   if (whence == SEEK_CUR)
85     {
86       /* If stream is invalid, fgetpos sets errno. */
87       if (fgetpos (stream, &pos))
88         return (-1);
89       pos += (fpos_t) offset;
90     }
91   else if (whence == SEEK_END)
92     {
93       /* If writing, we need to flush before getting file length.  */
94       fflush (stream);
95       pos = (fpos_t) (_filelengthi64 (_fileno (stream)) + offset);
96     }
97   else if (whence == SEEK_SET)
98     pos = (fpos_t) offset;
99   else
100     {
101       errno = EINVAL;
102       return (-1);
103     }
104   return fsetpos (stream, &pos);
105 }
106 
mingw_dosmaperr(unsigned long oserrno)107 void mingw_dosmaperr (unsigned long oserrno)
108 {
109   size_t i;
110 
111   _doserrno = oserrno;        /* set _doserrno */
112   /* check the table for the OS error code */
113   i = 0;
114   do {
115     if (oserrno == local_errtab[i].oscode)
116     {
117       errno = local_errtab[i].errnocode;
118       return;
119     }
120   } while (local_errtab[++i].errnocode != -1);
121   if (oserrno >= ERROR_WRITE_PROTECT && oserrno <= ERROR_SHARING_BUFFER_EXCEEDED)
122     errno = EACCES;
123   else if (oserrno >= ERROR_INVALID_STARTING_CODESEG && oserrno <= ERROR_INFLOOP_IN_RELOC_CHAIN)
124     errno = ENOEXEC;
125   else
126     errno = EINVAL;
127 }
128