The Pedigree Project  0.1
glue.c
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "posixSyscallNumbers.h"
21 
22 // Define errno before including syscall.h.
23 #include "errno.h"
24 #define errno (*__errno())
25 extern int *__errno(void);
26 int h_errno; // required by networking code
27 
28 #include "posix-syscall.h"
29 
30 #include "newlib.h"
31 
32 #include <ctype.h>
33 #include <malloc.h>
34 #include <mntent.h>
35 #include <netinet/in.h>
36 #include <semaphore.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sys/socket.h>
40 #include <sys/wait.h>
41 #include <time.h>
42 
43 #include <sys/mount.h>
44 #include <sys/resource.h>
45 
46 #include <sys/reent.h>
47 
48 #include <setjmp.h>
49 
50 #include <pedigree_config.h>
51 
52 #define PEDIGREE_SYSCALLS_LIBC
53 #include <pedigree-syscalls.h>
54 
55 #define BS8(x) (x)
56 #define BS16(x) (((x & 0xFF00) >> 8) | ((x & 0x00FF) << 8))
57 #define BS32(x) \
58  (((x & 0xFF000000) >> 24) | ((x & 0x00FF0000) >> 8) | \
59  ((x & 0x0000FF00) << 8) | ((x & 0x000000FF) << 24))
60 #define BS64(x) (x)
61 
62 #ifdef LITTLE_ENDIAN
63 
64 #define LITTLE_TO_HOST8(x) (x)
65 #define LITTLE_TO_HOST16(x) (x)
66 #define LITTLE_TO_HOST32(x) (x)
67 #define LITTLE_TO_HOST64(x) (x)
68 
69 #define HOST_TO_LITTLE8(x) (x)
70 #define HOST_TO_LITTLE16(x) (x)
71 #define HOST_TO_LITTLE32(x) (x)
72 #define HOST_TO_LITTLE64(x) (x)
73 
74 #define BIG_TO_HOST8(x) BS8((x))
75 #define BIG_TO_HOST16(x) BS16((x))
76 #define BIG_TO_HOST32(x) BS32((x))
77 #define BIG_TO_HOST64(x) BS64((x))
78 
79 #define HOST_TO_BIG8(x) BS8((x))
80 #define HOST_TO_BIG16(x) BS16((x))
81 #define HOST_TO_BIG32(x) BS32((x))
82 #define HOST_TO_BIG64(x) BS64((x))
83 
84 #else // else Big endian
85 
86 #define BIG_TO_HOST8(x) (x)
87 #define BIG_TO_HOST16(x) (x)
88 #define BIG_TO_HOST32(x) (x)
89 #define BIG_TO_HOST64(x) (x)
90 
91 #define HOST_TO_BIG8(x) (x)
92 #define HOST_TO_BIG16(x) (x)
93 #define HOST_TO_BIG32(x) (x)
94 #define HOST_TO_BIG64(x) (x)
95 
96 #define LITTLE_TO_HOST8(x) BS8((x))
97 #define LITTLE_TO_HOST16(x) BS16((x))
98 #define LITTLE_TO_HOST32(x) BS32((x))
99 #define LITTLE_TO_HOST64(x) BS64((x))
100 
101 #define HOST_TO_LITTLE8(x) BS8((x))
102 #define HOST_TO_LITTLE16(x) BS16((x))
103 #define HOST_TO_LITTLE32(x) BS32((x))
104 #define HOST_TO_LITTLE64(x) BS64((x))
105 
106 #endif
107 
108 // #define MAXNAMLEN 255
109 
110 const char *safepathchars =
111  "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-";
112 #define SAFE_PATH_LEN (sizeof safepathchars)
113 
114 #define STUBBED(str) \
115  syscall1(POSIX_STUBBED, (long) (str)); \
116  errno = ENOSYS;
117 
118 #define NUM_ATFORK_HANDLERS 32 // (* 3)
119 
120 // For getopt(3).
121 int optreset = 0;
122 
124 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
125 
126 // Defines an fork handler
128 {
129  void (*prepare)(void);
130  void (*parent)(void);
131  void (*child)(void);
132 };
133 
134 // Tables of handlers
135 static struct forkHandler atforkHandlers[NUM_ATFORK_HANDLERS];
136 
137 // Number of handlers (also an index to the next one)
138 static int nHandlers = 0;
139 
140 int ftruncate(int a, off_t b)
141 {
142  return syscall2(POSIX_FTRUNCATE, a, (long) b);
143 }
144 
145 int truncate(const char *path, off_t length)
146 {
147  int fd = open(path, O_WRONLY);
148  if (fd < 0)
149  return fd;
150  int r = ftruncate(fd, length);
151  close(fd);
152 
153  return r;
154 }
155 
156 char *getcwd(char *buf, unsigned long size)
157 {
158  if (buf && !size)
159  {
160  errno = EINVAL;
161  return 0;
162  }
163  else if (!buf && !size)
164  {
165  size = PATH_MAX;
166  }
167 
168  // buf == null is unspecified but used by bash.
169  int malloced = 0;
170  if (!buf)
171  {
172  buf = (char *) malloc(size);
173  if (!buf)
174  {
175  errno = ENOMEM;
176  return 0;
177  }
178  malloced = 1;
179  }
180  long r = syscall2(POSIX_GETCWD, (long) buf, (long) size);
181  char *result = (char *) r;
182  if (!result)
183  {
184  if (malloced)
185  {
186  free(buf);
187  }
188 
189  return 0;
190  }
191 
192  return (char *) result;
193 }
194 
195 int mkdir(const char *p, mode_t mode)
196 {
197  return (long) syscall2(POSIX_MKDIR, (long) p, mode);
198 }
199 
200 int close(int file)
201 {
202  return (long) syscall1(POSIX_CLOSE, file);
203 }
204 
205 int _execve(char *name, char **argv, char **env)
206 {
207  return (long) syscall3(POSIX_EXECVE, (long) name, (long) argv, (long) env);
208 }
209 
210 void _exit(int val)
211 {
212  syscall1(POSIX_EXIT, val);
213  while (1)
214  ;
215 }
216 
217 int fork(void)
218 {
219  if (nHandlers)
220  {
221  for (int i = 0; i < nHandlers; i++)
222  {
223  if (atforkHandlers[i].prepare)
224  atforkHandlers[i].prepare();
225  }
226  }
227 
228  int pid = (long) syscall0(POSIX_FORK);
229 
230  if (pid == 0)
231  {
232  if (nHandlers)
233  {
234  for (int i = 0; i < nHandlers; i++)
235  {
236  if (atforkHandlers[i].child)
237  atforkHandlers[i].child();
238  }
239  }
240  }
241  else if (pid > 0)
242  {
243  if (nHandlers)
244  {
245  for (int i = 0; i < nHandlers; i++)
246  {
247  if (atforkHandlers[i].parent)
248  atforkHandlers[i].parent();
249  }
250  }
251  }
252 
253  return pid;
254 }
255 
256 int vfork(void)
257 {
258  return fork();
259 }
260 
261 int fstat(int file, struct stat *st)
262 {
263  return (long) syscall2(POSIX_FSTAT, (long) file, (long) st);
264 }
265 
266 int _isatty(int file)
267 {
268  return (long) syscall1(POSIX_ISATTY, file);
269 }
270 
271 int link(const char *old, const char *_new)
272 {
273  return (long) syscall2(POSIX_LINK, (long) old, (long) _new);
274 }
275 
276 off_t lseek(int file, off_t ptr, int dir)
277 {
278  return (off_t) syscall3(POSIX_LSEEK, file, ptr, dir);
279 }
280 
281 int open(const char *name, int flags, ...) // , mode_t mode)
282 {
283  // Try to handle invalid arguments early, before we go to the effort of the
284  // system call...
285  if (!name)
286  {
287  errno = EINVAL;
288  return -1;
289  }
290 
291  // Only O_CREAT requires the 'mode' parameter.
292  mode_t mode = 0;
293  if (flags & O_CREAT)
294  {
295  va_list ap;
296  va_start(ap, flags);
297  mode = va_arg(ap, int);
298  va_end(ap);
299  }
300 
301  return (long) syscall3(POSIX_OPEN, (long) name, flags, mode);
302 }
303 
304 _READ_WRITE_RETURN_TYPE read(int file, void *ptr, size_t len)
305 {
306  if (file < 0)
307  {
308  syslog(LOG_NOTICE, "[%d] read: bad file given\n", getpid());
309  errno = EBADF;
310  return -1;
311  }
312  if (len == 0)
313  {
314  syslog(LOG_NOTICE, "[%d] read: bad length given\n", getpid());
315  errno = EINVAL;
316  return 0;
317  }
318  return (_READ_WRITE_RETURN_TYPE) syscall3(
319  POSIX_READ, file, (long) ptr, len);
320 }
321 
322 void *sbrk(ptrdiff_t incr)
323 {
324  uintptr_t result = syscall1(POSIX_SBRK, incr);
325  return (void *) result;
326 }
327 
328 int stat(const char *file, struct stat *st)
329 {
330  return (long) syscall2(POSIX_STAT, (long) file, (long) st);
331 }
332 
333 #ifndef PPC_COMMON
334 clock_t times(struct tms *buf)
335 {
336  return syscall1(POSIX_TIMES, (long) buf);
337 }
338 #endif
339 
340 int utimes(const char *filename, const struct timeval times[2])
341 {
342  return syscall2(POSIX_UTIMES, (long) filename, (long) times);
343 }
344 
345 int unlink(const char *name)
346 {
347  return (long) syscall1(POSIX_UNLINK, (long) name);
348 }
349 
350 int wait(int *status)
351 {
352  return waitpid(-1, status, 0);
353 }
354 
355 int waitpid(int pid, int *status, int options)
356 {
357  return (long) syscall3(POSIX_WAITPID, pid, (long) status, options);
358 }
359 
360 _READ_WRITE_RETURN_TYPE write(int file, const void *ptr, size_t len)
361 {
362  if (file < 0)
363  {
364  syslog(LOG_NOTICE, "[%d] write: bad file given\n", getpid());
365  errno = EBADF;
366  return -1;
367  }
368  return (_READ_WRITE_RETURN_TYPE) syscall3(
369  POSIX_WRITE, file, (long) ptr, len);
370 }
371 
372 ssize_t readv(int fd, const struct iovec *iov, int iovcnt)
373 {
374  if (!iov || !iovcnt || (fd == -1))
375  {
376  errno = EINVAL;
377  return -1;
378  }
379 
380  ssize_t ret = 0;
381  int i;
382  for (i = 0; i < iovcnt; i++)
383  {
384  if (iov[i].iov_base)
385  {
386  ssize_t r = read(fd, iov[i].iov_base, iov[i].iov_len);
387  ret += r;
388  }
389  }
390  return ret;
391 }
392 
393 ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
394 {
395  if (!iov || !iovcnt || (fd == -1))
396  {
397  errno = EINVAL;
398  return -1;
399  }
400 
401  ssize_t ret = 0;
402  int i;
403  for (i = 0; i < iovcnt; i++)
404  {
405  if (iov[i].iov_base)
406  {
407  ssize_t r = write(fd, iov[i].iov_base, iov[i].iov_len);
408  ret += r;
409  }
410  }
411  return ret;
412 }
413 
414 int lstat(const char *file, struct stat *st)
415 {
416  return (long) syscall2(POSIX_LSTAT, (long) file, (long) st);
417 }
418 
419 DIR *opendir(const char *dir)
420 {
421  DIR *p = (DIR *) malloc(sizeof(DIR));
422  int r = syscall2(POSIX_OPENDIR, (long) dir, (long) p);
423  if (r < 0 || p->fd < 0)
424  {
425  free(p);
426  return 0;
427  }
428  return p;
429 }
430 
431 struct dirent *readdir(DIR *dir)
432 {
433  if (!dir)
434  {
435  errno = EINVAL;
436  return 0;
437  }
438 
439  int old_errno = errno;
440 
441  if (dir->fd < 0)
442  {
443  // Bad DIR object.
444  errno = EINVAL;
445  return 0;
446  }
447 
448  if (dir->totalpos >= dir->count)
449  {
450  // End of directory. errno remains unchanged.
451  return 0;
452  }
453  else if (dir->pos >= 64)
454  {
455  // Buffer the next batch of entries.
456  if (syscall1(POSIX_READDIR, (long) dir) < 0)
457  {
458  // Failed to buffer more entries!
459  return 0;
460  }
461  dir->pos = 1;
462  dir->totalpos++;
463  return &dir->ent[0];
464  }
465  else
466  {
467  struct dirent *result = &dir->ent[dir->pos];
468  dir->pos++;
469  dir->totalpos++;
470  return result;
471  }
472 }
473 
474 void rewinddir(DIR *dir)
475 {
476  if (!dir)
477  {
478  return;
479  }
480 
481  if (dir->totalpos < 64)
482  {
483  // Don't need to re-buffer.
484  dir->pos = dir->totalpos = 0;
485  }
486  else if (dir->totalpos != 0)
487  {
488  dir->pos = dir->totalpos = 0;
489  syscall1(POSIX_READDIR, (long) dir);
490  }
491 }
492 
493 int closedir(DIR *dir)
494 {
495  if (!dir)
496  {
497  errno = EINVAL;
498  return -1;
499  }
500 
501  syscall1(POSIX_CLOSEDIR, (long) dir);
502  free(dir);
503  return 0;
504 }
505 
506 int _rename(const char *old, const char *new)
507 {
508  return (long) syscall2(POSIX_RENAME, (long) old, (long) new);
509 }
510 
511 int tcgetattr(int fd, struct termios *p)
512 {
513  return (long) syscall2(POSIX_TCGETATTR, fd, (long) p);
514 }
515 
516 int tcsetattr(int fd, int optional_actions, const struct termios *p)
517 {
518  return (long) syscall3(POSIX_TCSETATTR, fd, optional_actions, (long) p);
519 }
520 
521 int tcsendbreak(int fildes, int duration)
522 {
523  STUBBED("tcsendbreak");
524  return 0;
525 }
526 
527 int tcdrain(int fd)
528 {
529  STUBBED("tcdrain");
530  return -1;
531 }
532 
533 int tcflush(int fd, int queue_selector)
534 {
535  intptr_t selector = queue_selector;
536  return ioctl(fd, TIOCFLUSH, (void *) selector);
537 }
538 
539 int tcflow(int fd, int action)
540 {
541  STUBBED("tcflow");
542  return 0;
543 }
544 
545 void cfmakeraw(struct termios *t)
546 {
547  t->c_iflag &=
548  ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
549  t->c_oflag &= ~OPOST;
550  t->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
551  t->c_cflag &= ~(CSIZE | PARENB);
552  t->c_cflag |= CS8;
553 }
554 
555 int cfgetospeed(const struct termios *t)
556 {
557  STUBBED("cfgetospeed");
558  return 0;
559 }
560 
561 int cfgetispeed(const struct termios *t)
562 {
563  STUBBED("cfgetispeed");
564  return 0;
565 }
566 
567 int cfsetospeed(const struct termios *t, int speed)
568 {
569  STUBBED("cfsetospeed");
570  return 0;
571 }
572 
573 int cfsetispeed(const struct termios *t, int speed)
574 {
575  STUBBED("cfsetispeed");
576  return 0;
577 }
578 
579 int tcsetpgrp(int fd, pid_t pgid_id)
580 {
581  return (int) syscall2(POSIX_TCSETPGRP, fd, pgid_id);
582 }
583 
584 pid_t tcgetpgrp(int fd)
585 {
586  return (pid_t) syscall1(POSIX_TCGETPGRP, fd);
587 }
588 
589 int mkfifo(const char *_path, mode_t __mode)
590 {
591  STUBBED("mkfifo");
592  return -1;
593 }
594 
595 int gethostname(char *name, size_t len)
596 {
597  int result;
598 
599  if (!name || !len)
600  return -1;
601 
602  result = pedigree_config_query(
603  "select * from 'network_generic' WHERE `key` = 'hostname';");
604  if ((result == -1) || (pedigree_config_was_successful(result) == -1) ||
605  (pedigree_config_numrows(result) == 0))
606  {
607  if (result != -1)
608  pedigree_config_freeresult(result);
609  strncpy(name, "pedigree", len);
610  return 0;
611  }
612 
613  pedigree_config_getstr_s(result, 0, "value", name, len);
614  pedigree_config_freeresult(result);
615  return 0;
616 }
617 
618 int sethostname(char *name, size_t len)
619 {
620  if (!name || len > 255 || !len)
621  {
622  errno = EINVAL;
623  return -1;
624  }
625 
626  // Need to add permission and name checking
627 
628  const char *query =
629  "update 'network_generic' set `value`= '%s' WHERE `key` = 'hostname'";
630  char *tmp = pedigree_config_escape_string(name);
631  char *buffer = (char *) malloc(strlen(query) + strlen(tmp) - 2 + 1);
632 
633  sprintf(buffer, query, tmp);
634 
635  int result = pedigree_config_query(buffer);
636 
637  if (result != -1)
638  pedigree_config_freeresult(result);
639 
640  free(tmp);
641  free(buffer);
642 
643  return 0;
644 }
645 
646 int ioctl(int fd, int command, ...)
647 {
648  va_list ap;
649  va_start(ap, command);
650 
652  void *buf = va_arg(ap, void *);
653 
654  va_end(ap);
655 
656  return (long) syscall3(POSIX_IOCTL, fd, command, (long) buf);
657 }
658 
659 const char *const sys_siglist[] = {0,
660  "Hangup",
661  "Interrupt",
662  "Quit",
663  "Illegal instruction",
664  "Trap",
665  "IOT",
666  "Abort",
667  "EMT",
668  "Floating point exception",
669  "Kill",
670  "Bus error",
671  "Segmentation violation",
672  "Bad argument to system call",
673  "Pipe error",
674  "Alarm",
675  "Terminate"};
676 
677 const char *strsignal(int sig)
678 {
679  if (sig < 16)
680  return sys_siglist[sig];
681  else
682  return "Unknown";
683 }
684 
685 uid_t getuid(void)
686 {
687  return (long) syscall0(POSIX_GETUID);
688 }
689 
690 gid_t getgid(void)
691 {
692  return (long) syscall0(POSIX_GETGID);
693 }
694 
695 uid_t geteuid(void)
696 {
697  return (uid_t) syscall0(POSIX_GETEUID);
698 }
699 
700 gid_t getegid(void)
701 {
702  return (gid_t) syscall0(POSIX_GETEGID);
703 }
704 
705 int setuid(uid_t uid)
706 {
707  return syscall1(POSIX_SETUID, uid);
708 }
709 
710 int setgid(gid_t gid)
711 {
712  return syscall1(POSIX_SETGID, gid);
713 }
714 
715 int seteuid(uid_t uid)
716 {
717  return syscall1(POSIX_SETEUID, uid);
718 }
719 
720 int setegid(gid_t gid)
721 {
722  return syscall1(POSIX_SETEGID, gid);
723 }
724 
725 int setresuid(uid_t ruid, uid_t euid, uid_t suid)
726 {
727  STUBBED("setresuid");
728  return -1;
729 }
730 
731 int setresgid(gid_t rgid, gid_t egid, gid_t sgid)
732 {
733  STUBBED("setresgid");
734  return -1;
735 }
736 
737 int issetugid()
738 {
739  STUBBED("issetugid");
740  return 0;
741 }
742 
743 unsigned int alarm(unsigned int seconds)
744 {
745  return (unsigned int) syscall1(POSIX_ALARM, seconds);
746 }
747 
748 mode_t umask(mode_t mask)
749 {
750  return syscall1(POSIX_UMASK, mask);
751 }
752 
753 int chmod(const char *path, mode_t mode)
754 {
755  return syscall2(POSIX_CHMOD, (long) path, mode);
756 }
757 
758 int fchmod(int fildes, mode_t mode)
759 {
760  return syscall2(POSIX_FCHMOD, fildes, mode);
761 }
762 
763 int chown(const char *path, uid_t owner, gid_t group)
764 {
765  return syscall3(POSIX_CHOWN, (long) path, owner, group);
766 }
767 
768 int fchown(int fildes, uid_t owner, uid_t group)
769 {
770  return syscall3(POSIX_FCHOWN, fildes, owner, group);
771 }
772 
773 int utime(const char *path, const struct utimbuf *times)
774 {
775  return syscall2(POSIX_UTIME, (long) path, (long) times);
776 }
777 
778 int access(const char *path, int amode)
779 {
780  return (long) syscall2(POSIX_ACCESS, (long) path, amode);
781 }
782 
783 const char *const sys_errlist[] = {};
784 const int sys_nerr = 0;
785 long timezone;
786 
787 long pathconf(const char *path, int name)
788 {
789  STUBBED("pathconf");
790  return 0;
791 }
792 
793 long fpathconf(int filedes, int name)
794 {
795  STUBBED("fpathconf");
796  return 0;
797 }
798 
799 int select(
800  int nfds, struct fd_set *readfds, struct fd_set *writefds,
801  struct fd_set *errorfds, struct timeval *timeout)
802 {
803  return (long) syscall5(
804  POSIX_SELECT, nfds, (long) readfds, (long) writefds, (long) errorfds,
805  (long) timeout);
806 }
807 
808 void setgrent(void)
809 {
810  STUBBED("setgrent");
811 }
812 
813 void endgrent(void)
814 {
815  STUBBED("endgrent");
816 }
817 
818 struct group *getgrent(void)
819 {
820  STUBBED("getgrent");
821  errno = ENOSYS;
822  return 0;
823 }
824 
825 static struct passwd g_passwd;
826 int g_passwd_num = 0;
827 char g_passwd_str[256];
828 void setpwent(void)
829 {
830  g_passwd_num = 0;
831 }
832 
833 void endpwent(void)
834 {
835  g_passwd_num = 0;
836 }
837 
838 struct passwd *getpwent(void)
839 {
840  if (syscall3(
841  POSIX_GETPWENT, (long) &g_passwd, g_passwd_num,
842  (long) &g_passwd_str) != 0)
843  return 0;
844  g_passwd_num++;
845  return &g_passwd;
846 }
847 
848 struct passwd *getpwuid(uid_t uid)
849 {
850  if (syscall3(POSIX_GETPWENT, (long) &g_passwd, uid, (long) &g_passwd_str) !=
851  0)
852  return 0;
853  return &g_passwd;
854 }
855 
856 struct passwd *getpwnam(const char *name)
857 {
858  if (syscall3(
859  POSIX_GETPWNAM, (long) &g_passwd, (long) name,
860  (long) &g_passwd_str) != 0)
861  return 0;
862  return &g_passwd;
863 }
864 
865 int chdir(const char *path)
866 {
867  return (long) syscall1(POSIX_CHDIR, (long) path);
868 }
869 
870 int fchdir(int fildes)
871 {
872  return syscall1(POSIX_FCHDIR, fildes);
873 }
874 
875 int dup(int fileno)
876 {
877  return (long) syscall1(POSIX_DUP, fileno);
878 }
879 
880 int dup2(int fildes, int fildes2)
881 {
882  return (long) syscall2(POSIX_DUP2, fildes, fildes2);
883 }
884 
885 int pipe(int filedes[2])
886 {
887  return (long) syscall1(POSIX_PIPE, (long) filedes);
888 }
889 
890 int fcntl(int fildes, int cmd, ...)
891 {
892  va_list ap;
893  va_start(ap, cmd);
894  void *arg = va_arg(ap, void *);
895  va_end(ap);
896 
897  return syscall3(POSIX_FCNTL, fildes, cmd, (long) arg);
898 }
899 
900 int sigprocmask(int how, const sigset_t *set, sigset_t *oset)
901 {
902  return (long) syscall3(POSIX_SIGPROCMASK, how, (long) set, (long) oset);
903 }
904 
905 int rmdir(const char *path)
906 {
907  return syscall1(POSIX_RMDIR, (long) path);
908 }
909 
910 int socket(int domain, int type, int protocol)
911 {
912  return (long) syscall3(POSIX_SOCKET, domain, type, protocol);
913 }
914 
915 int connect(int sock, const struct sockaddr *address, size_t addrlen)
916 {
917  return (long) syscall3(POSIX_CONNECT, sock, (long) address, (long) addrlen);
918 }
919 
920 ssize_t send(int sock, const void *buff, size_t bufflen, int flags)
921 {
922  return (ssize_t) syscall4(
923  POSIX_SEND, sock, (long) buff, (long) bufflen, flags);
924 }
925 
926 ssize_t recv(int sock, void *buff, size_t bufflen, int flags)
927 {
928  return (ssize_t) syscall4(
929  POSIX_RECV, sock, (long) buff, (long) bufflen, flags);
930 }
931 
932 int accept(int sock, struct sockaddr *remote_addr, size_t *addrlen)
933 {
934  return (long) syscall3(
935  POSIX_ACCEPT, sock, (long) remote_addr, (long) addrlen);
936 }
937 
938 int bind(int sock, const struct sockaddr *local_addr, size_t addrlen)
939 {
940  return (long) syscall3(POSIX_BIND, sock, (long) local_addr, (long) addrlen);
941 }
942 
943 int getpeername(int sock, struct sockaddr *addr, size_t *addrlen)
944 {
945  return syscall3(POSIX_GETPEERNAME, sock, (long) addr, (long) addrlen);
946 }
947 
948 int getsockname(int sock, struct sockaddr *addr, size_t *addrlen)
949 {
950  return syscall3(POSIX_GETSOCKNAME, sock, (long) addr, (long) addrlen);
951 }
952 
953 int getsockopt(int sock, int level, int optname, void *optvalue, size_t *optlen)
954 {
955  return syscall5(
956  POSIX_GETSOCKOPT, sock, level, optname, (long) optvalue, (long) optlen);
957 }
958 
959 int listen(int sock, int backlog)
960 {
961  return (long) syscall2(POSIX_LISTEN, sock, backlog);
962 }
963 
965 {
966  int sock;
967  const void *buff;
968  size_t bufflen;
969  int flags;
970  const struct sockaddr *remote_addr;
971  const socklen_t *addrlen;
972 } __attribute__((packed));
973 
975 {
976  int sock;
977  void *buff;
978  size_t bufflen;
979  int flags;
980  struct sockaddr *remote_addr;
981  socklen_t *addrlen;
982 } __attribute__((packed));
983 
984 ssize_t recvfrom(
985  int sock, void *buff, size_t bufflen, int flags,
986  struct sockaddr *remote_addr, size_t *addrlen)
987 {
988  struct special_recv_data *tmp =
989  (struct special_recv_data *) malloc(sizeof(struct special_recv_data));
990  tmp->sock = sock;
991  tmp->buff = buff;
992  tmp->bufflen = bufflen;
993  tmp->flags = flags;
994  tmp->remote_addr = remote_addr;
995  tmp->addrlen = addrlen;
996 
997  int ret = syscall1(POSIX_RECVFROM, (long) tmp);
998 
999  free(tmp);
1000 
1001  return ret;
1002 }
1003 
1004 ssize_t recvmsg(int sock, struct msghdr *msg, int flags)
1005 {
1006  STUBBED("recvmsg");
1007  return -1;
1008 }
1009 
1010 ssize_t sendmsg(int sock, const struct msghdr *msg, int flags)
1011 {
1012  STUBBED("sendmsg");
1013  return -1;
1014 }
1015 
1016 ssize_t sendto(
1017  int sock, const void *buff, size_t bufflen, int flags,
1018  const struct sockaddr *remote_addr, socklen_t addrlen)
1019 {
1020  struct special_send_data *tmp =
1021  (struct special_send_data *) malloc(sizeof(struct special_send_data));
1022  tmp->sock = sock;
1023  tmp->buff = buff;
1024  tmp->bufflen = bufflen;
1025  tmp->flags = flags;
1026  tmp->remote_addr = remote_addr;
1027  tmp->addrlen = &addrlen;
1028 
1029  int ret = syscall1(POSIX_SENDTO, (long) tmp);
1030 
1031  free(tmp);
1032 
1033  return ret;
1034 }
1035 
1036 int setsockopt(
1037  int sock, int level, int optname, const void *optvalue,
1038  unsigned long optlen)
1039 {
1040  STUBBED("setsockopt");
1041  return 0;
1042 }
1043 
1044 int shutdown(int sock, int how)
1045 {
1046  return (long) syscall2(POSIX_SHUTDOWN, sock, how);
1047 }
1048 
1049 int sockatmark(int sock)
1050 {
1051  STUBBED("sockatmark");
1052  return -1;
1053 }
1054 
1055 int socketpair(int domain, int type, int protocol, int sock_vec[2])
1056 {
1057  STUBBED("socketpair");
1058  return -1;
1059 }
1060 
1061 struct group *getgrnam(const char *name)
1062 {
1063  static struct group ret = {0, 0, 0, 0};
1064 
1065  if (ret.gr_name)
1066  free(ret.gr_name);
1067  if (ret.gr_passwd)
1068  free(ret.gr_passwd);
1069 
1070  ret.gr_name = (char *) malloc(256);
1071  ret.gr_passwd = (char *) malloc(256);
1072  int r = syscall2(POSIX_GETGRNAM, (long) name, (long) &ret);
1073  if (r < 0)
1074  {
1075  return 0;
1076  }
1077 
1078  return &ret;
1079 }
1080 
1081 struct group *getgrgid(gid_t id)
1082 {
1083  static struct group ret = {0, 0, 0, 0};
1084 
1085  ret.gr_name = (char *) malloc(256);
1086  ret.gr_passwd = (char *) malloc(256);
1087  int r = syscall2(POSIX_GETGRGID, id, (long) &ret);
1088  if (r < 0)
1089  {
1090  return 0;
1091  }
1092 
1093  return &ret;
1094 }
1095 
1096 int symlink(const char *path1, const char *path2)
1097 {
1098  return (long) syscall2(POSIX_SYMLINK, (long) path1, (long) path2);
1099 }
1100 
1101 int fsync(int fd)
1102 {
1103  return syscall1(POSIX_FSYNC, fd);
1104 }
1105 
1106 ssize_t readlink(const char *path, char *buf, size_t bufsize)
1107 {
1108  return (long) syscall3(POSIX_READLINK, (long) path, (long) buf, bufsize);
1109 }
1110 
1111 int ftime(struct timeb *tp)
1112 {
1113  STUBBED("ftime");
1114  return -1;
1115 }
1116 
1117 int sigmask(void)
1118 {
1119  STUBBED("sigmask");
1120  return -1;
1121 }
1122 
1123 int sigblock(void)
1124 {
1125  STUBBED("sigblock");
1126  return -1;
1127 }
1128 
1129 int sigsetmask(int mask)
1130 {
1131  STUBBED("sigsetmask");
1132  return -1;
1133 }
1134 
1135 int siggetmask(void)
1136 {
1137  STUBBED("siggetmask");
1138  return -1;
1139 }
1140 
1141 int sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
1142 {
1143  return (long) syscall3(POSIX_SIGACTION, sig, (long) act, (long) oact);
1144 }
1145 
1146 _sig_func_ptr signal(int s, _sig_func_ptr func)
1147 {
1148  // Obtain the old mask for the sigaction structure, fill it in with default
1149  // arguments and pass on to sigaction
1150  static struct sigaction act;
1151  static struct sigaction tmp;
1152  unsigned long mask = 0;
1153  sigprocmask(0, 0, &mask);
1154  act.sa_mask = mask;
1155  act.sa_handler = func;
1156  act.sa_flags = 0;
1157  memset(&tmp, 0, sizeof(struct sigaction));
1158  if (sigaction(s, &act, &tmp) == 0)
1159  {
1160  return tmp.sa_handler;
1161  }
1162 
1163  // errno set by sigaction
1164  return (_sig_func_ptr) -1;
1165 }
1166 
1167 int kill(pid_t pid, int sig)
1168 {
1169  return (long) syscall2(POSIX_KILL, pid, sig);
1170 }
1171 
1172 int sigpending(long *set)
1173 {
1174  STUBBED("sigpending");
1175  return -1;
1176 }
1177 
1178 int sigsuspend(const long *sigmask)
1179 {
1180  STUBBED("sigsuspend");
1181  return -1;
1182 }
1183 
1184 void _init_signals(void)
1185 {
1186  // syscall0(PEDIGREE_INIT_SIGRET);
1187 }
1188 
1189 int fdatasync(int fildes)
1190 {
1192  return syscall1(POSIX_FSYNC, fildes);
1193 }
1194 
1195 struct dlHandle
1196 {
1197  int mode;
1198 };
1199 
1200 extern void *_libload_dlopen(const char *, int) __attribute__((weak));
1201 extern void *_libload_dlsym(void *, const char *) __attribute__((weak));
1202 extern int _libload_dlclose(void *) __attribute__((weak));
1203 
1204 void *dlopen(const char *file, int mode)
1205 {
1206  return _libload_dlopen(file, mode);
1207 }
1208 
1209 void *dlsym(void *handle, const char *name)
1210 {
1211  return _libload_dlsym(handle, name);
1212 }
1213 
1214 int dlclose(void *handle)
1215 {
1216  return _libload_dlclose(handle);
1217 }
1218 
1219 char *dlerror(void)
1220 {
1221  STUBBED("dlerror");
1222  return 0;
1223 }
1224 
1225 int poll(struct pollfd fds[], unsigned int nfds, int timeout)
1226 {
1227  return (long) syscall3(POSIX_POLL, (long) fds, nfds, timeout);
1228 }
1229 
1230 unsigned int htonl(unsigned int n)
1231 {
1232  return HOST_TO_BIG32(n);
1233 }
1234 unsigned int ntohl(unsigned int n)
1235 {
1236  return BIG_TO_HOST32(n);
1237 }
1238 
1239 unsigned short htons(unsigned short n)
1240 {
1241  return HOST_TO_BIG16(n);
1242 }
1243 unsigned short ntohs(unsigned short n)
1244 {
1245  return BIG_TO_HOST16(n);
1246 }
1247 
1248 void sync(void)
1249 {
1250  STUBBED("sync");
1251 }
1252 
1253 int mknod(const char *path, mode_t mode, dev_t dev)
1254 {
1255  STUBBED("mknod");
1256  return -1;
1257 }
1258 
1259 int getpwuid_r(
1260  uid_t uid, struct passwd *pwd, char *buffer, size_t bufsize,
1261  struct passwd **result)
1262 {
1263  STUBBED("getpwuid_r");
1264  return -1;
1265 }
1266 
1267 int getgrgid_r(
1268  gid_t gid, struct group *grp, char *buffer, size_t bufsize,
1269  struct group **result)
1270 {
1271  STUBBED("getgrgid_r");
1272  return -1;
1273 }
1274 
1275 int getpwnam_r(
1276  const char *name, struct passwd *pwd, char *buffer, size_t bufsize,
1277  struct passwd **result)
1278 {
1279  STUBBED("getpwnam_r");
1280  return -1;
1281 }
1282 
1283 int getgrnam_r(
1284  const char *name, struct group *grp, char *buffer, size_t bufsize,
1285  struct group **result)
1286 {
1287  STUBBED("getgrnam_r");
1288  return -1;
1289 }
1290 
1291 void err(int eval, const char *fmt, ...) _ATTRIBUTE((noreturn));
1292 void err(int eval, const char *fmt, ...)
1293 {
1294  printf(
1295  "err: %d: (todo: print format string based on arguments): %s\n", errno,
1296  strerror(errno));
1297  exit(eval);
1298 }
1299 
1300 long timegm(struct tm *tm)
1301 {
1302  STUBBED("timegm");
1303  return -1;
1304 }
1305 
1306 int chroot(const char *path)
1307 {
1308  return syscall1(POSIX_CHROOT, (long) path);
1309 }
1310 
1311 char *mkdtemp(char *template)
1312 {
1313  if (!template)
1314  {
1315  errno = EINVAL;
1316  return 0;
1317  }
1318 
1319  // Check for correct template - ends in 6 'X' characters.
1320  size_t template_len = strlen(template);
1321  if (template_len < 6)
1322  {
1323  errno = EINVAL;
1324  return 0;
1325  }
1326 
1327  for (size_t i = (template_len - 6); i < template_len; ++i)
1328  {
1329  if (template[i] != 'X')
1330  {
1331  errno = EINVAL;
1332  return 0;
1333  }
1334  }
1335 
1336  while (1)
1337  {
1338  // Generate a filename.
1339  for (size_t i = (template_len - 6); i < template_len; ++i)
1340  template[i] = safepathchars[rand() % SAFE_PATH_LEN];
1341 
1342  if (mkdir(template, 0700) == 0)
1343  return template;
1344  else if (errno != EEXIST)
1345  {
1346  // eg ENOENT, ENOTDIR, EROFS, etc...
1347  return 0;
1348  }
1349  }
1350 
1351  return 0;
1352 }
1353 
1354 int getitimer(int which, struct itimerval *value)
1355 {
1356  STUBBED("getitimer");
1357  return -1;
1358 }
1359 
1360 int setitimer(
1361  int which, const struct itimerval *value, struct itimerval *ovalue)
1362 {
1363  STUBBED("setitimer");
1364  return -1;
1365 }
1366 
1368 {
1369  void *addr;
1370  size_t len;
1371  int prot;
1372  int flags;
1373  int fildes;
1374  off_t off;
1375 };
1376 
1377 void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
1378 {
1379  struct _mmap_tmp t;
1380  t.addr = addr;
1381  t.len = len;
1382  t.prot = prot;
1383  t.flags = flags;
1384  t.fildes = fildes;
1385  t.off = off;
1386 
1387  uintptr_t result = syscall1(POSIX_MMAP, (long) &t);
1388  return (void *) result;
1389 }
1390 
1391 int msync(void *addr, size_t len, int flags)
1392 {
1393  return (int) syscall3(POSIX_MSYNC, (long) addr, (long) len, flags);
1394 }
1395 
1396 int munmap(void *addr, size_t len)
1397 {
1398  return (long) syscall2(POSIX_MUNMAP, (long) addr, (long) len);
1399 }
1400 
1401 int getgroups(int gidsetsize, gid_t grouplist[])
1402 {
1403  if (gidsetsize == 0)
1404  {
1405  return 1;
1406  }
1407  else
1408  {
1409  if (!grouplist)
1410  {
1411  errno = EINVAL;
1412  return -1;
1413  }
1414 
1415  grouplist[0] = getgid();
1416  return 1;
1417  }
1418 }
1419 
1420 size_t getpagesize(void)
1421 {
1422  // Avoid masses of system calls by assuming the page size doesn't actually
1423  // ever change.
1424  static size_t sz = (size_t) ~0;
1425  if (sz == (size_t) ~0)
1426  sz = sysconf(_SC_PAGESIZE);
1427  return sz;
1428 }
1429 
1430 char *realpath(const char *file_name, char *resolved_name)
1431 {
1432  if (!file_name)
1433  {
1434  errno = EINVAL;
1435  return 0;
1436  }
1437 
1438  if (!resolved_name)
1439  {
1440  resolved_name = (char *) malloc(PATH_MAX);
1441  }
1442 
1443  int n = syscall3(
1444  POSIX_REALPATH, (long) file_name, (long) resolved_name, PATH_MAX);
1445  if (n != 0)
1446  return 0;
1447 
1448  return resolved_name;
1449 }
1450 
1451 pid_t setsid(void)
1452 {
1453  return syscall0(POSIX_SETSID);
1454 }
1455 
1456 int setpgid(pid_t pid, pid_t pgid)
1457 {
1458  return syscall2(POSIX_SETPGID, (long) pid, (long) pgid);
1459 }
1460 
1461 pid_t getpgid(pid_t pid)
1462 {
1463  if (pid)
1464  {
1465  errno = EINVAL;
1466  return (pid_t) -1;
1467  }
1468 
1469  return getpgrp();
1470 }
1471 
1472 pid_t getpgrp(void)
1473 {
1474  return syscall0(POSIX_GETPGRP);
1475 }
1476 
1477 pid_t getppid(void)
1478 {
1479  return syscall0(POSIX_GETPPID);
1480 }
1481 
1482 int getrlimit(int resource, struct rlimit *rlp)
1483 {
1484  STUBBED("setrlimit");
1485  return -1;
1486 }
1487 
1488 int setrlimit(int resource, const struct rlimit *rlp)
1489 {
1490  STUBBED("setrlimit");
1491  return -1;
1492 }
1493 
1495 int getmntinfo(struct statvfs **mntbufp, int flags)
1496 {
1497  STUBBED("getmntinfo");
1498  return -1;
1499 }
1500 
1501 FILE *setmntent(const char *filename, const char *type)
1502 {
1503  STUBBED("setmntent");
1504  return 0;
1505 }
1506 
1507 struct mntent *getmntent(FILE *fp)
1508 {
1509  STUBBED("getmntent");
1510  return 0;
1511 }
1512 
1513 int endmntent(FILE *fp)
1514 {
1515  STUBBED("endmntent");
1516  return -1;
1517 }
1518 
1519 int statvfs(const char *path, struct statvfs *buf)
1520 {
1521  return syscall2(POSIX_STATVFS, (long) path, (long) buf);
1522 }
1523 
1524 int fstatvfs(int fd, struct statvfs *buf)
1525 {
1526  return syscall2(POSIX_FSTATVFS, fd, (long) buf);
1527 }
1528 
1529 struct fstab *getfsent(void)
1530 {
1531  STUBBED("getfsent");
1532  return 0;
1533 }
1534 
1535 struct fstab *getfsfile(const char *mount_point)
1536 {
1537  STUBBED("getfsfile");
1538  return 0;
1539 }
1540 
1541 struct fstab *getfsspec(const char *special_file)
1542 {
1543  STUBBED("getfsspec");
1544  return 0;
1545 }
1546 
1547 int setfsent(void)
1548 {
1549  STUBBED("setfsent");
1550  return -1;
1551 }
1552 
1553 void endfsent(void)
1554 {
1555  STUBBED("endfsent");
1556 }
1557 
1558 int getrusage(int who, struct rusage *r_usage)
1559 {
1560  return syscall2(POSIX_GETRUSAGE, who, (long) r_usage);
1561 }
1562 
1563 int sigaltstack(const struct stack_t *stack, struct stack_t *oldstack)
1564 {
1565  return syscall2(POSIX_SIGALTSTACK, (long) stack, (long) oldstack);
1566 }
1567 
1568 int sem_close(sem_t *sem)
1569 {
1570  return syscall1(POSIX_SEM_CLOSE, (long) sem);
1571 }
1572 
1573 int sem_destroy(sem_t *sem)
1574 {
1575  return syscall1(POSIX_SEM_DESTROY, (long) sem);
1576 }
1577 
1578 int sem_getvalue(sem_t *sem, int *val)
1579 {
1580  return syscall2(POSIX_SEM_GETVALUE, (long) sem, (long) val);
1581 }
1582 
1583 int sem_init(sem_t *sem, int pshared, unsigned value)
1584 {
1585  return syscall3(POSIX_SEM_INIT, (long) sem, pshared, value);
1586 }
1587 
1588 sem_t *sem_open(const char *name, int mode, ...)
1589 {
1590  STUBBED("sem_open");
1591  return 0;
1592 }
1593 
1594 int sem_post(sem_t *sem)
1595 {
1596  return syscall1(POSIX_SEM_POST, (long) sem);
1597 }
1598 
1599 int sem_timedwait(sem_t *sem, const struct timespec *tm)
1600 {
1601  return syscall2(POSIX_SEM_TIMEWAIT, (long) sem, (long) tm);
1602 }
1603 
1604 int sem_trywait(sem_t *sem)
1605 {
1606  return syscall1(POSIX_SEM_TRYWAIT, (long) sem);
1607 }
1608 
1609 int sem_unlink(const char *name)
1610 {
1611  STUBBED("sem_unlink");
1612  return -1;
1613 }
1614 
1615 int sem_wait(sem_t *sem)
1616 {
1617  return syscall1(POSIX_SEM_WAIT, (long) sem);
1618 }
1619 
1620 int pthread_atfork(
1621  void (*prepare)(void), void (*parent)(void), void (*child)(void))
1622 {
1623  // Already full?
1624  if (nHandlers == NUM_ATFORK_HANDLERS)
1625  {
1626  errno = ENOMEM;
1627  return -1;
1628  }
1629 
1630  // Create and insert
1631  struct forkHandler handler;
1632  handler.prepare = prepare;
1633  handler.parent = parent;
1634  handler.child = child;
1635  atforkHandlers[nHandlers++] = handler;
1636  return 0;
1637 }
1638 
1639 void closelog()
1640 {
1641 }
1642 
1643 void openlog(const char *log, int logopt, int facility)
1644 {
1645 }
1646 
1647 int setlogmask(int mask)
1648 {
1649  return 0;
1650 }
1651 
1652 void syslog(int prio, const char *fmt, ...)
1653 {
1654  static char print_temp[1024];
1655  va_list argptr;
1656  va_start(argptr, fmt);
1657  vsnprintf(print_temp, sizeof print_temp, fmt, argptr);
1658  syscall2(POSIX_SYSLOG, (long) print_temp, prio);
1659  va_end(argptr);
1660 }
1661 
1662 int pause()
1663 {
1664  STUBBED("pause");
1665  return -1;
1666 }
1667 
1668 pid_t forkpty(
1669  int *amaster, char *name, struct termios *termp, struct winsize *winp)
1670 {
1671  STUBBED("forkpty");
1672  errno = ENOENT;
1673  return -1;
1674 }
1675 
1676 struct utmp *pututline(struct utmp *ut)
1677 {
1678  STUBBED("pututline");
1679  return 0;
1680 }
1681 
1682 void logwtmp(const char *line, const char *name, const char *host)
1683 {
1684  STUBBED("logwtmp");
1685 }
1686 
1687 unsigned if_nametoindex(const char *name)
1688 {
1689  STUBBED("if_nametoindex");
1690  return 0;
1691 }
1692 
1693 char *if_indextoname(unsigned index, char *buf)
1694 {
1695  STUBBED("if_indextoname");
1696  errno = ENXIO;
1697  return 0;
1698 }
1699 
1700 struct if_nameindex *if_nameindex()
1701 {
1702  STUBBED("if_nameindex");
1703  errno = ENOBUFS;
1704  return 0;
1705 }
1706 
1707 void if_freenameindex(struct if_nameindex *nameindex)
1708 {
1709  STUBBED("if_freenameindex");
1710 }
1711 
1712 int sigsetjmp(sigjmp_buf env, int savemask)
1713 {
1714  // mask is not relevant currently.
1715  return setjmp(env);
1716 }
1717 
1718 void siglongjmp(sigjmp_buf env, int val)
1719 {
1720  longjmp(env, val);
1721 }
1722 
1723 char *basename(char *path)
1724 {
1725  static char bad[2] = {'.', 0};
1726  if ((path == NULL) || (path && !*path))
1727  return bad;
1728 
1729  char *p = strrchr(path, '/');
1730  if (!p)
1731  return path;
1732  else
1733  return p + 1;
1734 }
1735 
1736 int reboot(int howto)
1737 {
1738  return pedigree_reboot();
1739 }
1740 
1741 int initgroups(const char *user, gid_t group)
1742 {
1743  STUBBED("initgroups");
1744  return 0;
1745 }
1746 
1747 int setgroups(int ngroups, const gid_t *gidset)
1748 {
1749  STUBBED("setgroups");
1750  return 0;
1751 }
1752 
1753 ssize_t getdelim(char **a, size_t *b, int c, FILE *d)
1754 {
1755  return __getdelim(a, b, c, d);
1756 }
1757 ssize_t getline(char **a, size_t *b, FILE *c)
1758 {
1759  return __getline(a, b, c);
1760 }
1761 
1762 int sched_yield()
1763 {
1764  return syscall0(POSIX_SCHED_YIELD);
1765 }
1766 
1767 int getdtablesize()
1768 {
1769  STUBBED("getdtablesize");
1770 
1771  struct rlimit tmp;
1772  getrlimit(RLIMIT_NOFILE, &tmp);
1773  return tmp.rlim_cur;
1774 }
1775 
1776 int mprotect(void *addr, size_t len, int prot)
1777 {
1778  return syscall3(POSIX_MPROTECT, (long) addr, len, prot);
1779 }
1780 
1781 int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
1782 {
1783  if (!rqtp)
1784  {
1785  errno = EINVAL;
1786  return -1;
1787  }
1788 
1789  return syscall2(POSIX_NANOSLEEP, (long) rqtp, (long) rmtp);
1790 }
1791 
1792 int clock_getres(clockid_t clock_id, struct timespec *res)
1793 {
1794  if (!res)
1795  {
1796  errno = EINVAL;
1797  return -1;
1798  }
1799 
1800  // Nanosecond resolution.
1801  res->tv_nsec = 1;
1802  res->tv_sec = 0;
1803 
1804  return 0;
1805 }
1806 
1807 int setreuid(uid_t ruid, uid_t euid)
1808 {
1809  STUBBED("setreuid");
1810  return 0;
1811 }
1812 
1813 int grantpt(int fildes)
1814 {
1815  STUBBED("grantpt");
1816  return 0;
1817 }
1818 
1819 int unlockpt(int fildes)
1820 {
1821  STUBBED("unlockpt");
1822  return 0;
1823 }
1824 
1825 char *ptsname(int fildes)
1826 {
1827  static char ret[256] = {0};
1828  ret[0] = 0;
1829  int res = syscall2(POSIX_PTSNAME, fildes, (long) ret);
1830  if (res < 0)
1831  return 0;
1832  return ret;
1833 }
1834 
1835 char *ttyname(int fildes)
1836 {
1837  static char ret[256] = {0};
1838  ret[0] = 0;
1839  int res = syscall2(POSIX_TTYNAME, fildes, (long) ret);
1840  if (res < 0)
1841  return 0;
1842  return ret;
1843 }
1844 
1845 char *crypt(const char *key, const char *salt)
1846 {
1847  STUBBED("crypt");
1848  return 0;
1849 }
1850 
1851 int ffsl(long int i)
1852 {
1853  return __builtin_ffs(i);
1854 }
1855 
1856 int ffsll(long long int i)
1857 {
1858  return __builtin_ffsll(i);
1859 }
1860 
1861 void __pedigree_revoke_signal_context()
1862 {
1863  // Call into the kernel.
1864  syscall0(PEDIGREE_UNWIND_SIGNAL);
1865 }
1866 
1872 void *_malloc_r(struct _reent *ptr, size_t sz)
1873 {
1874  return malloc(sz);
1875 }
1876 
1877 void *_calloc_r(struct _reent *ptr, size_t a, size_t b)
1878 {
1879  return calloc(a, b);
1880 }
1881 
1882 void *_realloc_r(struct _reent *ptr, void *p, size_t sz)
1883 {
1884  return realloc(p, sz);
1885 }
1886 
1887 void *_memalign_r(struct _reent *ptr, size_t align, size_t nbytes)
1888 {
1889  return memalign(align, nbytes);
1890 }
1891 
1892 void _free_r(struct _reent *ptr, void *p)
1893 {
1894  free(p);
1895 }
1896 
1897 int posix_openpt(int oflag)
1898 {
1899  int master = 0;
1900  char name[16] = {0};
1901  const char *x, *y;
1902 
1903  oflag &= O_RDWR | O_NOCTTY;
1904 
1905  strcpy(name, "/dev/ptyXX");
1906  for (x = "pqrstuvwxyzabcde"; *x; ++x)
1907  {
1908  for (y = "0123456789abcdef"; *y; ++y)
1909  {
1910  name[8] = *x;
1911  name[9] = *y;
1912 
1913  master = open(name, oflag);
1914  if (master >= 0)
1915  return master;
1916  else if (errno == ENOENT)
1917  {
1918  // Console does not exist.
1919  return -1;
1920  }
1921  else
1922  continue; // Console already used.
1923  }
1924  }
1925 
1926  errno = EAGAIN;
1927  return -1;
1928 }
1929 
1930 int openpty(
1931  int *amaster, int *aslave, char *name, const struct termios *termp,
1932  const struct winsize *winp)
1933 {
1934  if (amaster == NULL)
1935  {
1936  errno = EINVAL;
1937  return -1;
1938  }
1939 
1940  // Grab the pty master.
1941  *amaster = posix_openpt(O_RDWR);
1942  if (aslave)
1943  {
1944  // Grab the slave name (ttyname will just return the master name).
1945  // We don't assume BSD or UNIX 98 psuedo-terminals here.
1946  char *slavename = ptsname(*amaster);
1947  *aslave = open(slavename, O_RDWR | O_NOCTTY);
1948  if (name)
1949  strcpy(name, slavename);
1950  }
1951 
1952  if (termp)
1953  {
1954  // Set the attributes of the terminal.
1955  tcsetattr(*aslave, TCSANOW, termp);
1956  }
1957 
1958  if (winp)
1959  {
1960  // Set the size of the terminal to the requested size.
1961  ioctl(*amaster, TIOCSWINSZ, winp);
1962  }
1963 
1964  return 0;
1965 }
Definition: cmd.h:30
#define IN6ADDR_ANY_INIT
Definition: inet.h:100
Definition: inet.h:81
#define IN6ADDR_LOOPBACK_INIT
Definition: inet.h:103
const struct in6_addr in6addr_any
Definition: glue.c:123