atfile wrapper support for sb2
authorRiku Voipio <riku.voipio@nokia.com>
Mon, 26 Jan 2009 15:56:14 +0000 (17:56 +0200)
committerRiku Voipio <riku.voipio@nokia.com>
Mon, 26 Jan 2009 15:56:14 +0000 (17:56 +0200)
configure
linux-user/syscall.c

index a8ea55a..d3a41e1 100755 (executable)
--- a/configure
+++ b/configure
@@ -1020,6 +1020,32 @@ EOF
   fi
 fi
 
+#
+# Check for xxxat() functions when we are building linux-user
+# emulator.  This is done because older glibc versions don't
+# have syscall stubs for these implemented.  In that case we
+# don't provide them even if kernel supports them.
+#
+atfile=no
+if [ "$linux_user" = "yes" ] ; then
+  cat > $TMPC << EOF
+#define _ATFILE_SOURCE
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+int
+main(void)
+{ 
+       /* try to unlink nonexisting file */
+       return (unlinkat(AT_FDCWD, "nonexistent_file", 0));
+}
+EOF
+  if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then
+    atfile=yes
+  fi
+fi
+
 # Check if tools are available to build documentation.
 if [ -x "`which texi2html 2>/dev/null`" ] && \
    [ -x "`which pod2man 2>/dev/null`" ]; then
@@ -1093,6 +1119,7 @@ if test "$sdl" != "no" ; then
     echo "SDL static link   $sdl_static"
 fi
 echo "curses support    $curses"
+echo "atfile support    $atfile"
 echo "mingw32 support   $mingw32"
 echo "Audio drivers     $audio_drv_list"
 echo "Extra audio cards $audio_card_list"
@@ -1384,6 +1411,9 @@ if test "$curses" = "yes" ; then
   echo "CONFIG_CURSES=yes" >> $config_mak
   echo "CURSES_LIBS=-lcurses" >> $config_mak
 fi
+if test "$atfile" = "yes" ; then
+  echo "#define CONFIG_ATFILE 1" >> $config_h
+fi
 if test "$brlapi" = "yes" ; then
   echo "CONFIG_BRLAPI=yes" >> $config_mak
   echo "#define CONFIG_BRLAPI 1" >> $config_h
index 5e0b4ae..6949d1b 100644 (file)
@@ -52,6 +52,7 @@
 #include <sys/statfs.h>
 #include <utime.h>
 #include <sys/sysinfo.h>
+#include <sys/utsname.h>
 //#include <sys/user.h>
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
@@ -201,18 +202,6 @@ static int gettid(void) {
 }
 #endif
 _syscall1(int,sys_exit,int,status)
-_syscall1(int,sys_uname,struct new_utsname *,buf)
-#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
-_syscall4(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode,int,flags)
-#endif
-#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
-_syscall4(int,sys_fchmodat,int,dirfd,const char *,pathname,
-          mode_t,mode,int,flags)
-#endif
-#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
-_syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
-          uid_t,owner,gid_t,group,int,flags)
-#endif
 #if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
         defined(__NR_fstatat64)
 _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
@@ -222,7 +211,6 @@ _syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
 _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
          const struct timeval *,times)
 #endif
-_syscall2(int,sys_getcwd1,char *,buf,size_t,size)
 #if TARGET_ABI_BITS == 32
 _syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
 #endif
@@ -234,38 +222,12 @@ _syscall2(int, sys_getpriority, int, which, int, who);
 _syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
           loff_t *, res, uint, wh);
 #endif
-#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
-_syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
-         int,newdirfd,const char *,newpath,int,flags)
-#endif
-#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
-_syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
-#endif
-#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
-_syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
-          mode_t,mode,dev_t,dev)
-#endif
 #if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
         defined(__NR_newfstatat)
 _syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
           struct stat *,buf,int,flags)
 #endif
-#if defined(TARGET_NR_openat) && defined(__NR_openat)
-_syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
-#endif
-#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
-_syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
-          char *,buf,size_t,bufsize)
-#endif
-#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
-_syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
-          int,newdirfd,const char *,newpath)
-#endif
 _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
-#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
-_syscall3(int,sys_symlinkat,const char *,oldpath,
-          int,newdirfd,const char *,newpath)
-#endif
 _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
 #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
 _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
@@ -279,13 +241,6 @@ _syscall1(int,exit_group,int,error_code)
 #if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
 _syscall1(int,set_tid_address,int *,tidptr)
 #endif
-#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
-_syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
-#endif
-#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
-_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
-          const struct timespec *,tsp,int,flags)
-#endif
 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
 _syscall0(int,sys_inotify_init)
 #endif
@@ -302,6 +257,230 @@ _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
 #endif
 #endif
 
+static bitmask_transtbl fcntl_flags_tbl[] = {
+  { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
+  { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
+  { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
+  { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
+  { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
+  { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
+  { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
+  { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
+  { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
+  { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
+  { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
+  { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
+  { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
+#if defined(O_DIRECT)
+  { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
+#endif
+  { 0, 0, 0, 0 }
+};
+
+static int
+sys_uname(struct new_utsname *buf)
+{
+  struct utsname uts_buf;
+
+  if (uname(&uts_buf) < 0)
+      return (-1);
+
+  /*
+   * Just in case these have some differences, we
+   * translate utsname to new_utsname (which is the
+   * struct linux kernel uses).
+   */
+
+#define COPY_UTSNAME_FIELD(dest, src) \
+  do { \
+      /* __NEW_UTS_LEN doesn't include terminating null */ \
+      (void) strncpy((dest), (src), __NEW_UTS_LEN); \
+      (dest)[__NEW_UTS_LEN] = '\0'; \
+  } while (0)
+
+  bzero(buf, sizeof (*buf));
+  COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
+  COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
+  COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
+  COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
+  COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
+#ifdef _GNU_SOURCE
+  COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
+#endif
+  return (0);
+
+#undef COPY_UTSNAME_FIELD
+}
+
+static int
+sys_getcwd1(char *buf, size_t size)
+{
+  if (getcwd(buf, size) == NULL) {
+      /* getcwd() sets errno */
+      return (-1);
+  }
+  return (0);
+}
+
+#ifdef CONFIG_ATFILE
+
+/*
+ * Host system seems to have atfile syscall stubs available.  We
+ * now enable them one by one as specified by target syscall_nr.h.
+ */
+
+#ifdef TARGET_NR_openat
+static int
+sys_openat(int dirfd, const char *pathname, int flags, ...)
+{
+  /*
+   * open(2) has extra parameter 'mode' when called with
+   * flag O_CREAT.
+   */
+  if ((flags & O_CREAT) != 0) {
+      va_list ap;
+      mode_t mode;
+
+      /*
+       * Get the 'mode' parameter and translate it to
+       * host bits.
+       */
+      va_start(ap, flags);
+      mode = va_arg(ap, mode_t);
+      mode = target_to_host_bitmask(mode, fcntl_flags_tbl);
+      va_end(ap);
+
+      return (openat(dirfd, pathname, flags, mode));
+  }
+  return (openat(dirfd, pathname, flags));
+}
+#endif
+
+#ifdef TARGET_NR_mkdirat
+static int
+sys_mkdirat(int dirfd, const char *pathname, mode_t mode)
+{
+  return (mkdirat(dirfd, pathname, mode));
+}
+#endif
+
+#ifdef TARGET_NR_mknodat
+static int
+sys_mknodat(int dirfd, const char *pathname, mode_t mode, dev_t dev)
+{
+  return (mknodat(dirfd, pathname, mode, dev));
+}
+#endif
+
+#ifdef TARGET_NR_fchownat
+static int
+sys_fchownat(int dirfd, const char *pathname, uid_t owner,
+    gid_t group, int flags)
+{
+  return (fchownat(dirfd, pathname, owner, group, flags));
+}
+#endif
+
+#ifdef TARGET_NR_fstatat
+static int
+sys_fstatat64(int dirfd, const char *pathname, struct stat *buf,
+    int flags)
+{
+  return (fstatat64(dirfd, pathname, buf, flags));
+}
+#endif
+
+#ifdef TARGET_NR_unlinkat
+static int
+sys_unlinkat(int dirfd, const char *pathname, int flags)
+{
+  return (unlinkat(dirfd, pathname, flags));
+}
+#endif
+
+#ifdef TARGET_NR_renameat
+static int
+sys_renameat(int olddirfd, const char *oldpath,
+    int newdirfd, const char *newpath)
+{
+  return (renameat(olddirfd, oldpath, newdirfd, newpath));
+}
+#endif
+
+#ifdef TARGET_NR_linkat
+static int
+sys_linkat(int olddirfd, const char *oldpath,
+    int newdirfd, const char *newpath, int flags)
+{
+  return (linkat(olddirfd, oldpath, newdirfd, newpath, flags));
+}
+#endif
+
+#ifdef TARGET_NR_symlinkat
+static int
+sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
+{
+  return (symlinkat(oldpath, newdirfd, newpath));
+}
+#endif
+
+#ifdef TARGET_NR_readlinkat
+static int
+sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
+{
+  return (readlinkat(dirfd, pathname, buf, bufsiz));
+}
+#endif
+
+#ifdef TARGET_NR_fchmodat
+static int
+sys_fchmodat(int dirfd, const char *pathname, mode_t mode, int flags)
+{
+  return (fchmodat(dirfd, pathname, mode, flags));
+}
+#endif
+
+#ifdef TARGET_NR_faccessat
+static int
+sys_faccessat(int dirfd, const char *pathname, int mode, int flags)
+{
+  return (faccessat(dirfd, pathname, mode, flags));
+}
+#endif
+
+#ifdef TARGET_NR_utimensat
+static int
+sys_utimensat(int dirfd, const char *pathname,
+    const struct timespec times[2], int flags)
+{
+  return (utimensat(dirfd, pathname, times, flags));
+}
+#endif
+
+#else /* !CONFIG_ATFILE */
+
+/*
+ * Host system doesn't have these available so we don't try
+ * to implement them.
+ */
+
+#undef TARGET_NR_openat
+#undef TARGET_NR_mkdirat
+#undef TARGET_NR_mknodat
+#undef TARGET_NR_fchownat
+#undef TARGET_NR_fstatat
+#undef TARGET_NR_unlinkat
+#undef TARGET_NR_renameat
+#undef TARGET_NR_linkat
+#undef TARGET_NR_symlinkat
+#undef TARGET_NR_readlinkat
+#undef TARGET_NR_fchmodat
+#undef TARGET_NR_faccessat
+#undef TARGET_NR_utimensat
+
+#endif /* CONFIG_ATFILE */
+
+
 extern int personality(int);
 extern int flock(int, int);
 extern int setfsuid(int);
@@ -2819,26 +2998,6 @@ static bitmask_transtbl mmap_flags_tbl[] = {
        { 0, 0, 0, 0 }
 };
 
-static bitmask_transtbl fcntl_flags_tbl[] = {
-       { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
-       { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
-       { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
-       { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
-       { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
-       { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
-       { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
-       { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
-       { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
-       { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
-       { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
-       { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
-       { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
-#if defined(O_DIRECT)
-       { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
-#endif
-       { 0, 0, 0, 0 }
-};
-
 #if defined(TARGET_I386)
 
 /* NOTE: there is really one LDT for all the threads */