mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:51:15 +08:00
3ac2e371a1
inf_child_fileio_open and its gdbserver equivalent both assume that the mode_t bits defined in gdb/fileio.h are the same as those used by the open system call, but there is no mechanism to ensure this is the case. This commit adds a conversion function to handle systems where the File-I/O definitions do not align with the host's. gdb/ChangeLog: * common/fileio.h (fileio_to_host_mode): New declaration. * common/fileio.c (fileio_to_host_mode): New Function. * inf-child.c (inf_child_fileio_open): Process mode argument with fileio_to_host_mode. gdb/gdbserver/ChangeLog: * hostio.c (handle_open): Process mode argument with fileio_to_host_mode.
256 lines
6.2 KiB
C
256 lines
6.2 KiB
C
/* File-I/O functions for GDB, the GNU debugger.
|
|
|
|
Copyright (C) 2003-2015 Free Software Foundation, Inc.
|
|
|
|
This file is part of GDB.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
#include "common-defs.h"
|
|
#include "fileio.h"
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
|
|
/* See fileio.h. */
|
|
|
|
int
|
|
host_to_fileio_error (int error)
|
|
{
|
|
switch (error)
|
|
{
|
|
case EPERM:
|
|
return FILEIO_EPERM;
|
|
case ENOENT:
|
|
return FILEIO_ENOENT;
|
|
case EINTR:
|
|
return FILEIO_EINTR;
|
|
case EIO:
|
|
return FILEIO_EIO;
|
|
case EBADF:
|
|
return FILEIO_EBADF;
|
|
case EACCES:
|
|
return FILEIO_EACCES;
|
|
case EFAULT:
|
|
return FILEIO_EFAULT;
|
|
case EBUSY:
|
|
return FILEIO_EBUSY;
|
|
case EEXIST:
|
|
return FILEIO_EEXIST;
|
|
case ENODEV:
|
|
return FILEIO_ENODEV;
|
|
case ENOTDIR:
|
|
return FILEIO_ENOTDIR;
|
|
case EISDIR:
|
|
return FILEIO_EISDIR;
|
|
case EINVAL:
|
|
return FILEIO_EINVAL;
|
|
case ENFILE:
|
|
return FILEIO_ENFILE;
|
|
case EMFILE:
|
|
return FILEIO_EMFILE;
|
|
case EFBIG:
|
|
return FILEIO_EFBIG;
|
|
case ENOSPC:
|
|
return FILEIO_ENOSPC;
|
|
case ESPIPE:
|
|
return FILEIO_ESPIPE;
|
|
case EROFS:
|
|
return FILEIO_EROFS;
|
|
case ENOSYS:
|
|
return FILEIO_ENOSYS;
|
|
case ENAMETOOLONG:
|
|
return FILEIO_ENAMETOOLONG;
|
|
}
|
|
return FILEIO_EUNKNOWN;
|
|
}
|
|
|
|
/* See fileio.h. */
|
|
|
|
int
|
|
fileio_to_host_openflags (int fileio_open_flags, int *open_flags_p)
|
|
{
|
|
int open_flags = 0;
|
|
|
|
if (fileio_open_flags & ~FILEIO_O_SUPPORTED)
|
|
return -1;
|
|
|
|
if (fileio_open_flags & FILEIO_O_CREAT)
|
|
open_flags |= O_CREAT;
|
|
if (fileio_open_flags & FILEIO_O_EXCL)
|
|
open_flags |= O_EXCL;
|
|
if (fileio_open_flags & FILEIO_O_TRUNC)
|
|
open_flags |= O_TRUNC;
|
|
if (fileio_open_flags & FILEIO_O_APPEND)
|
|
open_flags |= O_APPEND;
|
|
if (fileio_open_flags & FILEIO_O_RDONLY)
|
|
open_flags |= O_RDONLY;
|
|
if (fileio_open_flags & FILEIO_O_WRONLY)
|
|
open_flags |= O_WRONLY;
|
|
if (fileio_open_flags & FILEIO_O_RDWR)
|
|
open_flags |= O_RDWR;
|
|
/* On systems supporting binary and text mode, always open files
|
|
in binary mode. */
|
|
#ifdef O_BINARY
|
|
open_flags |= O_BINARY;
|
|
#endif
|
|
|
|
*open_flags_p = open_flags;
|
|
return 0;
|
|
}
|
|
|
|
/* See fileio.h. */
|
|
|
|
int
|
|
fileio_to_host_mode (int fileio_mode, mode_t *mode_p)
|
|
{
|
|
mode_t mode = 0;
|
|
|
|
if (fileio_mode & ~FILEIO_S_SUPPORTED)
|
|
return -1;
|
|
|
|
if (fileio_mode & FILEIO_S_IFREG)
|
|
mode |= S_IFREG;
|
|
if (fileio_mode & FILEIO_S_IFDIR)
|
|
mode |= S_IFDIR;
|
|
if (fileio_mode & FILEIO_S_IFCHR)
|
|
mode |= S_IFCHR;
|
|
if (fileio_mode & FILEIO_S_IRUSR)
|
|
mode |= S_IRUSR;
|
|
if (fileio_mode & FILEIO_S_IWUSR)
|
|
mode |= S_IWUSR;
|
|
if (fileio_mode & FILEIO_S_IXUSR)
|
|
mode |= S_IXUSR;
|
|
#ifdef S_IRGRP
|
|
if (fileio_mode & FILEIO_S_IRGRP)
|
|
mode |= S_IRGRP;
|
|
#endif
|
|
#ifdef S_IWGRP
|
|
if (fileio_mode & FILEIO_S_IWGRP)
|
|
mode |= S_IWGRP;
|
|
#endif
|
|
#ifdef S_IXGRP
|
|
if (fileio_mode & FILEIO_S_IXGRP)
|
|
mode |= S_IXGRP;
|
|
#endif
|
|
if (fileio_mode & FILEIO_S_IROTH)
|
|
mode |= S_IROTH;
|
|
#ifdef S_IWOTH
|
|
if (fileio_mode & FILEIO_S_IWOTH)
|
|
mode |= S_IWOTH;
|
|
#endif
|
|
#ifdef S_IXOTH
|
|
if (fileio_mode & FILEIO_S_IXOTH)
|
|
mode |= S_IXOTH;
|
|
#endif
|
|
|
|
*mode_p = mode;
|
|
return 0;
|
|
}
|
|
|
|
/* Convert a host-format mode_t into a bitmask of File-I/O flags. */
|
|
|
|
static LONGEST
|
|
fileio_mode_pack (mode_t mode)
|
|
{
|
|
mode_t tmode = 0;
|
|
|
|
if (S_ISREG (mode))
|
|
tmode |= FILEIO_S_IFREG;
|
|
if (S_ISDIR (mode))
|
|
tmode |= FILEIO_S_IFDIR;
|
|
if (S_ISCHR (mode))
|
|
tmode |= FILEIO_S_IFCHR;
|
|
if (mode & S_IRUSR)
|
|
tmode |= FILEIO_S_IRUSR;
|
|
if (mode & S_IWUSR)
|
|
tmode |= FILEIO_S_IWUSR;
|
|
if (mode & S_IXUSR)
|
|
tmode |= FILEIO_S_IXUSR;
|
|
#ifdef S_IRGRP
|
|
if (mode & S_IRGRP)
|
|
tmode |= FILEIO_S_IRGRP;
|
|
#endif
|
|
#ifdef S_IWGRP
|
|
if (mode & S_IWGRP)
|
|
tmode |= FILEIO_S_IWGRP;
|
|
#endif
|
|
#ifdef S_IXGRP
|
|
if (mode & S_IXGRP)
|
|
tmode |= FILEIO_S_IXGRP;
|
|
#endif
|
|
if (mode & S_IROTH)
|
|
tmode |= FILEIO_S_IROTH;
|
|
#ifdef S_IWOTH
|
|
if (mode & S_IWOTH)
|
|
tmode |= FILEIO_S_IWOTH;
|
|
#endif
|
|
#ifdef S_IXOTH
|
|
if (mode & S_IXOTH)
|
|
tmode |= FILEIO_S_IXOTH;
|
|
#endif
|
|
return tmode;
|
|
}
|
|
|
|
/* Pack a host-format mode_t into an fio_mode_t. */
|
|
|
|
static void
|
|
host_to_fileio_mode (mode_t num, fio_mode_t fnum)
|
|
{
|
|
host_to_bigendian (fileio_mode_pack (num), (char *) fnum, 4);
|
|
}
|
|
|
|
/* Pack a host-format integer into an fio_ulong_t. */
|
|
|
|
static void
|
|
host_to_fileio_ulong (LONGEST num, fio_ulong_t fnum)
|
|
{
|
|
host_to_bigendian (num, (char *) fnum, 8);
|
|
}
|
|
|
|
/* See fileio.h. */
|
|
|
|
void
|
|
host_to_fileio_stat (struct stat *st, struct fio_stat *fst)
|
|
{
|
|
LONGEST blksize;
|
|
|
|
host_to_fileio_uint ((long) st->st_dev, fst->fst_dev);
|
|
host_to_fileio_uint ((long) st->st_ino, fst->fst_ino);
|
|
host_to_fileio_mode (st->st_mode, fst->fst_mode);
|
|
host_to_fileio_uint ((long) st->st_nlink, fst->fst_nlink);
|
|
host_to_fileio_uint ((long) st->st_uid, fst->fst_uid);
|
|
host_to_fileio_uint ((long) st->st_gid, fst->fst_gid);
|
|
host_to_fileio_uint ((long) st->st_rdev, fst->fst_rdev);
|
|
host_to_fileio_ulong ((LONGEST) st->st_size, fst->fst_size);
|
|
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
|
|
blksize = st->st_blksize;
|
|
#else
|
|
blksize = 512;
|
|
#endif
|
|
host_to_fileio_ulong (blksize, fst->fst_blksize);
|
|
#if HAVE_STRUCT_STAT_ST_BLOCKS
|
|
host_to_fileio_ulong ((LONGEST) st->st_blocks, fst->fst_blocks);
|
|
#else
|
|
/* FIXME: This is correct for DJGPP, but other systems that don't
|
|
have st_blocks, if any, might prefer 512 instead of st_blksize.
|
|
(eliz, 30-12-2003) */
|
|
host_to_fileio_ulong (((LONGEST) st->st_size + blksize - 1)
|
|
/ blksize,
|
|
fst->fst_blocks);
|
|
#endif
|
|
host_to_fileio_time (st->st_atime, fst->fst_atime);
|
|
host_to_fileio_time (st->st_mtime, fst->fst_mtime);
|
|
host_to_fileio_time (st->st_ctime, fst->fst_ctime);
|
|
}
|