mescc: dup, dup2: Move to libc.
[mes.git] / lib / linux / libc.c
index d9243f262591f359bcf3779a483a06cc42ee1841..0e093ec3ae5f993a92e4a423c80234eb17c08b8f 100644 (file)
  * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <libmes.h>
+
 #include <fcntl.h>
 #include <stdarg.h>
 #include <stdio.h>
-#include <libmes.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
 
-#define SYS_fork    0x02
-#define SYS_read    0x03
-#define SYS_open    0x05
-#define SYS_waitpid 0x07
-#define SYS_execve  0x0b
-#define SYS_chmod   0x0f
-#define SYS_access  0x21
-#define SYS_brk     0x2d
-#define SYS_ioctl   0x36
-#define SYS_fsync   0x76
-
-#if __MESC__
-
-#include <linux/mes.c>
-
-#else // !__MESC__
-
-#include <assert.h>
-
-#include <linux/gcc.c>
-
-#endif // !__MESC__
+#if __MESC__ && __i386__
+#include <linux/x86-mes/mes.c>
+#elif __MESC__ && __x86_64__
+#include <linux/x86_64-mes/mes.c>
+#elif __i386__
+#include <linux/x86-mes-gcc/mes.c>
+#elif __x86_64__
+#include <linux/x86_64-mes-gcc/mes.c>
+#else
+#error arch not supported
+#endif
 
 int
 fork ()
@@ -59,15 +49,25 @@ fork ()
 ssize_t
 read (int filedes, void *buffer, size_t size)
 {
-  return _sys_call3 (SYS_read, (int)filedes, (int)buffer, (int)size);
+  ssize_t bytes = _sys_call3 (SYS_read, (int)filedes, (long)buffer, (long)size);
+  if (__mes_debug () > 3)
+    {
+      if (bytes == 1)
+        {
+          eputs ("read fd="); eputs (itoa ((int)filedes)); eputs (" c="); eputc (*(char*)buffer); eputs ("\n");
+        }
+      else
+        {
+          eputs ("read fd="); eputs (itoa ((int)filedes));
+          eputs (" bytes="); eputs (itoa (bytes)); eputs ("\n");
+        }
+    }
+  return bytes;
 }
 
 int
-open (char const *file_name, int flags, ...)
+_open3 (char const *file_name, int flags, int mask)
 {
-  va_list ap;
-  va_start (ap, flags);
-  int mask = va_arg (ap, int);
 #if !MES_BOOTSTRAP
   if (!flags)
     {
@@ -75,7 +75,24 @@ open (char const *file_name, int flags, ...)
       _ungetc_fd = -1;
     }
 #endif
-  int r = _sys_call3 (SYS_open, (int)file_name, (int)flags, (int)mask);
+  int r = _sys_call3 (SYS_open, (long)file_name, (int)flags, (int)mask);
+  return r;
+}
+
+int
+_open2 (char const *file_name, int flags)
+{
+  int mask = 0777;
+  return _open3 (file_name, flags, mask);
+}
+
+int
+open (char const *file_name, int flags, ...)
+{
+  va_list ap;
+  va_start (ap, flags);
+  int mask = va_arg (ap, int);
+  int r = _open3 (file_name, flags, mask);
   va_end (ap);
   return r;
 }
@@ -83,31 +100,37 @@ open (char const *file_name, int flags, ...)
 pid_t
 waitpid (pid_t pid, int *status_ptr, int options)
 {
-  return _sys_call3 (SYS_waitpid, (int)pid, (int)status_ptr, (int)options);
+#if __i386__
+  return _sys_call3 (SYS_waitpid, (long)pid, (long)status_ptr, (int)options);
+#elif __x86_64__
+  return _sys_call4 (SYS_wait4, (long)pid, (long)status_ptr, (int)options, 0);
+#else
+#error arch not supported
+#endif
 }
 
 int
 execve (char const* file_name, char *const argv[], char *const env[])
 {
-  return _sys_call3 (SYS_execve, (int)file_name, (int)argv, (int)env);
+  return _sys_call3 (SYS_execve, (long)file_name, (long)argv, (long)env);
 }
 
 int
 chmod (char const *file_name, mode_t mask)
 {
-  return _sys_call2 (SYS_chmod, (int)file_name, (int)mask);
+  return _sys_call2 (SYS_chmod, (long)file_name, (long)mask);
 }
 
 int
 access (char const *file_name, int how)
 {
-  return _sys_call2 (SYS_access, (int)file_name, (int)how);
+  return _sys_call2 (SYS_access, (long)file_name, (int)how);
 }
 
-int
+long
 brk (void *addr)
 {
-  return _sys_call1 (SYS_brk, (int)addr);
+  return _sys_call1 (SYS_brk, (long)addr);
 }
 
 int
@@ -116,7 +139,7 @@ ioctl (int filedes, unsigned long command, ...)
   va_list ap;
   va_start (ap, command);
   int data = va_arg (ap, int);
-  int r = _sys_call3 (SYS_ioctl, (int)filedes, (int)command, (int)data);
+  int r = _sys_call3 (SYS_ioctl, (int)filedes, (long)command, (int)data);
   va_end (ap);
   return r;
 }
@@ -126,3 +149,28 @@ fsync (int filedes)
 {
   return _sys_call1 (SYS_fsync, (int)filedes);
 }
+
+char *
+getcwd (char *buffer, size_t size)
+{
+  int r = _sys_call2 (SYS_getcwd, (long)buffer, (long)size);
+  if (r >= 0)
+    return buffer;
+  return 0;
+}
+
+int
+dup (int old)
+{
+  return _sys_call1 (SYS_dup, (int)old);
+}
+
+int
+dup2 (int old, int new)
+{
+  return _sys_call2 (SYS_dup2, (int)old, (int)new);
+}
+
+#include "linux/clock_gettime.c"
+#include "linux/gettimeofday.c"
+#include "linux/time.c"