@@ -1,3 +1,15 @@
+2018-07-12 Julio Guerra <julio@farjump.io>
+
+ * remote-fileio.c (remote_fileio_func_open, remote_fileio_func_stat):
+ Allow using File I/O functions open(), stat() and fstat() on special
+ files.
+ * common/fileio.c (fileio_to_host_mode, fileio_mode_pack): Add new
+ special file types in fst_mode's definition.
+ (host_to_fileio_stat): Define fst_dev using the new macro definitions
+ and according to the file's type.
+ * NEWS: Briefly describe the changes of File I/O operations open, stat,
+ fstat.
+
2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com>
Jan Kratochvil <jan.kratochvil@redhat.com>
Paul Fertser <fercerpav@gmail.com>
@@ -7,6 +7,10 @@
can be passed using the '[ADDRESS]:PORT' notation, or the regular
'ADDRESS:PORT' method.
+* The File I/O remote protocol feature has been extended to allow opening and
+ stating special files such as FIFOs and character devices. Previously only
+ regular files and GDB's console were supported.
+
*** Changes in GDB 8.2
* The 'set disassembler-options' command now supports specifying options
@@ -119,12 +119,40 @@ fileio_to_host_mode (int fileio_mode, mode_t *mode_p)
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;
+ switch (fileio_mode & FILEIO_S_IFMT)
+ {
+#ifdef S_IFSOCK
+ case FILEIO_S_IFSOCK:
+ *mode_p |= S_IFSOCK;
+ break;
+#endif
+#ifdef S_IFREG
+ case FILEIO_S_IFREG:
+ mode |= S_IFREG;
+ break;
+#endif
+#ifdef S_IFBLK
+ case FILEIO_S_IFBLK:
+ mode |= S_IFBLK;
+ break;
+#endif
+#ifdef S_IFDIR
+ case FILEIO_S_IFDIR:
+ mode |= S_IFDIR;
+ break;
+#endif
+#ifdef S_IFCHR
+ case FILEIO_S_IFCHR:
+ mode |= S_IFCHR;
+ break;
+#endif
+#ifdef S_IFIFO
+ case FILEIO_S_IFIFO:
+ mode |= S_IFIFO;
+ break;
+#endif
+ }
+
if (fileio_mode & FILEIO_S_IRUSR)
mode |= S_IRUSR;
if (fileio_mode & FILEIO_S_IWUSR)
@@ -167,10 +195,17 @@ fileio_mode_pack (mode_t mode)
if (S_ISREG (mode))
tmode |= FILEIO_S_IFREG;
- if (S_ISDIR (mode))
+ else if (S_ISDIR (mode))
tmode |= FILEIO_S_IFDIR;
- if (S_ISCHR (mode))
+ else if (S_ISCHR (mode))
tmode |= FILEIO_S_IFCHR;
+ else if (S_ISSOCK (mode))
+ tmode |= FILEIO_S_IFSOCK;
+ else if (S_ISBLK (mode))
+ tmode |= FILEIO_S_IFBLK;
+ else if (S_ISFIFO (mode))
+ tmode |= FILEIO_S_IFIFO;
+
if (mode & S_IRUSR)
tmode |= FILEIO_S_IRUSR;
if (mode & S_IWUSR)
@@ -224,8 +259,10 @@ void
host_to_fileio_stat (struct stat *st, struct fio_stat *fst)
{
LONGEST blksize;
+ long fst_dev;
- host_to_fileio_uint ((long) st->st_dev, fst->fst_dev);
+ fst_dev = S_ISREG (st->st_mode) ? FILEIO_STDEV_FILE : FILEIO_STDEV_SPECIAL;
+ host_to_fileio_uint (fst_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);
@@ -1,3 +1,8 @@
+2018-07-12 Julio Guerra <julio@farjump.io>
+
+ * gdb.texinfo: Document new file formats returned by remote File
+ I/O functions stat and fstat.
+
2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com>
Jan Kratochvil <jan.kratochvil@redhat.com>
Paul Fertser <fercerpav@gmail.com>
@@ -41030,12 +41030,13 @@ appropriate section (see @ref{Integral Datatypes}, for details) so this
structure is of size 64 bytes.
The values of several fields have a restricted meaning and/or
-range of values.
+range of values, such as @code{st_dev} or @code{st_mode}.
@table @code
@item st_dev
-A value of 0 represents a file, 1 the console.
+A value of 0 represents a regular file, 1 GDB's console and 2 a special file
+(@code{st_mode} gives further details on the file type).
@item st_ino
No valid meaning for the target. Transmitted unchanged.
@@ -41119,11 +41120,17 @@ All values are given in hexadecimal representation.
@unnumberedsubsubsec mode_t Values
@cindex mode_t values, in file-i/o protocol
-All values are given in octal representation.
+All values are given in octal representation. Bits @code{S_IF*}
+describe commonly used file formats. They default to zero when the
+file format is not in this list.
@smallexample
+ S_IFSOCK 0140000
S_IFREG 0100000
+ S_IFBLK 060000
S_IFDIR 040000
+ S_IFCHR 020000
+ S_IFIFO 010000
S_IRUSR 0400
S_IWUSR 0200
S_IXUSR 0100
@@ -885,16 +885,9 @@ remote_fileio_func_stat (remote_target *remote, char *buf)
remote_fileio_return_errno (remote, -1);
return;
}
- /* Only operate on regular files and directories. */
- if (!ret && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
- {
- remote_fileio_reply (remote, -1, FILEIO_EACCES);
- return;
- }
if (statptr)
{
host_to_fileio_stat (&st, &fst);
- host_to_fileio_uint (0, fst.fst_dev);
errno = target_write_memory (statptr, (gdb_byte *) &fst, sizeof fst);
if (errno != 0)
@@ -939,7 +932,6 @@ remote_fileio_func_fstat (remote_target *remote, char *buf)
if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
{
- host_to_fileio_uint (1, fst.fst_dev);
memset (&st, 0, sizeof (st));
st.st_mode = S_IFCHR | (fd == FIO_FD_CONSOLE_IN ? S_IRUSR : S_IWUSR);
st.st_nlink = 1;
@@ -972,6 +964,8 @@ remote_fileio_func_fstat (remote_target *remote, char *buf)
if (ptrval)
{
host_to_fileio_stat (&st, &fst);
+ if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
+ host_to_fileio_uint (FILEIO_STDEV_CONSOLE, fst.fst_dev);
errno = target_write_memory (ptrval, (gdb_byte *) &fst, sizeof fst);
if (errno != 0)
@@ -1,3 +1,9 @@
+2018-07-12 Julio Guerra <julio@farjump.io>
+
+ * gdb.base/fileio.c: Add test cases to cover some special
+ files and file descriptors.
+ * gdb.base/fileio.exp: Likewise.
+
2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com>
Jan Kratochvil <jan.kratochvil@redhat.com>
Paul Fertser <fercerpav@gmail.com>
@@ -32,11 +32,19 @@ close(int fd);
1) Attempt to close an invalid file descriptor - EBADF
stat(const char *file_name, struct stat *buf);
-1) Pathname is a null string - ENOENT
-2) Pathname does not exist - ENOENT
+1) Regular file
+2) Pathname is a null string - ENOENT
+3) Pathname is an empty string - ENOENT or EFAULT
+4) Pathname does not exist - ENOENT
+5) Directory
fstat(int filedes, struct stat *buf);
-1) Attempt to stat using an invalid file descriptor - EBADF
+1) Regular file
+2) Attempt to stat using an invalid file descriptor - EBADF
+3) Directory
+4) Standard input
+5) Standard output
+6) Standard error
isatty (int desc);
Not applicable. We will test that it returns 1 when expected and a case
@@ -63,14 +71,17 @@ system (const char * string);
static const char *strerrno (int err);
+static int is_st_dev (int actual, int expected);
+
/* Note that OUTDIR is defined by the test suite. */
#define FILENAME "foo.fileio.test"
#define RENAMED "bar.fileio.test"
#define NONEXISTANT "nofoo.fileio.test"
#define NOWRITE "nowrt.fileio.test"
-#define TESTDIR1 "dir1.fileio.test"
-#define TESTDIR2 "dir2.fileio.test"
-#define TESTSUBDIR "dir1.fileio.test/subdir.fileio.test"
+#define TESTDIR1 "dir1.fileio.test"
+#define TESTDIR2 "dir2.fileio.test"
+#define TESTSUBDIR "dir1.fileio.test/subdir.fileio.test"
+#define DIRECTORY "directory.fileio.test"
#define STRING "Hello World"
@@ -292,7 +303,8 @@ test_stat (void)
ret = stat (OUTDIR FILENAME, &st);
if (!ret)
printf ("stat 1: ret = %d, errno = %d %s\n", ret, errno,
- st.st_size == 11 ? "OK" : "");
+ is_st_dev (st.st_dev, 0) && S_ISREG (st.st_mode) && st.st_size == 11 ?
+ "OK" : "");
else
printf ("stat 1: ret = %d, errno = %d\n", ret, errno);
stop ();
@@ -314,6 +326,15 @@ test_stat (void)
printf ("stat 4: ret = %d, errno = %d %s\n", ret, errno,
strerrno (errno));
stop ();
+ /* Special file: directory */
+ errno = 0;
+ ret = stat (OUTDIR DIRECTORY, &st);
+ if (!ret)
+ printf ("stat 5: ret = %d, errno = %d %s\n", ret, errno,
+ is_st_dev (st.st_dev, 2) && S_ISDIR (st.st_mode) ? "OK" : "");
+ else
+ printf ("stat 5: ret = %d, errno = %d\n", ret, errno);
+ stop ();
}
void
@@ -331,7 +352,8 @@ test_fstat (void)
ret = fstat (fd, &st);
if (!ret)
printf ("fstat 1: ret = %d, errno = %d %s\n", ret, errno,
- st.st_size == 11 ? "OK" : "");
+ is_st_dev (st.st_dev, 0) && S_ISREG (st.st_mode) && st.st_size == 11 ?
+ "OK" : "");
else
printf ("fstat 1: ret = %d, errno = %d\n", ret, errno);
close (fd);
@@ -345,6 +367,50 @@ test_fstat (void)
printf ("fstat 2: ret = %d, errno = %d %s\n", ret, errno,
strerrno (errno));
stop ();
+ /* Special file: directory */
+ errno = 0;
+ fd = open (OUTDIR DIRECTORY, O_RDONLY);
+ if (fd >= 0)
+ {
+ errno = 0;
+ ret = fstat (fd, &st);
+ if (!ret)
+ printf ("fstat 3: ret = %d, errno = %d %s\n", ret, errno,
+ is_st_dev (st.st_dev, 2) && S_ISDIR (st.st_mode) ? "OK" : "");
+ else
+ printf ("fstat 3: ret = %d, errno = %d\n", ret, errno);
+ close (fd);
+ }
+ else
+ printf ("fstat 3: errno = %d\n", errno);
+ stop ();
+ /* Standard input */
+ errno = 0;
+ ret = fstat (STDIN_FILENO, &st);
+ if (!ret)
+ printf ("fstat 4: ret = %d, errno = %d %s\n", ret, errno,
+ is_st_dev (st.st_dev, 1) ? "OK" : "");
+ else
+ printf ("fstat 4: ret = %d, errno = %d\n", ret, errno);
+ stop ();
+ /* Standard output */
+ errno = 0;
+ ret = fstat (STDOUT_FILENO, &st);
+ if (!ret)
+ printf ("fstat 5: ret = %d, errno = %d %s\n", ret, errno,
+ is_st_dev (st.st_dev, 1) ? "OK" : "");
+ else
+ printf ("fstat 5: ret = %d, errno = %d\n", ret, errno);
+ stop ();
+ /* Standard error */
+ errno = 0;
+ ret = fstat (STDERR_FILENO, &st);
+ if (!ret)
+ printf ("fstat 6: ret = %d, errno = %d %s\n", ret, errno,
+ is_st_dev (st.st_dev, 1) ? "OK" : "");
+ else
+ printf ("fstat 6: ret = %d, errno = %d\n", ret, errno);
+ stop ();
}
void
@@ -557,6 +623,16 @@ strerrno (int err)
}
}
+static int
+is_st_dev (int actual, int expected)
+{
+#ifdef TESTING_RSP
+ return actual == expected;
+#else
+ return 1;
+#endif
+}
+
int
main ()
{
@@ -29,9 +29,16 @@ if {[is_remote host]} {
set outdir [standard_output_file {}]
}
+if {[target_info gdb_protocol] == "remote"
+ || [target_info gdb_protocol] == "extended-remote"} {
+ set additional_flags " -DTESTING_RSP"
+} else {
+ set additional_flags ""
+}
+
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
executable \
- [list debug "additional_flags=-DOUTDIR=\"$outdir/\""]] != "" } {
+ [list debug "additional_flags=-DOUTDIR=\"$outdir/\" $additional_flags"]] != "" } {
untested "failed to compile"
return -1
}
@@ -136,6 +143,10 @@ gdb_test continue \
"Continuing\\..*close 2:.*EBADF$stop_msg" \
"Closing an invalid file descriptor returns EBADF"
+# Prepare some different file types for stat and fstat.
+set filetype_directory [file join $outdir "directory.fileio.test"]
+remote_exec host "mkdir -p $filetype_directory"
+
gdb_test continue \
"Continuing\\..*stat 1:.*OK$stop_msg" \
"Stat a file"
@@ -152,6 +163,10 @@ gdb_test continue \
"Continuing\\..*stat 4:.*ENOENT$stop_msg" \
"Stat a nonexistant file returns ENOENT"
+gdb_test continue \
+"Continuing\\..*stat 5:.*OK$stop_msg" \
+"Stat a directory"
+
gdb_test continue \
"Continuing\\..*fstat 1:.*OK$stop_msg" \
"Fstat an open file"
@@ -160,6 +175,22 @@ gdb_test continue \
"Continuing\\..*fstat 2:.*EBADF$stop_msg" \
"Fstat an invalid file descriptor returns EBADF"
+gdb_test continue \
+"Continuing\\..*fstat 3:.*OK$stop_msg" \
+"Fstat a directory"
+
+gdb_test continue \
+"Continuing\\..*fstat 4:.*OK$stop_msg" \
+"Fstat standard output"
+
+gdb_test continue \
+"Continuing\\..*fstat 5:.*OK$stop_msg" \
+"Fstat standard input"
+
+gdb_test continue \
+"Continuing\\..*fstat 6:.*OK$stop_msg" \
+"Fstat standard error"
+
gdb_test continue \
"Continuing\\..*isatty 1:.*OK$stop_msg" \
"Isatty (stdin)"
@@ -1,3 +1,8 @@
+2018-07-12 Julio Guerra <julio@farjump.io>
+
+ * gdb/fileio.h: Add macro definitions for special files,
+ both for fst_dev and fst_mode fields of struct fst_stat.
+
2018-07-06 Alan Modra <amodra@gmail.com>
* diagnostics.h: Comment on macro usage.
@@ -37,10 +37,24 @@
FILEIO_O_CREAT | FILEIO_O_TRUNC| \
FILEIO_O_EXCL)
+/* Device id values of fst_dev field */
+/* Regular file */
+#define FILEIO_STDEV_FILE 0
+/* GDB's console */
+#define FILEIO_STDEV_CONSOLE 1
+/* Not a regular file nor the console.
+ Bits FILEIO_S_IFMT of fst_mode give the exact file type. */
+#define FILEIO_STDEV_SPECIAL 2
+
/* mode_t bits */
+#define FILEIO_S_IFSOCK 0140000
#define FILEIO_S_IFREG 0100000
+#define FILEIO_S_IFBLK 060000
#define FILEIO_S_IFDIR 040000
#define FILEIO_S_IFCHR 020000
+#define FILEIO_S_IFIFO 010000
+#define FILEIO_S_IFMT (FILEIO_S_IFIFO | FILEIO_S_IFCHR| \
+ FILEIO_S_IFDIR | FILEIO_S_IFBLK | FILEIO_S_IFREG | FILEIO_S_IFSOCK)
#define FILEIO_S_IRUSR 0400
#define FILEIO_S_IWUSR 0200
#define FILEIO_S_IXUSR 0100
@@ -53,9 +67,8 @@
#define FILEIO_S_IWOTH 02
#define FILEIO_S_IXOTH 01
#define FILEIO_S_IRWXO 07
-#define FILEIO_S_SUPPORTED (FILEIO_S_IFREG|FILEIO_S_IFDIR| \
- FILEIO_S_IRWXU|FILEIO_S_IRWXG| \
- FILEIO_S_IRWXO)
+#define FILEIO_S_SUPPORTED (FILEIO_S_IFMT | FILEIO_S_IRWXU| \
+ FILEIO_S_IRWXG | FILEIO_S_IRWXO)
/* lseek(2) flags */
#define FILEIO_SEEK_SET 0