* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / linux86-0.16.17 / elksemu / elks_sys.c
blobf938023de17dd5b3f7a01dbc9d09fdc2fce80f7b
1 /*
2 * System calls are mostly pretty easy as the emulator is tightly bound to
3 * the elks task.
4 */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <fcntl.h>
11 #include <sys/stat.h>
12 #include <sys/vm86.h>
13 #include <sys/times.h>
14 #include <utime.h>
15 #include <termios.h>
16 #include <time.h>
17 #include <signal.h>
18 #include <errno.h>
19 #include <sys/types.h>
20 #include <sys/resource.h>
21 #include <sys/wait.h>
22 #include <sys/ioctl.h>
23 #include <dirent.h>
24 #include <sys/time.h>
25 #include "elks.h"
27 #include "efile.h"
29 #ifdef DEBUG
30 #define dbprintf(x) db_printf x
31 #else
32 #define dbprintf(x)
33 #endif
35 #define sys_signal elks_signal
36 extern int elks_signal(int bx,int cx,int dx,int di,int si);
38 /* Forward refs */
39 static int elks_termios(int bx,int cx,int dx,int di,int si);
40 static int elks_enosys(int bx,int cx,int dx,int di,int si);
42 #define DIRCOUNT 20
43 DIR * dirtab[DIRCOUNT];
44 int diropen = 0;
45 static int elks_opendir(char * dname);
46 static int elks_readdir(int bx,int cx,int dx,int di,int si);
47 static int elks_closedir(int bx);
50 * Compress a host stat into a elks one. Lose upper bits with wild
51 * abandon. For SYS5.3 this isn't a problem, but machines with 32
52 * bit inodes (BSD, SYS5 with veritas, newest SCO) you lose the top
53 * bits which can confuse a few programs which use inode numbers
54 * (eg gnu tar).
57 static void squash_stat(struct stat *s, int bx)
59 #if 1 /* Can't use elks_stat, shot in the foot by alignment */
61 ELKS_POKE(short, bx+0, s->st_dev);
62 ELKS_POKE(short, bx+2, s->st_ino ^ (s->st_ino>>16));
63 ELKS_POKE(short, bx+4, s->st_mode);
64 ELKS_POKE(short, bx+6, s->st_nlink);
65 ELKS_POKE(short, bx+8, s->st_uid);
66 ELKS_POKE(short, bx+10, s->st_gid);
67 ELKS_POKE(short, bx+12, s->st_rdev);
68 ELKS_POKE(long, bx+14, s->st_size);
69 ELKS_POKE(long, bx+18, s->st_atime);
70 ELKS_POKE(long, bx+22, s->st_mtime);
71 ELKS_POKE(long, bx+26, s->st_ctime);
72 #else
73 struct elks_stat * ms = ELKS_PTR(struct elks_stat, bx);
74 ms->est_dev=s->st_dev;
75 ms->est_inode=(unsigned short)s->st_ino; /* Bits lost */
76 ms->est_mode=s->st_mode;
77 ms->est_nlink=s->st_nlink;
78 ms->est_uid=s->st_uid;
79 ms->est_gid=s->st_gid;
80 ms->est_rdev=s->st_rdev;
81 ms->est_size=s->st_size;
82 ms->est_atime=s->st_atime;
83 ms->est_mtime=s->st_mtime;
84 ms->est_ctime=s->st_ctime;
85 #endif
89 * Implementation of ELKS syscalls.
93 #define sys_exit elks_exit
94 static int elks_exit(int bx,int cx,int dx,int di,int si)
96 dbprintf(("exit(%d)\n",bx));
97 exit(bx);
100 #define sys_vfork elks_fork
101 #define sys_fork elks_fork
102 static int elks_fork(int bx,int cx,int dx,int di,int si)
104 dbprintf(("fork()\n"));
105 /* This is fun 8) - fork the emulator (its easier that way) */
106 return fork();
109 #define sys_read elks_read
110 static int elks_read(int bx,int cx,int dx,int di,int si)
112 dbprintf(("read(%d, %d, %d)\n",
113 bx,cx,dx));
114 if( bx >= 10000 && bx < 10000+DIRCOUNT)
115 return elks_readdir(bx, cx, dx, di, si);
116 if( dx < 0 || dx > 1024 ) dx = 1024;
117 return read(bx, ELKS_PTR(void, cx), dx);
120 #define sys_write elks_write
121 static int elks_write(int bx,int cx,int dx,int di,int si)
123 #ifdef TESTING
124 if( dx > 1024 || dx < 0 )
126 dx = 1024;
127 dbprintf(("write(%d, %d, >%d)\n",bx,cx,dx));
129 else
130 #endif
132 dbprintf(("write(%d, %d, %d)\n",bx,cx,dx));
134 return write(bx,ELKS_PTR(void, cx),dx);
137 #define sys_open elks_open
138 static int elks_open(int bx,int cx,int dx,int di,int si)
140 struct stat s;
142 /* Assumes _all_ flags are the same */
143 char *dp=ELKS_PTR(char, bx);
144 dbprintf(("open(%s, %d, %d)\n",
145 dp,cx,dx));
147 /* Nasty hack so /lib/liberror.txt doesn't exist on the host.
149 if (strcmp(dp, "/lib/liberror.txt") == 0 ) {
150 int fd = open("/var/run/elks-liberror.txt", O_CREAT|O_EXCL|O_RDWR, 0666);
151 if (fd < 0) return fd;
152 unlink("/var/run/elks-liberror.txt");
153 write(fd, efile, sizeof(efile));
154 lseek(fd, 0L, 0);
155 return fd;
158 if( cx == O_RDONLY )
160 if(stat(dp,&s)==-1)
161 return -1;
162 if( S_ISDIR(s.st_mode) )
163 return elks_opendir(dp);
166 return open(dp,cx,dx);
169 #define sys_close elks_close
170 static int elks_close(int bx,int cx,int dx,int di,int si)
172 dbprintf(("close(%d)\n",bx));
173 if( bx >= 10000 && bx < 10000+DIRCOUNT)
174 return elks_closedir(bx);
175 return close(bx);
178 #define sys_wait4 elks_wait4
179 static int elks_wait4(int bx,int cx,int dx,int di,int si)
181 int status;
182 unsigned short *tp=ELKS_PTR(unsigned short, cx);
183 int r;
184 struct rusage use;
186 dbprintf(("wait4(%d, %d, %d, %d)\n", bx, cx, dx, di));
187 r=wait4((int)(short)bx, &status, dx, &use );
189 *tp=status;
190 if( di ) memcpy(ELKS_PTR(void, di), &use, sizeof(use));
191 return r;
194 #define sys_link elks_link
195 static int elks_link(int bx,int cx,int dx,int di,int si)
197 dbprintf(("link(%s,%s)\n", ELKS_PTR(char, bx), ELKS_PTR(char, cx)));
198 return link(ELKS_PTR(char, bx),ELKS_PTR(char, cx));
201 #define sys_unlink elks_unlink
202 static int elks_unlink(int bx,int cx,int dx,int di,int si)
204 dbprintf(("unlink(%s)\n",ELKS_PTR(char, bx)));
205 return unlink(ELKS_PTR(char, bx));
208 #define sys_chdir elks_chdir
209 static int elks_chdir(int bx,int cx,int dx,int di,int si)
211 dbprintf(("chdir(%s)\n",ELKS_PTR(char, bx)));
212 return chdir(ELKS_PTR(char, bx));
215 #define sys_fchdir elks_fchdir
216 static int elks_fchdir(int bx,int cx,int dx,int di,int si)
218 dbprintf(("fchdir(%s)\n",bx));
219 return fchdir(bx);
223 #define sys_mknod elks_mknod
224 static int elks_mknod(int bx,int cx,int dx,int di,int si)
226 dbprintf(("mknod(%s,%d,%d)\n", ELKS_PTR(char, bx),cx,dx));
227 return mknod(ELKS_PTR(char, bx),cx,dx);
230 #define sys_chmod elks_chmod
231 static int elks_chmod(int bx,int cx,int dx,int di,int si)
233 dbprintf(("chmod(%s,%d)\n", ELKS_PTR(char, bx),cx));
234 return chmod(ELKS_PTR(char, bx), cx);
237 #define sys_chown elks_chown
238 static int elks_chown(int bx,int cx,int dx,int di,int si)
240 dbprintf(("chown(%s,%d,%d)\n", ELKS_PTR(char, bx),cx,dx));
241 return chown(ELKS_PTR(char, bx),cx,dx);
244 #define sys_brk elks_brk
245 static int elks_brk(int bx,int cx,int dx,int di,int si)
247 dbprintf(("brk(%d)\n",bx));
248 if(bx>=elks_cpu.regs.esp)
250 errno= 1; /* Really return -1 */
251 return -1;
253 return 0; /* Can't return bx, 0xBAD1 is an error */
256 #define sys_stat elks_stat
257 static int elks_stat(int bx,int cx,int dx,int di,int si)
259 struct stat s;
260 dbprintf(("stat(%s,%d)\n", ELKS_PTR(char, bx), cx));
261 if(stat(ELKS_PTR(char, bx),&s)==-1)
262 return -1;
263 squash_stat(&s,cx);
264 return 0;
267 #define sys_lstat elks_lstat
268 static int elks_lstat(int bx,int cx,int dx,int di,int si)
270 struct stat s;
271 dbprintf(("lstat(%s,%d)\n", ELKS_PTR(char, bx), cx));
272 if(lstat(ELKS_PTR(char, bx),&s)==-1)
273 return -1;
274 squash_stat(&s,cx);
275 return 0;
278 #define sys_lseek elks_lseek
279 static int elks_lseek(int bx,int cx,int dx,int di,int si)
281 long l=ELKS_PEEK(long, cx);
283 dbprintf(("lseek(%d,%ld,%d)\n",bx,l,dx));
284 l = lseek(bx,l,dx);
285 if( l < 0 ) return -1;
286 ELKS_POKE(long, cx, l);
287 return 0;
290 #define sys_getpid elks_getpid
291 static int elks_getpid(int bx,int cx,int dx,int di,int si)
293 dbprintf(("getpid/getppid()\n"));
294 ELKS_POKE(unsigned short, bx, getppid());
295 return getpid();
298 #define sys_setuid elks_setuid
299 static int elks_setuid(int bx,int cx,int dx,int di,int si)
301 dbprintf(("setuid(%d)\n",bx));
302 return setuid(bx);
305 #define sys_getuid elks_getuid
306 static int elks_getuid(int bx,int cx,int dx,int di,int si)
308 dbprintf(("get[e]uid()\n"));
309 ELKS_POKE(unsigned short, bx, geteuid());
310 return getuid();
313 #define sys_alarm elks_alarm
314 static int elks_alarm(int bx,int cx,int dx,int di,int si)
316 dbprintf(("alarm(%d)\n",bx&0xFFFF));
317 return alarm(bx&0xFFFF);
320 #define sys_fstat elks_fstat
321 static int elks_fstat(int bx,int cx,int dx,int di,int si)
323 struct stat s;
324 int err;
325 dbprintf(("fstat(%d,%d)\n",bx,cx));
326 err=fstat(bx,&s);
327 squash_stat(&s,cx);
328 return err;
331 #define sys_pause elks_pause
332 static int elks_pause(int bx,int cx,int dx,int di,int si)
334 dbprintf(("pause()\n"));
335 return pause();
338 #define sys_utime elks_utime
339 static int elks_utime(int bx,int cx,int dx,int di,int si)
341 unsigned long *up=ELKS_PTR(long, cx);
342 struct utimbuf u;
343 u.actime=*up++;
344 u.modtime=*up;
345 return utime(ELKS_PTR(char, bx), &u);
348 #define sys_access elks_access
349 static int elks_access(int bx,int cx,int dx,int di,int si)
351 dbprintf(("access(%s,%d)\n",ELKS_PTR(char, bx),cx));
352 return access(ELKS_PTR(char, bx),cx);
355 #define sys_sync elks_sync
356 static int elks_sync(int bx,int cx,int dx,int di,int si)
358 dbprintf(("sync()\n"));
359 sync();
360 return 0;
363 #define sys_kill elks_kill
364 static int elks_kill(int bx,int cx,int dx,int di,int si)
366 dbprintf(("kill(%d,%d)\n",bx,cx));
367 return kill(bx,cx);
370 #define sys_pipe elks_pipe
371 static int elks_pipe(int bx,int cx,int dx,int di,int si)
373 unsigned short *dp=ELKS_PTR(unsigned short, bx);
374 int p[2];
375 int err=pipe(p);
376 if(err==-1)
377 return err;
378 *dp++=p[0];
379 *dp=p[1];
380 return 0;
383 #define sys_times elks_times
384 static int elks_times(int bx,int cx,int dx,int di,int si)
386 struct tms t;
387 long clock_ticks=times(&t);
388 long *tp=ELKS_PTR(long, bx);
389 long *clkt=ELKS_PTR(long, cx);
390 *tp++=t.tms_utime;
391 *tp++=t.tms_stime;
392 *tp++=t.tms_cutime;
393 *tp=t.tms_cstime;
394 *clkt = clock_ticks;
395 return 0; /* Should be clock_ticks */
398 #define sys_setgid elks_setgid
399 static int elks_setgid(int bx,int cx,int dx,int di,int si)
401 return setgid(bx);
404 #define sys_getgid elks_getgid
405 static int elks_getgid(int bx,int cx,int dx,int di,int si)
407 ELKS_POKE(unsigned short, bx, getegid());
408 return getgid();
412 * Exec is fun. The Minix user library builds a complete elks stack image.
413 * Great except that we need to unpack it all again and do a real exec. If
414 * its another elks image then our kernel side binary loader will load
415 * elksemu again and we'll take the Unix args and turn them back into a
416 * elks stack image.
418 * For now we run elksemu ourselves and do token attempts at binary checking.
420 * Of course if the kernel misc module is confiured we could just run the exe.
422 #define sys_execve elks_execve
423 static int elks_execve(int bx,int cx,int dx,int di,int si)
425 int fd;
426 int arg_ct,env_ct;
427 int ct;
428 char **argp, **envp;
429 unsigned short *bp;
430 unsigned char *base;
431 unsigned short *tmp;
432 struct elks_exec_hdr mh;
433 int is_elks = 1;
435 dbprintf(("exec(%s,%d,%d)\n",ELKS_PTR(char, bx), cx, dx));
437 base=ELKS_PTR(unsigned char, cx);
438 bp=ELKS_PTR(unsigned short, cx+2);
439 tmp=bp;
441 fd=open(ELKS_PTR(char, bx),O_RDONLY);
442 if(fd==-1)
443 { errno = ENOENT; return -1; }
444 if(read(fd, &mh, sizeof(mh))!=sizeof(mh))
446 close(fd);
447 errno = ENOEXEC;
448 return -1;
450 close(fd);
451 if(mh.hlen!=EXEC_HEADER_SIZE
452 || (mh.type!=ELKS_COMBID && mh.type!=ELKS_SPLITID))
453 is_elks = 0;
455 arg_ct = env_ct = 0;
456 while(*tmp++)
457 arg_ct++;
458 while(*tmp++)
459 env_ct++;
460 arg_ct+=2; /* elksemu-path progname arg0...argn */
461 argp=malloc(sizeof(char *)*(arg_ct+1));
462 envp=malloc(sizeof(char *)*(env_ct+1));
463 if(!argp||!envp) { errno = ENOMEM; return -1; }
464 ct=0;
465 if( is_elks )
467 argp[0]="/usr/bin/elksemu";
468 /* argp[1]=ELKS_PTR(char, bx); */
469 ct=1;
471 while(*bp)
472 argp[ct++]=ELKS_PTR(char, cx+ *bp++);
473 argp[ct]=0;
474 bp++;
475 ct=0;
476 while(*bp)
477 envp[ct++]=ELKS_PTR(char, cx+ *bp++);
478 envp[ct]=0;
479 if( is_elks )
481 argp[1]=ELKS_PTR(char, bx);
482 execve(argp[0],argp,envp);
484 else
485 execve(ELKS_PTR(char, bx),argp,envp);
486 if( errno == ENOEXEC || errno == EACCES ) return -1;
487 perror("elksemu");
488 exit(1);
491 #define sys_umask elks_umask
492 static int elks_umask(int bx,int cx,int dx,int di,int si)
494 return umask(bx);
497 #define sys_chroot elks_chroot
498 static int elks_chroot(int bx,int cx,int dx,int di,int si)
500 dbprintf(("chroot(%s)\n", ELKS_PTR(char, bx)));
501 return chroot(ELKS_PTR(char, bx));
505 #define sys_fcntl elks_fcntl
506 static int elks_fcntl(int bx,int cx,int dx,int di,int si)
508 dbprintf(("fcntl(%d,%d,%d)\n", bx,cx,dx));
509 switch(cx)
511 case ELKS_F_GETFD:
512 return fcntl(bx,F_GETFD,0);
513 case ELKS_F_GETFL:
514 return fcntl(bx,F_GETFL,0);
515 case ELKS_F_DUPFD:
516 return fcntl(bx,F_DUPFD,dx);
517 case ELKS_F_SETFD:
518 return fcntl(bx,F_SETFD,dx);
519 case ELKS_F_SETFL:
520 return fcntl(bx,F_SETFL,dx);
522 * Fixme: Unpack and process elks file locks
524 case ELKS_F_GETLK:
525 case ELKS_F_SETLK:
526 case ELKS_F_SETLKW:
527 errno = EINVAL;
528 return -1;
530 errno = EINVAL;
531 return -1;
534 #define sys_dup elks_dup
535 static int elks_dup(int bx,int cx,int dx,int di,int si)
537 return dup(bx);
540 #define sys_dup2 elks_dup2
541 static int elks_dup2(int bx,int cx,int dx,int di,int si)
543 return dup2(bx, cx);
546 #define sys_rename elks_rename
547 static int elks_rename(int bx,int cx,int dx,int di,int si)
549 dbprintf(("rename(%s,%s)\n", ELKS_PTR(char, bx), ELKS_PTR(char, cx)));
550 return rename(ELKS_PTR(char, bx), ELKS_PTR(char, cx));
553 #define sys_mkdir elks_mkdir
554 static int elks_mkdir(int bx,int cx,int dx,int di,int si)
556 dbprintf(("mkdir(%s,%d)\n", ELKS_PTR(char, bx),cx));
557 return mkdir(ELKS_PTR(char, bx),cx);
560 #define sys_rmdir elks_rmdir
561 static int elks_rmdir(int bx,int cx,int dx,int di,int si)
563 dbprintf(("rmdir(%s)\n", ELKS_PTR(char, bx)));
564 return rmdir(ELKS_PTR(char, bx));
567 #define sys_gettimeofday elks_gettimeofday
568 static int elks_gettimeofday(int bx,int cx,int dx,int di,int si)
570 struct timeval tv;
571 struct timezone tz;
572 int ax;
573 dbprintf(("gettimeofday(%d,%d)\n",bx,cx));
575 ax = gettimeofday(&tv, &tz);
577 if( ax == 0 && bx )
579 ELKS_POKE(long, bx, tv.tv_sec);
580 ELKS_POKE(long, bx+4, tv.tv_usec);
582 if( ax == 0 && cx )
584 ELKS_POKE(short, cx, tz.tz_minuteswest);
585 ELKS_POKE(short, cx+2, tz.tz_dsttime);
587 return ax?-1:0;
590 #define sys_settimeofday elks_settimeofday
591 static int elks_settimeofday(int bx,int cx,int dx,int di,int si)
593 struct timeval tv, *pv = 0;
594 struct timezone tz, *pz = 0;
595 int ax;
596 dbprintf(("settimeofday(%d,%d)\n",bx,cx));
598 if( bx )
600 pv = &tv;
601 tv.tv_sec = ELKS_PEEK(long, bx);
602 tv.tv_usec = ELKS_PEEK(long, bx+4);
604 if( cx )
606 pz = &tz;
607 tz.tz_minuteswest = ELKS_PEEK(short, cx);
608 tz.tz_dsttime = ELKS_PEEK(short, cx+2);
611 ax = settimeofday(pv, pz);
612 return ax?-1:0;
615 #define sys_nice elks_nice
616 static int elks_nice(int bx,int cx,int dx,int di,int si)
618 dbprintf(("nice(%d)\n",bx));
619 return nice(bx);
622 #define sys_symlink elks_symlink
623 static int elks_symlink(int bx,int cx,int dx,int di,int si)
625 dbprintf(("symlink(%s,%s)\n", ELKS_PTR(char, bx), ELKS_PTR(char, cx)));
626 return symlink(ELKS_PTR(char, bx), ELKS_PTR(char, cx));
629 #define sys_readlink elks_readlink
630 static int elks_readlink(int bx,int cx,int dx,int di,int si)
632 dbprintf(("readlink(%s,%s,%d)\n",
633 ELKS_PTR(char, bx),
634 ELKS_PTR(char, cx),
635 dx));
636 return readlink(ELKS_PTR(char, bx), ELKS_PTR(char, cx), dx);
639 #define sys_ioctl elks_ioctl
640 static int elks_ioctl(int bx,int cx,int dx,int di,int si)
642 dbprintf(("ioctl(%d,0x%04x,0x%04x)\n", bx,cx,dx));
643 switch((cx>>8)&0xFF)
645 case 'T': return elks_termios(bx,cx,dx,di,si);
646 default: return elks_enosys(bx,cx,dx,di,si);
650 #define sys_reboot elks_reboot
651 static int elks_reboot(int bx,int cx,int dx,int di,int si)
653 errno = EINVAL;
654 if( bx != 0xfee1 || cx != 0xdead ) return -1;
656 switch(dx)
658 /* graceful shutdown, C-A-D off, kill -? 1 */
659 case 0: return reboot(0xfee1dead, 672274793, 0);
660 /* Enable C-A-D */
661 case 0xCAD: return reboot(0xfee1dead, 672274793, 0x89abcdef);
662 /* Time to die! */
663 case 0xD1E: return reboot(0xfee1dead, 672274793, 0x1234567);
665 return -1;
668 /****************************************************************************/
670 static int
671 elks_opendir(char * dname)
673 DIR * d;
674 int rv;
675 for(rv=0; rv<DIRCOUNT; rv++)
676 if( dirtab[rv] == 0 )
677 break;
678 if( rv >= DIRCOUNT ) { errno=ENOMEM; return -1; }
679 d = opendir(dname);
680 if( d == 0 ) return -1;
681 dirtab[rv] = d;
682 return 10000+rv;
685 #define sys_readdir elks_readdir
686 static int elks_readdir(int bx,int cx,int dx,int di,int si)
688 struct dirent * ent;
690 /* Only read _ONE_ _WHOLE_ dirent at a time */
691 if( dx != 266 && dx != 1 )
693 errno=EINVAL; return -1;
695 errno = 0;
696 ent = readdir(dirtab[bx-10000]);
697 if( ent == 0 ) { if( errno ) { return -1; } else return 0; }
699 memcpy(ELKS_PTR(char, cx+10), ent->d_name, ent->d_reclen+1);
700 ELKS_POKE(long, cx, ent->d_ino);
701 ELKS_POKE(short, cx+8, ent->d_reclen);
702 return dx;
705 static int
706 elks_closedir(int bx)
708 bx-=10000;
709 if( dirtab[bx] ) closedir(dirtab[bx]);
710 dirtab[bx] = 0;
711 return 0;
714 /****************************************************************************/
716 static int elks_termios(int bx,int cx,int dx,int di,int si)
718 int rv = 0;
719 switch(cx&0xFF)
721 case 0x01: rv = ioctl(bx, TCGETS, ELKS_PTR(void, dx)); break;
722 case 0x02: rv = ioctl(bx, TCSETS, ELKS_PTR(void, dx)); break;
723 case 0x03: rv = ioctl(bx, TCSETSW, ELKS_PTR(void, dx)); break;
724 case 0x04: rv = ioctl(bx, TCSETSF, ELKS_PTR(void, dx)); break;
726 case 0x09: rv = ioctl(bx, TCSBRK, dx); break;
727 case 0x0A: rv = ioctl(bx, TCXONC, dx); break;
728 case 0x0B: rv = ioctl(bx, TCFLSH, dx); break;
730 case 0x11: rv = ioctl(bx, TIOCOUTQ, ELKS_PTR(void, dx)); break;
731 case 0x1B: rv = ioctl(bx, TIOCINQ, ELKS_PTR(void, dx)); break;
733 default: rv = -1; errno = EINVAL; break;
735 return rv;
738 /****************************************************************************/
739 /* */
740 /****************************************************************************/
741 #define sys_enosys elks_enosys
742 static int elks_enosys(int bx,int cx,int dx,int di,int si)
744 fprintf(stderr, "Function number %d called (%d,%d,%d)\n",
745 (int)(0xFFFF&elks_cpu.regs.eax),
746 bx, cx, dx);
747 errno = ENOSYS;
748 return -1;
751 #include "defn_tab.v"
752 /* * */
754 typedef int (*funcp)(int, int, int, int, int);
756 static funcp jump_tbl[] = {
757 #include "call_tab.v"
758 elks_enosys
761 int elks_syscall(void)
763 int r, n;
764 int bx=elks_cpu.regs.ebx&0xFFFF;
765 int cx=elks_cpu.regs.ecx&0xFFFF;
766 int dx=elks_cpu.regs.edx&0xFFFF;
767 int di=elks_cpu.regs.edi&0xFFFF;
768 int si=elks_cpu.regs.esi&0xFFFF;
770 errno=0;
771 n = (elks_cpu.regs.eax&0xFFFF);
772 if( n>= 0 && n< sizeof(jump_tbl)/sizeof(funcp) )
773 r = (*(jump_tbl[n]))(bx, cx, dx, di, si);
774 else
775 return -ENOSYS;
777 if(r>=0)
778 return r;
779 else
780 return -errno;