| #! /bin/sh |
| # Copyright (C) 2005 Axis Communications. |
| # All rights reserved. |
| # |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions |
| # are met: |
| # |
| # 1. Redistributions of source code must retain the above copyright |
| # notice, this list of conditions and the following disclaimer. |
| # |
| # 2. Neither the name of Axis Communications nor the names of its |
| # contributors may be used to endorse or promote products derived |
| # from this software without specific prior written permission. |
| # |
| # THIS SOFTWARE IS PROVIDED BY AXIS COMMUNICATIONS AND ITS CONTRIBUTORS |
| # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AXIS |
| # COMMUNICATIONS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
| # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| # POSSIBILITY OF SUCH DAMAGE. |
| |
| # To avoid an abundance of copyright/license messages for boilerplate |
| # code, we instead generate them from this file. Generating the |
| # function code could also be done automatically, but at the cost of |
| # slightly more intricate build machinery and/or scattered syscall |
| # information. Beware that the cat-lines must match the sed regexp |
| # "^cat > \([^ ]*\).*". |
| |
| lu='/* -*- buffer-read-only: t -*- |
| THIS FILE IS AUTOMATICALLY GENERATED |
| FROM "'$0'". */ |
| #include "linunistd.h" |
| #define R(x) return (x); } |
| ' |
| lui="$lu int" |
| r=") { R (_Sys_" |
| |
| cat > close.c <<EOF |
| $lui _close (int fd${r}close (fd)) |
| EOF |
| cat > execve.c <<EOF |
| $lui _execve (char *path, char **argv, char **env${r}execve (path, argv, env)) |
| EOF |
| cat > exit.c <<EOF |
| $lu void _exit (int val) { _Sys_exit (val); /* Appease GCC: */ while (1) ; } |
| EOF |
| cat > fcntl.c <<EOF |
| $lui _fcntl (int fd, int cmd, long arg${r}fcntl (fd, cmd, arg)) |
| EOF |
| cat > fork.c <<EOF |
| $lui _fork (void${r}fork ()) |
| EOF |
| cat > fstat.c <<EOF |
| $lu#include <string.h> |
| #include <sys/stat.h> |
| int |
| _fstat (int fd, struct stat *buf) |
| { |
| struct new_stat ks; |
| int retval = _Sys_fstat (fd, &ks); |
| |
| /* Blank before filling it in. */ |
| memset (buf, 0, sizeof (*buf)); |
| |
| /* We have to translate from the linux struct new_stat. |
| It seems we don't have to translate the contents, though. */ |
| buf->st_dev = ks.st_dev; |
| buf->st_ino = ks.st_ino; |
| buf->st_mode = ks.st_mode; |
| buf->st_nlink = ks.st_nlink; |
| buf->st_uid = ks.st_uid; |
| buf->st_gid = ks.st_gid; |
| buf->st_rdev = ks.st_rdev; |
| buf->st_size = ks.st_size; |
| buf->st_blksize = ks.st_blksize; |
| buf->st_blocks = ks.st_blocks; |
| buf->st_atime = ks.st_atime; |
| buf->st_mtime = ks.st_mtime; |
| buf->st_ctime = ks.st_ctime; |
| R (retval) |
| EOF |
| cat > getpid.c <<EOF |
| $lui _getpid (void${r}getpid ()) |
| EOF |
| cat > gettod.c <<EOF |
| $lu#include <sys/time.h> |
| #include <sys/times.h> |
| int |
| _gettimeofday (struct timeval *tp, void *tzp |
| ${r}gettimeofday (tp, tzp)) |
| EOF |
| cat > isatty.c <<EOF |
| $lu |
| typedef unsigned int tcflag_t; |
| typedef unsigned char cc_t; |
| #define NCCS 19 |
| |
| struct termios { |
| tcflag_t c_iflag; /* input mode flags */ |
| tcflag_t c_oflag; /* output mode flags */ |
| tcflag_t c_cflag; /* control mode flags */ |
| tcflag_t c_lflag; /* local mode flags */ |
| cc_t c_line; /* line discipline */ |
| cc_t c_cc[NCCS]; /* control characters */ |
| }; |
| |
| /* From asm-etrax100/ioctls.h: beware of updates. */ |
| #define TCGETS 0x5401 |
| |
| int |
| _isatty (int fd) |
| { |
| struct termios dummy; |
| int save_errno = errno; |
| int ret = _Sys_ioctl (fd, TCGETS, (unsigned long) &dummy); |
| errno = save_errno; |
| R (ret == 0) |
| EOF |
| cat > kill.c <<EOF |
| $lui _kill (int pid, int sig${r}kill (pid, sig)) |
| EOF |
| cat > link.c <<EOF |
| $lui _link (const char *old, const char *new${r}link (old, new)) |
| EOF |
| cat > lseek.c <<EOF |
| $lui _lseek (int fd, int offset, int whence${r}lseek (fd, offset, whence)) |
| EOF |
| cat > open.c <<EOF |
| $lui _open (const char *fnam, int flags, int mode${r}open (fnam, flags, mode)) |
| EOF |
| cat > read.c <<EOF |
| $lui _read (int fd, char *buf, int nbytes${r}read (fd, buf, nbytes)) |
| EOF |
| cat > rename.c <<EOF |
| $lui _rename (const char *old, const char *new${r}rename (old, new)) |
| EOF |
| cat > sbrk.c <<EOF |
| $lu |
| /* From asm-etrax100/mman.h: beware of updates. */ |
| #define PROT_READ 0x1 /* page can be read */ |
| #define PROT_WRITE 0x2 /* page can be written */ |
| #define MAP_ANONYMOUS 0x20 /* don't use a file */ |
| char * |
| _sbrk (int d) |
| { |
| static long last_alloc = 0; |
| |
| /* FIXME: Things are a whole lot different than elinux. */ |
| #ifdef __elinux__ |
| |
| /* We can't promise linear memory from a predetermined location. |
| We're NO_MM. We're paria. We have to rely on tweaks and unclean |
| behavior. We abuse the fact that the malloc function in newlib |
| accepts nonlinear chunks in return to its sbrk calls (with a minor |
| patch). */ |
| |
| /* We use an "old" type mmap, which takes a pointer to a vector of 6 |
| longs where the parameters are stored. */ |
| long buffer[6]; |
| |
| /* We can't return memory. Well we could, but we would have to keep a |
| list of previous allocations. FIXME: Seems reasonable to do that |
| later. */ |
| if (d < 0) |
| return (char *) last_alloc; |
| |
| buffer[3] = MAP_ANONYMOUS; /* Not associated with a file. */ |
| buffer[4] = -1; /* No file. */ |
| buffer[0] = 0; /* Address 0: let mmap pick one. */ |
| buffer[1] = d; /* Length. */ |
| buffer[2] = (PROT_READ | PROT_WRITE); /* Protection flags. */ |
| buffer[5] = 0; /* Offset into file. */ |
| |
| last_alloc = _Sys_mmap (buffer); |
| |
| return (char *) last_alloc; |
| |
| #else /* not __elinux__ */ |
| |
| long prev_brk; |
| |
| if (last_alloc == 0) |
| { |
| last_alloc = _Sys_brk (0); |
| |
| if (last_alloc < 0) |
| return (char *) -1; |
| } |
| |
| prev_brk = last_alloc; |
| |
| if (_Sys_brk (last_alloc + d) < last_alloc + d) |
| return (char *) -1; |
| |
| last_alloc += d; |
| |
| return (char *) prev_brk; |
| #endif |
| } |
| EOF |
| cat > stat.c <<EOF |
| $lu#include <string.h> |
| #include <sys/stat.h> |
| int |
| _stat (const char *path, struct stat *buf) |
| { |
| struct new_stat ks; |
| int retval = _Sys_stat (path, &ks); |
| |
| /* Blank before filling it in. */ |
| memset (buf, 0, sizeof (*buf)); |
| |
| /* We have to translate from the linux struct new_stat. |
| It seems we don't have to translate the contents, though. */ |
| buf->st_dev = ks.st_dev; |
| buf->st_ino = ks.st_ino; |
| buf->st_mode = ks.st_mode; |
| buf->st_nlink = ks.st_nlink; |
| buf->st_uid = ks.st_uid; |
| buf->st_gid = ks.st_gid; |
| buf->st_rdev = ks.st_rdev; |
| buf->st_size = ks.st_size; |
| buf->st_blksize = ks.st_blksize; |
| buf->st_blocks = ks.st_blocks; |
| buf->st_atime = ks.st_atime; |
| buf->st_mtime = ks.st_mtime; |
| buf->st_ctime = ks.st_ctime; |
| R (retval) |
| EOF |
| cat > times.c <<EOF |
| $lu#include <sys/times.h> |
| clock_t |
| _times (struct tms * tp${r}times (tp)) |
| EOF |
| cat > unlink.c <<EOF |
| $lui _unlink (const char *f${r}unlink (f)) |
| EOF |
| cat > wait.c <<EOF |
| $lui _wait (int *status${r}wait4 (_getpid(), status, 0, 0)) |
| EOF |
| cat > write.c <<EOF |
| $lui _write (int fd, char *buf, int nbytes${r}write (fd, buf, nbytes)) |
| EOF |
| exit 0 |