1 /*
2  * solaris-cfuncs.S -- C functions for Solaris.
3  *
4  * Copyright (c) 1996 Cygnus Support
5  *
6  * The authors hereby grant permission to use, copy, modify, distribute,
7  * and license this software and its documentation for any purpose, provided
8  * that existing copyright notices are retained in all copies and that this
9  * notice is included verbatim in any distributions. No written agreement,
10  * license, or royalty fee is required for any of the authorized uses.
11  * Modifications to this software may be copyrighted by their authors
12  * and need not follow the licensing terms described here, provided that
13  * the new terms are clearly indicated on the first page of each file where
14  * they apply.
15  */
16 
17 #include <errno.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <sys/unistd.h>
21 
22 #ifndef __STDC__
23 #define const
24 #endif
25 
26 /* Solaris stat packet */
27 typedef	long		solaris_off_t;
28 typedef	long		solaris_uid_t;
29 typedef	long		solaris_gid_t;
30 typedef	long unsigned	solaris_mode_t;
31 typedef	long unsigned	solaris_nlink_t;
32 typedef long unsigned	solaris_dev_t;
33 typedef long unsigned	solaris_ino_t;
34 typedef long		solaris_time_t;
35 
36 typedef struct {
37   solaris_time_t	tv_sec;
38   long			tv_nsec;
39 } solaris_timestruc_t;
40 
41 #define	_ST_FSTYPSZ 16
42 
43 struct solaris_stat {
44   solaris_dev_t		st_dev;
45   long			st_pad1[3];
46   solaris_ino_t		st_ino;
47   solaris_mode_t	st_mode;
48   solaris_nlink_t	st_nlink;
49   solaris_uid_t 	st_uid;
50   solaris_gid_t 	st_gid;
51   solaris_dev_t		st_rdev;
52   long			st_pad2[2];
53   solaris_off_t		st_size;
54   long			st_pad3;
55   solaris_timestruc_t	st_atim;
56   solaris_timestruc_t	st_mtim;
57   solaris_timestruc_t	st_ctim;
58   long			st_blksize;
59   long			st_blocks;
60   char			st_fstype[_ST_FSTYPSZ];
61   long			st_pad4[8];
62 };
63 
64 /* Solaris termios packet */
65 #define	SOLARIS_NCCS	19
66 typedef unsigned long solaris_tcflag_t;
67 typedef unsigned char solaris_cc_t;
68 typedef unsigned long solaris_speed_t;
69 
70 struct solaris_termios {
71   solaris_tcflag_t	c_iflag;
72   solaris_tcflag_t	c_oflag;
73   solaris_tcflag_t	c_cflag;
74   solaris_tcflag_t	c_lflag;
75   solaris_cc_t		c_cc[SOLARIS_NCCS];
76 };
77 
78 #define	SOLARIS_TIOC	('T'<<8)
79 #define	SOLARIS_TCGETS	(SOLARIS_TIOC|13)
80 
81 
82 
83 /* Debug support */
84 #ifdef DEBUG
85 #define TRACE(msg) trace (msg)
86 #define TRACE1(msg,num) trace1 (msg,(unsigned)num)
87 
88 static void
trace(msg)89 trace (msg)
90      const char *msg;
91 {
92   const char *p;
93 
94   for (p = msg; *p != '\0'; p++)
95     ;
96 
97   (void) write (2, msg, p-msg);
98 }
99 
100 static void
trace1(msg,num)101 trace1 (msg, num)
102      const char *msg;
103      unsigned int num;
104 {
105   char buffer[16];
106   char *p = &buffer[ sizeof(buffer) ];
107 
108   trace (msg);
109   *--p = '\0';
110   *--p = '\n';
111   do {
112     *--p = '0' + (num % 10);
113     num /= 10;
114   } while (num != 0);
115   trace (p);
116 }
117 
118 #else
119 #define TRACE(msg)
120 #define TRACE1(msg,num)
121 #endif
122 
123 
124 /* Errno support */
125 
126 int errno;
127 
128 int *
__errno()129 __errno ()
130 {
131   return &errno;
132 }
133 
134 /* syscall handler branches here to set errno.  Error codes
135    that are common between newlib and Solaris are the same.  */
136 
137 int
_cerror(e)138 _cerror (e)
139      int e;
140 {
141   TRACE1("got to _cerror ",e);
142   errno = e;
143   return -1;
144 }
145 
146 
147 /* Sbrk support */
148 
149 extern char _end[];
150 static char *curbrk = _end;
151 
152 void *
sbrk(incr)153 sbrk (incr)
154      size_t incr;
155 {
156   char *oldbrk = curbrk;
157   TRACE("got to sbrk\n");
158   curbrk += incr;
159   if (brk (curbrk) == -1)
160     return (char *) -1;
161 
162   return (void *)oldbrk;
163 }
164 
165 
166 /* Isatty support */
167 
168 int
isatty(fd)169 isatty (fd)
170      int fd;
171 {
172   struct solaris_termios t;
173   int ret;
174 
175   ret = (ioctl (fd, SOLARIS_TCGETS, &t) == 0);
176 
177   TRACE1("got to isatty, returned ", ret);
178   return ret;
179 }
180 
181 
182 /* Convert Solaris {,f}stat to newlib.
183    Fortunately, the st_mode bits are the same.  */
184 
185 static void
solaris_to_newlib_stat(solaris,newlib)186 solaris_to_newlib_stat (solaris, newlib)
187      struct solaris_stat *solaris;
188      struct stat *newlib;
189 {
190   static struct stat zero_stat;
191 
192   *newlib = zero_stat;
193   newlib->st_dev     = solaris->st_dev;
194   newlib->st_ino     = solaris->st_ino;
195   newlib->st_mode    = solaris->st_mode;
196   newlib->st_nlink   = solaris->st_nlink;
197   newlib->st_uid     = solaris->st_uid;
198   newlib->st_gid     = solaris->st_gid;
199   newlib->st_rdev    = solaris->st_rdev;
200   newlib->st_size    = solaris->st_size;
201   newlib->st_blksize = solaris->st_blksize;
202   newlib->st_blocks  = solaris->st_blocks;
203   newlib->st_atime   = solaris->st_atim.tv_sec;
204   newlib->st_mtime   = solaris->st_mtim.tv_sec;
205   newlib->st_ctime   = solaris->st_ctim.tv_sec;
206 }
207 
208 int
stat(file,newlib_stat)209 stat (file, newlib_stat)
210      const char *file;
211      struct stat *newlib_stat;
212 {
213   int ret;
214   struct solaris_stat st;
215 
216   TRACE("got to stat\n");
217   ret = _stat (file, &st);
218   if (ret >= 0)
219     solaris_to_newlib_stat (&st, newlib_stat);
220 
221   return ret;
222 }
223 
224 int
lstat(file,newlib_stat)225 lstat (file, newlib_stat)
226      const char *file;
227      struct stat *newlib_stat;
228 {
229   int ret;
230   struct solaris_stat st;
231 
232   TRACE("got to lstat\n");
233   ret = _lstat (file, &st);
234   if (ret >= 0)
235     solaris_to_newlib_stat (&st, newlib_stat);
236 
237   return ret;
238 }
239 
240 int
fstat(fd,newlib_stat)241 fstat (fd, newlib_stat)
242      int fd;
243      struct stat *newlib_stat;
244 {
245   int ret;
246   struct solaris_stat st;
247 
248   TRACE("got to fstat\n");
249   ret = _fstat (fd, &st);
250   if (ret >= 0)
251     solaris_to_newlib_stat (&st, newlib_stat);
252 
253   return ret;
254 }
255 
256 
257 /* Nops */
258 
259 int
getrusage()260 getrusage ()
261 {
262   _cerror (EINVAL);
263   return -1;
264 }
265 
266 char *
getcwd(buf,size)267 getcwd(buf, size)
268      char *buf;
269      size_t size;
270 {
271   if (!buf || size < 2)
272     return ".";
273 
274   buf[0] = '.';
275   buf[1] = '\0';
276   return buf;
277 }
278