1 /* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
2  * This file is part of the Linux-8086 C library and is distributed
3  * under the GNU Library General Public License.
4  */
5 
6 #include <sys/types.h>
7 #include <errno.h>
8 #include <time.h>
9 #include <sys/times.h>
10 
11 /* MSDOS has it's own versions */
12 #ifndef __MSDOS__
13 #ifdef __AS386_16__
14 
15 /********************** Function __cstartup *******************************/
16 
17 #ifdef L___cstartup
18 
19 void (*__cleanup)() = 0;
20 char ** environ;
21 
22 #asm
23   loc	2
24 call_main:
25   .word run_main	! Segment 2 is the trailing pointers, main and the
26   .word	call_exit	! routine to call exit.
27 #if __FIRST_ARG_IN_AX__
28   .data
29 saved_arg1:
30   .word 0
31 #endif
32   .data
33 loop_safe:
34   .word 0
35   .text
36 
37 export ___cstartup
38 ___cstartup:		! Crt0 startup
39   pop	cx		! Argc
40   mov	bx,sp		! Calculate ptrs to argv and envp
41   mov	ax,cx
42   inc	ax
43   shl	ax,#1
44   add	ax,bx
45 
46 export ___mkargv
47 ___mkargv:		! BCC tells the linker to init argc,argv with this.
48 
49   push	ax		! Push Envp
50   mov	[_environ],ax	! And save
51   push	bx		! Push argv
52 #if __FIRST_ARG_IN_AX__
53   mov	[saved_arg1],cx
54 #else
55   push	cx		! Push argc
56 #endif
57 
58   mov	bx,#auto_start	! Pointer to first autostart function
59 auto_run:
60 #if __FIRST_ARG_IN_AX__
61   mov	ax,[saved_arg1]
62 #endif
63   mov   [loop_safe],bx
64   mov	bx,[bx]
65   test	bx,bx
66   jz	no_entry
67   call	bx		! Call the function
68 no_entry:
69   mov   bx,[loop_safe]
70   inc	bx		! next
71   inc	bx
72   jmp	auto_run	! And round for the next.
73 
74 run_main:
75   br	_main
76 
77 call_exit:		! Last item called by above.
78   pop	bx		! Be tidy.
79 #if !__FIRST_ARG_IN_AX__
80   push	ax		! At the end the last called was main() push it`s
81 #endif
82   call	_exit		! return val and call exit();
83 bad_exit:
84   jmp	bad_exit	! Exit returned !!
85 
86 export _exit
87 export __exit
88 _exit:			! exit(rv) function
89 #if __FIRST_ARG_IN_AX__
90   mov	[saved_arg1],ax
91 #else
92   mov	bx,sp
93   push	[bx+2]		! Copy the `rv` for the exit fuctions.
94 #endif
95   mov	bx,[___cleanup] ! Call exit, normally this is `__do_exit`
96   test	bx,bx
97   je	no_clean	! But it`s default is null
98   call	bx
99 no_clean:
100 #if __FIRST_ARG_IN_AX__
101   mov	ax,[saved_arg1]
102 #else
103   inc	sp
104   inc	sp
105 #endif
106 __exit:			! _exit(rv)
107   br	___exit		! This is just an alias for __exit();
108 
109 #endasm
110 
111 #endif
112 
113 /********************** Function lseek ************************************/
114 
115 #ifdef L_lseek
lseek(fd,posn,where)116 off_t lseek(fd, posn, where)
117 int fd;
118 off_t posn;
119 int where;
120 {
121    if( __lseek(fd, &posn, where) < 0 ) return -1;
122    else return posn;
123 }
124 #endif
125 
126 /********************** Function getpid ************************************/
127 
128 #ifdef L_getpid
getpid()129 int getpid()
130 {
131    int ppid;
132    return __getpid(&ppid);
133 }
134 #endif
135 
136 /********************** Function getppid ************************************/
137 
138 #ifdef L_getppid
getppid()139 int getppid()
140 {
141    int ppid;
142    __getpid(&ppid);
143    return ppid;
144 }
145 #endif
146 
147 /********************** Function getuid ************************************/
148 
149 #ifdef L_getuid
getuid()150 int getuid()
151 {
152    int euid;
153    return __getuid(&euid);
154 }
155 #endif
156 
157 /********************** Function geteuid ************************************/
158 
159 #ifdef L_geteuid
geteuid()160 int geteuid()
161 {
162    int euid;
163    __getuid(&euid);
164    return euid;
165 }
166 #endif
167 
168 /********************** Function getgid ************************************/
169 
170 #ifdef L_getgid
getgid()171 int getgid()
172 {
173    int egid;
174    return __getgid(&egid);
175 }
176 #endif
177 
178 /********************** Function getegid ************************************/
179 
180 #ifdef L_getegid
getegid()181 int getegid()
182 {
183    int egid;
184    __getgid(&egid);
185    return egid;
186 }
187 #endif
188 
189 /********************** Function dup2 ************************************/
190 
191 #ifdef L_dup2
192 
193 #include <fcntl.h>
194 
dup2(ifd,ofd)195 int dup2(ifd, ofd)
196 int ifd;
197 {
198    return fcntl(ifd, F_DUPFD, ofd);
199 }
200 #endif
201 
202 /********************** Function dup ************************************/
203 
204 #ifdef L_dup
205 #include <sys/param.h>
206 #include <fcntl.h>
207 #include <errno.h>
208 
209 /* This is horribly complicated, there _must_ be a better way! */
210 
211 int
dup(fd)212 dup(fd)
213 int fd;
214 {
215    int nfd;
216    extern int errno;
217    int oerr = errno;
218 
219    errno = 0;
220    for(nfd=0; nfd<NR_OPEN; nfd++)
221    {
222       if( fcntl(nfd, F_GETFD) < 0 )
223          break;
224    }
225    if( nfd == NR_OPEN ) { errno = EMFILE ; return -1; }
226    errno = oerr;
227    if( fcntl(fd, F_DUPFD, nfd) < 0 )
228    {
229       if( errno == EINVAL ) errno = EMFILE;
230       return -1;
231    }
232    return nfd;
233 }
234 #endif
235 
236 /********************** Function getpgrp ************************************/
237 
238 #ifdef L_getpgrp
239 int
getpgrp()240 getpgrp()
241 {
242    return getpgid(0);
243 }
244 #endif
245 
246 /********************** Function times ************************************/
247 
248 #ifdef L_times
times(buf)249 clock_t times(buf)
250 struct tms* buf;
251 {
252    long rv;
253    __times(buf, &rv);
254    return rv;
255 }
256 #endif
257 
258 /********************** THE END ********************************************/
259 
260 #endif /* __AS386_16__ */
261 #endif /* __MSDOS__ */
262