+static int
+os_stat (host_callback *p, const char *file, struct stat *buf)
+{
+ /* ??? There is an issue of when to translate to the target layout.
+ One could do that inside this function, or one could have the
+ caller do it. It's more flexible to let the caller do it, though
+ I'm not sure the flexibility will ever be useful. */
+ return wrap (p, stat (file, buf));
+}
+
+static int
+os_fstat (host_callback *p, int fd, struct stat *buf)
+{
+ if (fdbad (p, fd))
+ return -1;
+
+ if (p->ispipe[fd])
+ {
+#if defined (HAVE_STRUCT_STAT_ST_ATIME) || defined (HAVE_STRUCT_STAT_ST_CTIME) || defined (HAVE_STRUCT_STAT_ST_MTIME)
+ time_t t = (*p->time) (p, NULL);
+#endif
+
+ /* We have to fake the struct stat contents, since the pipe is
+ made up in the simulator. */
+ memset (buf, 0, sizeof (*buf));
+
+#ifdef HAVE_STRUCT_STAT_ST_MODE
+ buf->st_mode = S_IFIFO;
+#endif
+
+ /* If more accurate tracking than current-time is needed (for
+ example, on GNU/Linux we get accurate numbers), the p->time
+ callback (which may be something other than os_time) should
+ happen for each read and write, and we'd need to keep track of
+ atime, ctime and mtime. */
+#ifdef HAVE_STRUCT_STAT_ST_ATIME
+ buf->st_atime = t;
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_CTIME
+ buf->st_ctime = t;
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_MTIME
+ buf->st_mtime = t;
+#endif
+ return 0;
+ }
+
+ /* ??? There is an issue of when to translate to the target layout.
+ One could do that inside this function, or one could have the
+ caller do it. It's more flexible to let the caller do it, though
+ I'm not sure the flexibility will ever be useful. */
+ return wrap (p, fstat (fdmap (p, fd), buf));
+}
+
+static int
+os_lstat (host_callback *p, const char *file, struct stat *buf)
+{
+ /* NOTE: hpn/2004-12-12: Same issue here as with os_fstat. */
+#ifdef HAVE_LSTAT
+ return wrap (p, lstat (file, buf));
+#else
+ return wrap (p, stat (file, buf));
+#endif
+}
+
+static int
+os_ftruncate (host_callback *p, int fd, long len)
+{
+ int result;
+
+ result = fdbad (p, fd);
+ if (p->ispipe[fd])
+ {
+ p->last_errno = EINVAL;
+ return -1;
+ }
+ if (result)
+ return result;
+#ifdef HAVE_FTRUNCATE
+ result = wrap (p, ftruncate (fdmap (p, fd), len));
+#else
+ p->last_errno = EINVAL;
+ result = -1;
+#endif
+ return result;
+}
+
+static int
+os_truncate (host_callback *p, const char *file, long len)
+{
+#ifdef HAVE_TRUNCATE
+ return wrap (p, truncate (file, len));
+#else
+ p->last_errno = EINVAL;
+ return -1;
+#endif
+}