1/* File-I/O functions for GDB, the GNU debugger.
2
3   Copyright (C) 2003-2020 Free Software Foundation, Inc.
4
5   This file is part of GDB.
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 3 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20#include "common-defs.h"
21#include "fileio.h"
22#include <sys/stat.h>
23#include <fcntl.h>
24
25/* See fileio.h.  */
26
27int
28host_to_fileio_error (int error)
29{
30  switch (error)
31    {
32      case EPERM:
33        return FILEIO_EPERM;
34      case ENOENT:
35        return FILEIO_ENOENT;
36      case EINTR:
37        return FILEIO_EINTR;
38      case EIO:
39        return FILEIO_EIO;
40      case EBADF:
41        return FILEIO_EBADF;
42      case EACCES:
43        return FILEIO_EACCES;
44      case EFAULT:
45        return FILEIO_EFAULT;
46      case EBUSY:
47        return FILEIO_EBUSY;
48      case EEXIST:
49        return FILEIO_EEXIST;
50      case ENODEV:
51        return FILEIO_ENODEV;
52      case ENOTDIR:
53        return FILEIO_ENOTDIR;
54      case EISDIR:
55        return FILEIO_EISDIR;
56      case EINVAL:
57        return FILEIO_EINVAL;
58      case ENFILE:
59        return FILEIO_ENFILE;
60      case EMFILE:
61        return FILEIO_EMFILE;
62      case EFBIG:
63        return FILEIO_EFBIG;
64      case ENOSPC:
65        return FILEIO_ENOSPC;
66      case ESPIPE:
67        return FILEIO_ESPIPE;
68      case EROFS:
69        return FILEIO_EROFS;
70      case ENOSYS:
71        return FILEIO_ENOSYS;
72      case ENAMETOOLONG:
73        return FILEIO_ENAMETOOLONG;
74    }
75  return FILEIO_EUNKNOWN;
76}
77
78/* See fileio.h.  */
79
80int
81fileio_to_host_openflags (int fileio_open_flags, int *open_flags_p)
82{
83  int open_flags = 0;
84
85  if (fileio_open_flags & ~FILEIO_O_SUPPORTED)
86    return -1;
87
88  if (fileio_open_flags & FILEIO_O_CREAT)
89    open_flags |= O_CREAT;
90  if (fileio_open_flags & FILEIO_O_EXCL)
91    open_flags |= O_EXCL;
92  if (fileio_open_flags & FILEIO_O_TRUNC)
93    open_flags |= O_TRUNC;
94  if (fileio_open_flags & FILEIO_O_APPEND)
95    open_flags |= O_APPEND;
96  if (fileio_open_flags & FILEIO_O_RDONLY)
97    open_flags |= O_RDONLY;
98  if (fileio_open_flags & FILEIO_O_WRONLY)
99    open_flags |= O_WRONLY;
100  if (fileio_open_flags & FILEIO_O_RDWR)
101    open_flags |= O_RDWR;
102  /* On systems supporting binary and text mode, always open files
103     in binary mode. */
104#ifdef O_BINARY
105  open_flags |= O_BINARY;
106#endif
107
108  *open_flags_p = open_flags;
109  return 0;
110}
111
112/* See fileio.h.  */
113
114int
115fileio_to_host_mode (int fileio_mode, mode_t *mode_p)
116{
117  mode_t mode = 0;
118
119  if (fileio_mode & ~FILEIO_S_SUPPORTED)
120    return -1;
121
122  if (fileio_mode & FILEIO_S_IFREG)
123    mode |= S_IFREG;
124  if (fileio_mode & FILEIO_S_IFDIR)
125    mode |= S_IFDIR;
126  if (fileio_mode & FILEIO_S_IFCHR)
127    mode |= S_IFCHR;
128  if (fileio_mode & FILEIO_S_IRUSR)
129    mode |= S_IRUSR;
130  if (fileio_mode & FILEIO_S_IWUSR)
131    mode |= S_IWUSR;
132  if (fileio_mode & FILEIO_S_IXUSR)
133    mode |= S_IXUSR;
134#ifdef S_IRGRP
135  if (fileio_mode & FILEIO_S_IRGRP)
136    mode |= S_IRGRP;
137#endif
138#ifdef S_IWGRP
139  if (fileio_mode & FILEIO_S_IWGRP)
140    mode |= S_IWGRP;
141#endif
142#ifdef S_IXGRP
143  if (fileio_mode & FILEIO_S_IXGRP)
144    mode |= S_IXGRP;
145#endif
146  if (fileio_mode & FILEIO_S_IROTH)
147    mode |= S_IROTH;
148#ifdef S_IWOTH
149  if (fileio_mode & FILEIO_S_IWOTH)
150    mode |= S_IWOTH;
151#endif
152#ifdef S_IXOTH
153  if (fileio_mode & FILEIO_S_IXOTH)
154    mode |= S_IXOTH;
155#endif
156
157  *mode_p = mode;
158  return 0;
159}
160
161/* Convert a host-format mode_t into a bitmask of File-I/O flags.  */
162
163static LONGEST
164fileio_mode_pack (mode_t mode)
165{
166  mode_t tmode = 0;
167
168  if (S_ISREG (mode))
169    tmode |= FILEIO_S_IFREG;
170  if (S_ISDIR (mode))
171    tmode |= FILEIO_S_IFDIR;
172  if (S_ISCHR (mode))
173    tmode |= FILEIO_S_IFCHR;
174  if (mode & S_IRUSR)
175    tmode |= FILEIO_S_IRUSR;
176  if (mode & S_IWUSR)
177    tmode |= FILEIO_S_IWUSR;
178  if (mode & S_IXUSR)
179    tmode |= FILEIO_S_IXUSR;
180#ifdef S_IRGRP
181  if (mode & S_IRGRP)
182    tmode |= FILEIO_S_IRGRP;
183#endif
184#ifdef S_IWGRP
185  if (mode & S_IWGRP)
186    tmode |= FILEIO_S_IWGRP;
187#endif
188#ifdef S_IXGRP
189  if (mode & S_IXGRP)
190    tmode |= FILEIO_S_IXGRP;
191#endif
192  if (mode & S_IROTH)
193    tmode |= FILEIO_S_IROTH;
194#ifdef S_IWOTH
195  if (mode & S_IWOTH)
196    tmode |= FILEIO_S_IWOTH;
197#endif
198#ifdef S_IXOTH
199  if (mode & S_IXOTH)
200    tmode |= FILEIO_S_IXOTH;
201#endif
202  return tmode;
203}
204
205/* Pack a host-format mode_t into an fio_mode_t.  */
206
207static void
208host_to_fileio_mode (mode_t num, fio_mode_t fnum)
209{
210  host_to_bigendian (fileio_mode_pack (num), (char *) fnum, 4);
211}
212
213/* Pack a host-format integer into an fio_ulong_t.  */
214
215static void
216host_to_fileio_ulong (LONGEST num, fio_ulong_t fnum)
217{
218  host_to_bigendian (num, (char *) fnum, 8);
219}
220
221/* See fileio.h.  */
222
223void
224host_to_fileio_stat (struct stat *st, struct fio_stat *fst)
225{
226  LONGEST blksize;
227
228  host_to_fileio_uint ((long) st->st_dev, fst->fst_dev);
229  host_to_fileio_uint ((long) st->st_ino, fst->fst_ino);
230  host_to_fileio_mode (st->st_mode, fst->fst_mode);
231  host_to_fileio_uint ((long) st->st_nlink, fst->fst_nlink);
232  host_to_fileio_uint ((long) st->st_uid, fst->fst_uid);
233  host_to_fileio_uint ((long) st->st_gid, fst->fst_gid);
234  host_to_fileio_uint ((long) st->st_rdev, fst->fst_rdev);
235  host_to_fileio_ulong ((LONGEST) st->st_size, fst->fst_size);
236#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
237  blksize = st->st_blksize;
238#else
239  blksize = 512;
240#endif
241  host_to_fileio_ulong (blksize, fst->fst_blksize);
242#if HAVE_STRUCT_STAT_ST_BLOCKS
243  host_to_fileio_ulong ((LONGEST) st->st_blocks, fst->fst_blocks);
244#else
245  /* FIXME: This is correct for DJGPP, but other systems that don't
246     have st_blocks, if any, might prefer 512 instead of st_blksize.
247     (eliz, 30-12-2003)  */
248  host_to_fileio_ulong (((LONGEST) st->st_size + blksize - 1)
249			/ blksize,
250			fst->fst_blocks);
251#endif
252  host_to_fileio_time (st->st_atime, fst->fst_atime);
253  host_to_fileio_time (st->st_mtime, fst->fst_mtime);
254  host_to_fileio_time (st->st_ctime, fst->fst_ctime);
255}
256