278 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			278 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | ||
|  * solaris-cfuncs.S -- C functions for Solaris.
 | ||
|  *
 | ||
|  * Copyright (c) 1996 Cygnus Support
 | ||
|  *
 | ||
|  * The authors hereby grant permission to use, copy, modify, distribute,
 | ||
|  * and license this software and its documentation for any purpose, provided
 | ||
|  * that existing copyright notices are retained in all copies and that this
 | ||
|  * notice is included verbatim in any distributions. No written agreement,
 | ||
|  * license, or royalty fee is required for any of the authorized uses.
 | ||
|  * Modifications to this software may be copyrighted by their authors
 | ||
|  * and need not follow the licensing terms described here, provided that
 | ||
|  * the new terms are clearly indicated on the first page of each file where
 | ||
|  * they apply.
 | ||
|  */
 | ||
| 
 | ||
| #include <errno.h>
 | ||
| #include <sys/types.h>
 | ||
| #include <sys/stat.h>
 | ||
| #include <sys/unistd.h>
 | ||
| 
 | ||
| #ifndef __STDC__
 | ||
| #define const
 | ||
| #endif
 | ||
| 
 | ||
| /* Solaris stat packet */
 | ||
| typedef	long		solaris_off_t;
 | ||
| typedef	long		solaris_uid_t;
 | ||
| typedef	long		solaris_gid_t;
 | ||
| typedef	long unsigned	solaris_mode_t;
 | ||
| typedef	long unsigned	solaris_nlink_t;
 | ||
| typedef long unsigned	solaris_dev_t;
 | ||
| typedef long unsigned	solaris_ino_t;
 | ||
| typedef long		solaris_time_t;
 | ||
| 
 | ||
| typedef struct {
 | ||
|   solaris_time_t	tv_sec;
 | ||
|   long			tv_nsec;
 | ||
| } solaris_timestruc_t;
 | ||
| 
 | ||
| #define	_ST_FSTYPSZ 16
 | ||
| 
 | ||
| struct solaris_stat {
 | ||
|   solaris_dev_t		st_dev;
 | ||
|   long			st_pad1[3];
 | ||
|   solaris_ino_t		st_ino;
 | ||
|   solaris_mode_t	st_mode;
 | ||
|   solaris_nlink_t	st_nlink;
 | ||
|   solaris_uid_t 	st_uid;
 | ||
|   solaris_gid_t 	st_gid;
 | ||
|   solaris_dev_t		st_rdev;
 | ||
|   long			st_pad2[2];
 | ||
|   solaris_off_t		st_size;
 | ||
|   long			st_pad3;
 | ||
|   solaris_timestruc_t	st_atim;
 | ||
|   solaris_timestruc_t	st_mtim;
 | ||
|   solaris_timestruc_t	st_ctim;
 | ||
|   long			st_blksize;
 | ||
|   long			st_blocks;
 | ||
|   char			st_fstype[_ST_FSTYPSZ];
 | ||
|   long			st_pad4[8];
 | ||
| };
 | ||
| 
 | ||
| /* Solaris termios packet */
 | ||
| #define	SOLARIS_NCCS	19
 | ||
| typedef unsigned long solaris_tcflag_t;
 | ||
| typedef unsigned char solaris_cc_t;
 | ||
| typedef unsigned long solaris_speed_t;
 | ||
| 
 | ||
| struct solaris_termios {
 | ||
|   solaris_tcflag_t	c_iflag;
 | ||
|   solaris_tcflag_t	c_oflag;
 | ||
|   solaris_tcflag_t	c_cflag;
 | ||
|   solaris_tcflag_t	c_lflag;
 | ||
|   solaris_cc_t		c_cc[SOLARIS_NCCS];
 | ||
| };
 | ||
| 
 | ||
| #define	SOLARIS_TIOC	('T'<<8)
 | ||
| #define	SOLARIS_TCGETS	(SOLARIS_TIOC|13)
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| /* Debug support */
 | ||
| #ifdef DEBUG
 | ||
| #define TRACE(msg) trace (msg)
 | ||
| #define TRACE1(msg,num) trace1 (msg,(unsigned)num)
 | ||
| 
 | ||
| static void
 | ||
| trace (msg)
 | ||
|      const char *msg;
 | ||
| {
 | ||
|   const char *p;
 | ||
| 
 | ||
|   for (p = msg; *p != '\0'; p++)
 | ||
|     ;
 | ||
| 
 | ||
|   (void) write (2, msg, p-msg);
 | ||
| }
 | ||
| 
 | ||
| static void
 | ||
| trace1 (msg, num)
 | ||
|      const char *msg;
 | ||
|      unsigned int num;
 | ||
| {
 | ||
|   char buffer[16];
 | ||
|   char *p = &buffer[ sizeof(buffer) ];
 | ||
| 
 | ||
|   trace (msg);
 | ||
|   *--p = '\0';
 | ||
|   *--p = '\n';
 | ||
|   do {
 | ||
|     *--p = '0' + (num % 10);
 | ||
|     num /= 10;
 | ||
|   } while (num != 0); 
 | ||
|   trace (p);  
 | ||
| }
 | ||
| 
 | ||
| #else
 | ||
| #define TRACE(msg)
 | ||
| #define TRACE1(msg,num)
 | ||
| #endif
 | ||
| 
 | ||
| 
 | ||
| /* Errno support */
 | ||
| 
 | ||
| int errno;
 | ||
| 
 | ||
| int *
 | ||
| __errno ()
 | ||
| {
 | ||
|   return &errno;
 | ||
| }
 | ||
| 
 | ||
| /* syscall handler branches here to set errno.  Error codes
 | ||
|    that are common between newlib and Solaris are the same.  */
 | ||
| 
 | ||
| int
 | ||
| _cerror (e)
 | ||
|      int e;
 | ||
| {
 | ||
|   TRACE1("got to _cerror ",e);
 | ||
|   errno = e;
 | ||
|   return -1;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| /* Sbrk support */
 | ||
| 
 | ||
| extern char _end[];
 | ||
| static char *curbrk = _end;
 | ||
| 
 | ||
| void *
 | ||
| sbrk (incr)
 | ||
|      size_t incr;
 | ||
| {
 | ||
|   char *oldbrk = curbrk;
 | ||
|   TRACE("got to sbrk\n");
 | ||
|   curbrk += incr;
 | ||
|   if (brk (curbrk) == -1)
 | ||
|     return (char *) -1;
 | ||
| 
 | ||
|   return (void *)oldbrk;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| /* Isatty support */
 | ||
| 
 | ||
| int
 | ||
| isatty (fd)
 | ||
|      int fd;
 | ||
| {
 | ||
|   struct solaris_termios t;
 | ||
|   int ret;
 | ||
| 
 | ||
|   ret = (ioctl (fd, SOLARIS_TCGETS, &t) == 0);
 | ||
| 
 | ||
|   TRACE1("got to isatty, returned ", ret);
 | ||
|   return ret;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| /* Convert Solaris {,f}stat to newlib.
 | ||
|    Fortunately, the st_mode bits are the same.  */
 | ||
| 
 | ||
| static void
 | ||
| solaris_to_newlib_stat (solaris, newlib)
 | ||
|      struct solaris_stat *solaris;
 | ||
|      struct stat *newlib;
 | ||
| {
 | ||
|   static struct stat zero_stat;
 | ||
| 
 | ||
|   *newlib = zero_stat;
 | ||
|   newlib->st_dev     = solaris->st_dev;
 | ||
|   newlib->st_ino     = solaris->st_ino;
 | ||
|   newlib->st_mode    = solaris->st_mode;
 | ||
|   newlib->st_nlink   = solaris->st_nlink;
 | ||
|   newlib->st_uid     = solaris->st_uid;
 | ||
|   newlib->st_gid     = solaris->st_gid;
 | ||
|   newlib->st_rdev    = solaris->st_rdev;
 | ||
|   newlib->st_size    = solaris->st_size;
 | ||
|   newlib->st_blksize = solaris->st_blksize;
 | ||
|   newlib->st_blocks  = solaris->st_blocks;
 | ||
|   newlib->st_atime   = solaris->st_atim.tv_sec;
 | ||
|   newlib->st_mtime   = solaris->st_mtim.tv_sec;
 | ||
|   newlib->st_ctime   = solaris->st_ctim.tv_sec;
 | ||
| }
 | ||
| 
 | ||
| int
 | ||
| stat (file, newlib_stat)
 | ||
|      const char *file;
 | ||
|      struct stat *newlib_stat;
 | ||
| {
 | ||
|   int ret;
 | ||
|   struct solaris_stat st;
 | ||
| 
 | ||
|   TRACE("got to stat\n");
 | ||
|   ret = _stat (file, &st);
 | ||
|   if (ret >= 0)
 | ||
|     solaris_to_newlib_stat (&st, newlib_stat);
 | ||
| 
 | ||
|   return ret;
 | ||
| }
 | ||
| 
 | ||
| int
 | ||
| lstat (file, newlib_stat)
 | ||
|      const char *file;
 | ||
|      struct stat *newlib_stat;
 | ||
| {
 | ||
|   int ret;
 | ||
|   struct solaris_stat st;
 | ||
| 
 | ||
|   TRACE("got to lstat\n");
 | ||
|   ret = _lstat (file, &st);
 | ||
|   if (ret >= 0)
 | ||
|     solaris_to_newlib_stat (&st, newlib_stat);
 | ||
| 
 | ||
|   return ret;
 | ||
| }
 | ||
| 
 | ||
| int
 | ||
| fstat (fd, newlib_stat)
 | ||
|      int fd;
 | ||
|      struct stat *newlib_stat;
 | ||
| {
 | ||
|   int ret;
 | ||
|   struct solaris_stat st;
 | ||
| 
 | ||
|   TRACE("got to fstat\n");
 | ||
|   ret = _fstat (fd, &st);
 | ||
|   if (ret >= 0)
 | ||
|     solaris_to_newlib_stat (&st, newlib_stat);
 | ||
| 
 | ||
|   return ret;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| /* Nops */
 | ||
| 
 | ||
| int
 | ||
| getrusage ()
 | ||
| {
 | ||
|   _cerror (EINVAL);
 | ||
|   return -1;
 | ||
| }
 | ||
| 
 | ||
| char *
 | ||
| getcwd(buf, size)
 | ||
|      char *buf;
 | ||
|      size_t size;
 | ||
| {
 | ||
|   if (!buf || size < 2)
 | ||
|     return ".";
 | ||
| 
 | ||
|   buf[0] = '.';
 | ||
|   buf[1] = '\0';
 | ||
|   return buf;
 | ||
| }
 |