LibXenon
Bare-metal Xbox 360 homebrew library
Loading...
Searching...
No Matches
newlib.c
Go to the documentation of this file.
1#include <_ansi.h>
2#include <_syslist.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <ctype.h>
6#include <string.h>
7#include <errno.h>
8#include <sys/iosupport.h>
9#include <sys/dirent.h>
10#include <sys/errno.h>
11#include <sys/time.h>
12#include <sys/resource.h>
13#include <sys/unistd.h>
14#include <diskio/disc_io.h>
16
17#include <debug.h>
18
19void (*stdout_hook)(const char *text, int len) = 0;
20void (*stdlog_hook)(const char *text, int len) = 0;
21
25ssize_t vfs_console_write(struct _reent *r, int fd, const char *src, size_t len) {
26 if (stdout_hook)
27 stdout_hook(src, len);
28 if (stdlog_hook)
29 stdlog_hook(src, len);
30 size_t i;
31 for (i = 0; i < len; ++i)
32 putch(((const char*) src)[i]);
33 return len;
34}
35//---------------------------------------------------------------------------------
37 //---------------------------------------------------------------------------------
38 "stdout", // device name
39 0, // size of file structure
40 NULL, // device open
41 NULL, // device close
42 vfs_console_write, // device write
43 NULL, // device read
44 NULL, // device seek
45 NULL, // device fstat
46 NULL, // device stat
47 NULL, // device link
48 NULL, // device unlink
49 NULL, // device chdir
50 NULL, // device rename
51 NULL, // device mkdir
52 0, // dirStateSize
53 NULL, // device diropen_r
54 NULL, // device dirreset_r
55 NULL, // device dirnext_r
56 NULL, // device dirclose_r
57 NULL, // device statvfs_r
58 NULL, // device ftrunctate_r
59 NULL, // device fsync_r
60 NULL, // deviceData;
61};
62
63/*
64 * System stuff
65 */
66int __libc_lock_init(int *lock, int recursive) {
67
69 return __syscalls.lock_init(lock, recursive);
70 }
71
72 return 0;
73}
74
76
79 }
80
81 return 0;
82}
83
85
88 }
89
90 return 0;
91}
92
94
97 }
98
99 return 0;
100}
101
102void __malloc_lock(struct _reent *ptr) {
103
106 }
107}
108
109void __malloc_unlock(struct _reent *ptr) {
110
113 }
114}
115
116void _exit(int status) {
117 if (__syscalls.exit) {
119 }
120
121 for(;;);
122}
123
124void * sbrk(ptrdiff_t incr) {
125 struct _reent *ptr = _REENT;
126 if (__syscalls.sbrk_r) {
127 return __syscalls.sbrk_r(ptr, incr);
128 } else {
129 ptr->_errno = ENOMEM;
130 return (caddr_t) - 1;
131 }
132}
133
134//---------------------------------------------------------------------------------
135
136void abort(void) {
137 vfs_console_write(NULL, 0, "Abort called.\n", sizeof ("Abort called.\n") - 1);
138 _exit(1);
139}
140//---------------------------------------------------------------------------------
141
142void *dlopen(const char * c, int i) {
143 return NULL;
144}
145
146void *dlsym(void * p, const char * s) {
147 return NULL;
148}
149
150int dlclose(void * p) {
151 return -1;
152}
153
154char *dlerror(void) {
155 return "";
156}
157
158//---------------------------------------------------------------------------------
159
160FILE *popen(const char * s1, const char * s2){
161 return NULL;
162}
163
164int pclose(FILE * f) {
165 return -1;
166}
167
168//---------------------------------------------------------------------------------
169
170int execve(const char *path, char * const argv[], char * const envp[]) {
171 struct _reent *r = _REENT;
172 r->_errno = ENOSYS;
173 return -1;
174}
175
176int execv(const char *path, char * const argv[]) {
177 return execve(path, argv, NULL);
178}
179
180int execvp(const char *file, char * const argv[]) {
181 return execve(file, argv, NULL);
182}
183
184//---------------------------------------------------------------------------------
185
186int fork() {
187 struct _reent *r = _REENT;
188 r->_errno = ENOSYS;
189 return -1;
190}
191//---------------------------------------------------------------------------------
192
193int getpid() {
194 struct _reent *ptr = _REENT;
195 ptr->_errno = ENOSYS;
196 return -1;
197}
198
199pid_t waitpid(pid_t pid, int *stat_loc, int options) {
200 return (pid_t)-1;
201}
202
203//---------------------------------------------------------------------------------
204
205int mkfifo(const char *pathname, mode_t mode) {
206 return -1;
207}
208
209//---------------------------------------------------------------------------------
210
211int lstat(const char * path, struct stat * buf) {
212 return -1;
213}
214
215//---------------------------------------------------------------------------------
216
217int access(const char * path, int mode){
218 struct stat information;
219 int ok = stat(path, &information);
220 // printf("stat of '%s' is %d\n", path.c_str(), ok);
221 if (ok == 0){
222 if (mode == R_OK){
223 if (((information.st_mode & S_IRUSR) == S_IRUSR) ||
224 ((information.st_mode & S_IRGRP) == S_IRGRP) ||
225 ((information.st_mode & S_IROTH) == S_IROTH)){
226 return 0;
227 } else {
228 /* handle other modes if they become useful to us */
229 return -1;
230 }
231 } else {
232 return -1;
233 }
234 } else {
235 // perror("stat");
236 return -1;
237 }
238}
239
240//---------------------------------------------------------------------------------
241
242int getrusage(int who, struct rusage *usage) {
243 struct _reent *ptr = _REENT;
244 ptr->_errno = ENOSYS;
245 return -1;
246}
247
248int gettimeofday(struct timeval *ptimeval, void *ptimezone) {
249 struct _reent *ptr = _REENT;
250
252 return __syscalls.gettod_r(ptr, ptimeval, ptimezone);
253
254 ptr->_errno = ENOSYS;
255 return -1;
256
257}
258
259int isatty(int file) {
260 return 0;
261}
262
263int kill(int pid, int sig) {
264 struct _reent *ptr = _REENT;
265 ptr->_errno = ENOSYS;
266 return -1;
267}
268
269int gethostname(char *name, size_t len) {
270 strncpy(name,"xenon",len);
271 return 0;
272}
273//---------------------------------------------------------------------------------
274
275/*
276int
277_DEFUN(wait, (status),
278 int *status) {
279 struct _reent *r = _REENT;
280 r->_errno = ENOSYS;
281 return -1;
282}
283 */
284
288#define ROOT_UID 0
289#define ROOT_GID 0
290
291uid_t getuid(void) {
292 return ROOT_UID;
293}
294
295uid_t geteuid(void) {
296 return ROOT_UID;
297}
298
299gid_t getgid(void) {
300 return ROOT_GID;
301}
302
303gid_t getegid(void) {
304 return ROOT_GID;
305}
306
307int setuid(uid_t uid) {
308 return (uid == ROOT_UID ? 0 : -1);
309}
310
311int setgid(gid_t gid) {
312 return (gid == ROOT_GID ? 0 : -1);
313}
314
315pid_t getppid(void) {
316 return 0;
317}
318
319void *getpwuid(uid_t uid) {
320 TR
321 return NULL;
322}
323
324void *getpwnam(const char *name) {
325 TR
326 return NULL;
327};
328
329void *getgrnam(const char *name) {
330 TR
331 return NULL;
332};
333
334void *getgrgid(gid_t gid) {
335 TR
336 return NULL;
337};
338
339
344#define MAX_HANDLES 1024
345
346static __handle* handles[MAX_HANDLES];
347__attribute__((unused)) static int __hndl_lock = 0;
348
349void __release_handle(int fd) {
350
351 if (fd < 3 || fd >= MAX_HANDLES + 3) return;
352
353 fd -= 3;
354 __handle* handle = handles[fd];
355 if (NULL != handle) {
356 free(handle);
357 handles[fd] = NULL;
358 }
359
360}
361
363
364 int i, ret = -1;
365
366 __lock_acquire_recursive(__hndl_lock);
367 for (i = 0; i < MAX_HANDLES; i++) {
368 if (handles[i] == NULL) break;
369 }
370
371 if (i < MAX_HANDLES) {
372 handles[i] = malloc(size);
373 if (NULL != handles[i]) ret = i + 3;
374 }
375 __lock_release_recursive(__hndl_lock);
376
377 return ret;
378}
379
381
382 if (fd < 3 || fd > MAX_HANDLES + 3) return NULL;
383
384 return handles[fd - 3];
385
386}
387
392static int defaultDevice = -1;
393
394//---------------------------------------------------------------------------------
395
396void setDefaultDevice(int device) {
397 //---------------------------------------------------------------------------------
398
399 if (device > 2 && device <= STD_MAX)
400 defaultDevice = device;
401}
402
403//---------------------------------------------------------------------------------
405 //---------------------------------------------------------------------------------
406 "stdnull", // device name
407 0, // size of file structure
408 NULL, // device open
409 NULL, // device close
410 NULL, // device write
411 NULL, // device read
412 NULL, // device seek
413 NULL, // device fstat
414 NULL, // device stat
415 NULL, // device link
416 NULL, // device unlink
417 NULL, // device chdir
418 NULL, // device rename
419 NULL, // device mkdir
420 0, // dirStateSize
421 NULL, // device diropen_r
422 NULL, // device dirreset_r
423 NULL, // device dirnext_r
424 NULL, // device dirclose_r
425 NULL, // device statvfs_r
426 NULL, // device ftruncate_r
427 NULL, // device fsync_r
428 NULL // deviceData
429};
430
431//---------------------------------------------------------------------------------
433 //---------------------------------------------------------------------------------
434 //&dotab_stdnull, &dotab_stdnull, &dotab_stdnull, &dotab_stdnull,
439};
440
441//---------------------------------------------------------------------------------
442
443int FindDevice(const char* name) {
444 //---------------------------------------------------------------------------------
445 int i = 0, namelen, dev = -1;
446
447 if (strchr(name, ':') == NULL) return defaultDevice;
448
449 while (i < STD_MAX) {
450 if (devoptab_list[i]) {
451 namelen = strlen(devoptab_list[i]->name);
452 if (strncmp(devoptab_list[i]->name, name, namelen) == 0) {
453 if (name[namelen] == ':' || (isdigit((int)name[namelen]) && name[namelen + 1] == ':')) {
454 dev = i;
455 break;
456 }
457 }
458 }
459 i++;
460 }
461
462 return dev;
463}
464
465//---------------------------------------------------------------------------------
466
467int RemoveDevice(const char* name) {
468 //---------------------------------------------------------------------------------
469 int dev = FindDevice(name);
470
471 if (-1 != dev) {
473 return 0;
474 }
475
476 return -1;
477
478}
479
480//---------------------------------------------------------------------------------
481
482int AddDevice(const devoptab_t* device) {
483 //---------------------------------------------------------------------------------
484
485 int devnum;
486
487 for (devnum = 3; devnum < STD_MAX; devnum++) {
488
489 if ((!strcmp(devoptab_list[devnum]->name, device->name) &&
490 strlen(devoptab_list[devnum]->name) == strlen(device->name)) ||
491 !strcmp(devoptab_list[devnum]->name, "stdnull")
492 )
493 break;
494 }
495
496 if (devnum == STD_MAX) {
497 devnum = -1;
498 } else {
499 devoptab_list[devnum] = device;
500 }
501 return devnum;
502}
503
504//---------------------------------------------------------------------------------
505
506const devoptab_t* GetDeviceOpTab(const char *name) {
507 //---------------------------------------------------------------------------------
508 int dev = FindDevice(name);
509 if (dev >= 0 && dev < STD_MAX) {
510 return devoptab_list[dev];
511 } else {
512 return NULL;
513 }
514}
515
520//---------------------------------------------------------------------------------
521
522int open(const char *file, int flags, int mode) {
523 struct _reent *r = _REENT;
524
525 __handle *handle;
526 int dev, fd, ret;
527
528 dev = FindDevice(file);
529
530 fd = -1;
531 if (dev != -1 && devoptab_list[dev]->open_r) {
532
533 fd = __alloc_handle(sizeof (__handle) + devoptab_list[dev]->structSize);
534
535 if (-1 != fd) {
536 handle = __get_handle(fd);
537 handle->device = dev;
538 handle->fileStruct = ((void *) handle) + sizeof (__handle);
539
540 ret = devoptab_list[dev]->open_r(r, handle->fileStruct, file, flags, mode);
541
542 if (ret == -1) {
543 __release_handle(fd);
544 fd = -1;
545 }
546 } else {
547 r->_errno = ENOSR;
548 }
549 } else {
550 r->_errno = ENOSYS;
551 }
552
553 return fd;
554}
555
556
557//---------------------------------------------------------------------------------
558
559int read(int fileDesc, void *ptr, size_t len) {
560 struct _reent *r = _REENT;
561 int ret = -1;
562 unsigned int dev = 0;
563 unsigned int fd = -1;
564
565 __handle * handle = NULL;
566
567 if (fileDesc != -1) {
568 if (fileDesc < 3) {
569 dev = fileDesc;
570 } else {
571 handle = __get_handle(fileDesc);
572
573 if (NULL == handle) return ret;
574
575 dev = handle->device;
576 fd = (int) handle->fileStruct;
577 }
578 if (devoptab_list[dev]->read_r)
579 ret = devoptab_list[dev]->read_r(r, fd, ptr, len);
580 }
581 return ret;
582}
583
584int write(int fileDesc, const void *ptr, size_t len) {
585 struct _reent *r = _REENT;
586 int ret = -1;
587 unsigned int dev = 0;
588 unsigned int fd = -1;
589
590 __handle * handle = NULL;
591
592
593 if (fileDesc != -1) {
594 if (fileDesc < 3) {
595 dev = fileDesc;
596 ret = len;
597 } else {
598 handle = __get_handle(fileDesc);
599
600 if (NULL == handle) return ret;
601
602 dev = handle->device;
603 fd = (int) handle->fileStruct;
604 }
605 if (devoptab_list[dev]->write_r)
606 ret = devoptab_list[dev]->write_r(r, fd, ptr, len);
607 }
608 return ret;
609}
610
611
612//---------------------------------------------------------------------------------
613
614int fstat(int fileDesc, struct stat *st) {
615 //---------------------------------------------------------------------------------
616 struct _reent *r = _REENT;
617 int ret = -1;
618 unsigned int dev = 0;
619 unsigned int fd = -1;
620
621 __handle * handle = NULL;
622
623 if (fileDesc != -1) {
624 if (fileDesc < 3) {
625 dev = fileDesc;
626 } else {
627 handle = __get_handle(fileDesc);
628
629 if (NULL == handle) return ret;
630
631 dev = handle->device;
632 fd = (int) handle->fileStruct;
633 }
634 if (devoptab_list[dev]->fstat_r) {
635 ret = devoptab_list[dev]->fstat_r(r, fd, st);
636 } else {
637 r->_errno = ENOSYS;
638 }
639 }
640 return ret;
641}
642
643int stat(const char *file, struct stat *st) {
644 //---------------------------------------------------------------------------------
645 struct _reent *r = _REENT;
646 int dev, ret;
647
648 dev = FindDevice(file);
649
650 if (dev != -1 && devoptab_list[dev]->stat_r) {
651 ret = devoptab_list[dev]->stat_r(r, file, st);
652 } else {
653 ret = -1;
654 r->_errno = ENODEV;
655 }
656 return ret;
657}
658
659int statvfs(const char *path, struct statvfs *buf) {
660 struct _reent *r = _REENT;
661
662 int ret;
663 int device = FindDevice(path);
664
665 ret = -1;
666
667 if (device != -1 && devoptab_list[device]->statvfs_r) {
668
669 ret = devoptab_list[device]->statvfs_r(r, path, buf);
670
671 } else {
672 r->_errno = ENOSYS;
673 }
674
675 return ret;
676}
677
678int fsync(int fileDesc) {
679 int ret = -1;
680 unsigned int dev = 0;
681 unsigned int fd = -1;
682
683 __handle * handle;
684
685 if (fileDesc < 3) {
686 errno = EINVAL;
687 } else {
688 handle = __get_handle(fileDesc);
689
690 if (NULL == handle) {
691 errno = EINVAL;
692 return ret;
693 }
694
695 dev = handle->device;
696 fd = (int) handle->fileStruct;
697
698 if (devoptab_list[dev]->fsync_r)
699 ret = devoptab_list[dev]->fsync_r(_REENT, fd);
700 }
701
702 return ret;
703}
704
705int ftruncate(int fileDesc, off_t len) {
706 int ret = -1;
707 unsigned int dev = 0;
708 unsigned int fd = -1;
709
710 __handle * handle;
711
712 if (fileDesc < 3) {
713 errno = EINVAL;
714 } else {
715 handle = __get_handle(fileDesc);
716
717 if (NULL == handle) {
718 errno = EINVAL;
719 return ret;
720 }
721
722 dev = handle->device;
723 fd = (int) handle->fileStruct;
724
725 if (devoptab_list[dev]->ftruncate_r)
726 ret = devoptab_list[dev]->ftruncate_r(_REENT, fd, len);
727 }
728
729 return ret;
730}
731
732int link(const char *existing, const char *new) {
733 struct _reent *r = _REENT;
734 int ret;
735 int sourceDev = FindDevice(existing);
736 int destDev = FindDevice(new);
737
738 ret = -1;
739
740 if (sourceDev == destDev) {
741 if (devoptab_list[destDev]->link_r) {
742 ret = devoptab_list[destDev]->link_r(r, existing, new);
743 } else {
744 r->_errno = ENOSYS;
745 }
746 } else {
747 r->_errno = EXDEV;
748 }
749
750 return ret;
751}
752
753
754//---------------------------------------------------------------------------------
755
756_off_t lseek(int fileDesc, _off_t pos, int dir) {
757 //---------------------------------------------------------------------------------
758 struct _reent *r = _REENT;
759 //---------------------------------------------------------------------------------
760 _off_t ret = -1;
761 unsigned int dev = 0;
762 unsigned int fd = -1;
763
764 __handle * handle;
765
766 if (fileDesc != -1) {
767
768 if (fileDesc < 3) {
769 dev = fileDesc;
770 } else {
771 handle = __get_handle(fileDesc);
772
773 if (NULL == handle) return ret;
774
775 dev = handle->device;
776 fd = (int) handle->fileStruct;
777 }
778
779 if (devoptab_list[dev]->seek_r)
780 ret = devoptab_list[dev]->seek_r(r, fd, pos, dir);
781
782 }
783 return ret;
784
785}
786
787int rename(const char *existing, const char *newName) {
788 struct _reent *r = _REENT;
789
790 int ret;
791 int sourceDev = FindDevice(existing);
792 int destDev = FindDevice(newName);
793
794 ret = -1;
795
796 if (sourceDev == destDev) {
797 if (devoptab_list[destDev]->rename_r) {
798 ret = devoptab_list[destDev]->rename_r(r, existing, newName);
799 } else {
800 r->_errno = ENOSYS;
801 }
802 } else {
803 r->_errno = EXDEV;
804 }
805
806 return ret;
807}
808
809//---------------------------------------------------------------------------------
810
811int unlink(const char *name) {
812 //---------------------------------------------------------------------------------
813 struct _reent *r = _REENT;
814 int dev, ret;
815
816 dev = FindDevice(name);
817 if (dev != -1 && devoptab_list[dev]->unlink_r) {
818 ret = devoptab_list[dev]->unlink_r(r, name);
819 } else {
820 ret = -1;
821 r->_errno = ENODEV;
822 }
823
824 return ret;
825}
826
827//---------------------------------------------------------------------------------
828
829int close(int fileDesc) {
830 //---------------------------------------------------------------------------------
831 struct _reent *ptr = _REENT;
832 int ret = -1;
833 unsigned int dev = 0;
834 unsigned int fd = -1;
835
836 if (fileDesc != -1) {
837
838 __handle *handle = __get_handle(fileDesc);
839
840 if (handle != NULL) {
841 dev = handle->device;
842 fd = (unsigned int) handle->fileStruct;
843
844 if (devoptab_list[dev]->close_r)
845 ret = devoptab_list[dev]->close_r(ptr, fd);
846
847 __release_handle(fileDesc);
848 }
849 }
850 return ret;
851}
856/* CWD always start with "/" */
857static char _current_working_directory [PATH_MAX] = "/";
858
859#define DIRECTORY_SEPARATOR_CHAR '/'
860const char DIRECTORY_SEPARATOR[] = "/";
861const char DIRECTORY_THIS[] = ".";
862const char DIRECTORY_PARENT[] = "..";
863
864int _concatenate_path(struct _reent *r, char *path, const char *extra, int maxLength) {
865 char *pathEnd;
866 int pathLength;
867 const char *extraEnd;
868 int extraSize;
869
870 pathLength = strnlen(path, maxLength);
871
872 /* assumes path ends in a directory separator */
873 if (pathLength >= maxLength) {
874 r->_errno = ENAMETOOLONG;
875 return -1;
876 }
877 pathEnd = path + pathLength;
878 if (pathEnd[-1] != DIRECTORY_SEPARATOR_CHAR) {
879 pathEnd[0] = DIRECTORY_SEPARATOR_CHAR;
880 pathEnd += 1;
881 }
882
883 extraEnd = extra;
884
885 /* If the extra bit starts with a slash, start at root */
886 if (extra[0] == DIRECTORY_SEPARATOR_CHAR) {
887 pathEnd = strchr(path, DIRECTORY_SEPARATOR_CHAR) + 1;
888 pathEnd[0] = '\0';
889 }
890 do {
891 /* Advance past any separators in extra */
892 while (extra[0] == DIRECTORY_SEPARATOR_CHAR) {
893 extra += 1;
894 }
895
896 /* Grab the next directory name from extra */
897 extraEnd = strchr(extra, DIRECTORY_SEPARATOR_CHAR);
898 if (extraEnd == NULL) {
899 extraEnd = strrchr(extra, '\0');
900 } else {
901 extraEnd += 1;
902 }
903
904 extraSize = (extraEnd - extra);
905 if (extraSize == 0) {
906 break;
907 }
908
909 if ((strncmp(extra, DIRECTORY_THIS, sizeof (DIRECTORY_THIS) - 1) == 0)
910 && ((extra[sizeof (DIRECTORY_THIS) - 1] == DIRECTORY_SEPARATOR_CHAR)
911 || (extra[sizeof (DIRECTORY_THIS) - 1] == '\0'))) {
912 /* Don't copy anything */
913 } else if ((strncmp(extra, DIRECTORY_PARENT, sizeof (DIRECTORY_PARENT) - 1) == 0)
914 && ((extra[sizeof (DIRECTORY_PARENT) - 1] == DIRECTORY_SEPARATOR_CHAR)
915 || (extra[sizeof (DIRECTORY_PARENT) - 1] == '\0'))) {
916 /* Go up one level of in the path */
917 if (pathEnd[-1] == DIRECTORY_SEPARATOR_CHAR) {
918 // Remove trailing separator
919 pathEnd[-1] = '\0';
920 }
921 pathEnd = strrchr(path, DIRECTORY_SEPARATOR_CHAR);
922 if (pathEnd == NULL) {
923 /* Can't go up any higher, return false */
924 r->_errno = ENOENT;
925 return -1;
926 }
927 pathLength = pathEnd - path;
928 pathEnd += 1;
929 } else {
930 pathLength += extraSize;
931 if (pathLength >= maxLength) {
932 r->_errno = ENAMETOOLONG;
933 return -1;
934 }
935 /* Copy the next part over */
936 strncpy(pathEnd, extra, extraSize);
937 pathEnd += extraSize;
938 }
939 pathEnd[0] = '\0';
940 extra += extraSize;
941 } while (extraSize != 0);
942
943 if (pathEnd[-1] != DIRECTORY_SEPARATOR_CHAR) {
944 pathEnd[0] = DIRECTORY_SEPARATOR_CHAR;
945 pathEnd[1] = 0;
946 pathEnd += 1;
947 }
948
949 return 0;
950}
951
952int chdir(const char *path) {
953 struct _reent *r = _REENT;
954
955 int dev;
956 const char *pathPosition;
957 char temp_cwd [PATH_MAX];
958
959 /* Make sure the path is short enough */
960 if (strnlen(path, PATH_MAX + 1) >= PATH_MAX) {
961 r->_errno = ENAMETOOLONG;
962 return -1;
963 }
964
965 if (strchr(path, ':') != NULL) {
966 strncpy(temp_cwd, path, PATH_MAX);
967 /* Move path past device name */
968 path = strchr(path, ':') + 1;
969 } else {
970 strncpy(temp_cwd, _current_working_directory, PATH_MAX);
971 }
972
973 pathPosition = strchr(temp_cwd, ':') + 1;
974
975 /* Make sure the path starts in the root directory */
976 if (pathPosition[0] != DIRECTORY_SEPARATOR_CHAR) {
977 r->_errno = ENOENT;
978 return -1;
979 }
980
981 /* Concatenate the path to the CWD */
982 if (_concatenate_path(r, temp_cwd, path, PATH_MAX) == -1) {
983 return -1;
984 }
985
986 /* Get device from path name */
987 dev = FindDevice(temp_cwd);
988
989 if ((dev < 0) || (devoptab_list[dev]->chdir_r == NULL)) {
990 r->_errno = ENODEV;
991 return -1;
992 }
993
994 /* Try changing directories on the device */
995 if (devoptab_list[dev]->chdir_r(r, temp_cwd) == -1) {
996 return -1;
997 }
998
999 /* Since it worked, set the new CWD and default device */
1000 setDefaultDevice(dev);
1001 strncpy(_current_working_directory, temp_cwd, PATH_MAX);
1002
1003 return 0;
1004}
1005
1006char *getcwd(char * buf, size_t size) {
1007
1008 struct _reent *r = _REENT;
1009
1010 if (size == 0) {
1011 r->_errno = EINVAL;
1012 return NULL;
1013 }
1014
1015 if (size < (strnlen(_current_working_directory, PATH_MAX) + 1)) {
1016 r->_errno = ERANGE;
1017 return NULL;
1018 }
1019
1020 strncpy(buf, _current_working_directory, size);
1021
1022 return buf;
1023}
1024
1025int chmod(const char *path, mode_t mode) {
1026 int ret, dev;
1027 struct _reent *r = _REENT;
1028
1029 /* Get device from path name */
1030 dev = FindDevice(path);
1031
1032 if ((dev < 0) || (devoptab_list[dev]->chmod_r == NULL)) {
1033 r->_errno = ENODEV;
1034 ret = -1;
1035 } else {
1036 ret = devoptab_list[dev]->chmod_r(r, path, mode);
1037 }
1038
1039 return ret;
1040}
1041
1042int fchmod(int fd, mode_t mode) {
1043 int ret = -1, dev;
1044 struct _reent *r = _REENT;
1045
1046 if (fd != -1) {
1047
1048 __handle *handle = __get_handle(fd);
1049
1050 if (handle != NULL) {
1051
1052 dev = handle->device;
1053 fd = (unsigned int) handle->fileStruct;
1054
1055 if (devoptab_list[dev]->fchmod_r)
1056 ret = devoptab_list[dev]->fchmod_r(r, fd, mode);
1057
1058 }
1059 }
1060 return ret;
1061}
1062
1063static DIR_ITER * __diropen(const char *path) {
1064 struct _reent *r = _REENT;
1065 DIR_ITER *handle = NULL;
1066 DIR_ITER *dir = NULL;
1067 int dev;
1068
1069 dev = FindDevice(path);
1070
1071 if (dev != -1 && devoptab_list[dev]->diropen_r) {
1072
1073 handle = (DIR_ITER *) malloc(sizeof (DIR_ITER) + devoptab_list[dev]->dirStateSize);
1074
1075 if (NULL != handle) {
1076 handle->device = dev;
1077 handle->dirStruct = ((void *) handle) + sizeof (DIR_ITER);
1078
1079 dir = devoptab_list[dev]->diropen_r(r, handle, path);
1080
1081 if (dir == NULL) {
1082 free(handle);
1083 handle = NULL;
1084 }
1085 } else {
1086 r->_errno = ENOSR;
1087 handle = NULL;
1088 }
1089 } else {
1090 r->_errno = ENOSYS;
1091 }
1092
1093 return handle;
1094}
1095
1096static int __dirreset(DIR_ITER *dirState) {
1097 struct _reent *r = _REENT;
1098 int ret = -1;
1099 int dev = 0;
1100
1101 if (dirState != NULL) {
1102 dev = dirState->device;
1103
1104 if (devoptab_list[dev]->dirreset_r) {
1105 ret = devoptab_list[dev]->dirreset_r(r, dirState);
1106 } else {
1107 r->_errno = ENOSYS;
1108 }
1109 }
1110 return ret;
1111}
1112
1113static int __dirnext(DIR_ITER *dirState, char *filename, struct stat *filestat) {
1114 struct _reent *r = _REENT;
1115 int ret = -1;
1116 int dev = 0;
1117
1118 if (dirState != NULL) {
1119 dev = dirState->device;
1120
1121 if (devoptab_list[dev]->dirnext_r) {
1122 ret = devoptab_list[dev]->dirnext_r(r, dirState, filename, filestat);
1123 } else {
1124 r->_errno = ENOSYS;
1125 }
1126 }
1127 return ret;
1128}
1129
1130static int __dirclose(DIR_ITER *dirState) {
1131 struct _reent *r = _REENT;
1132 int ret = -1;
1133 int dev = 0;
1134
1135 if (dirState != NULL) {
1136 dev = dirState->device;
1137
1138 if (devoptab_list[dev]->dirclose_r) {
1139 ret = devoptab_list[dev]->dirclose_r(r, dirState);
1140 } else {
1141 r->_errno = ENOSYS;
1142 }
1143
1144 free(dirState);
1145 }
1146 return ret;
1147}
1148
1149DIR* opendir(const char *dirname) {
1150 DIR* dirp = malloc(sizeof (DIR));
1151 if (!dirp) {
1152 errno = ENOMEM;
1153 return NULL;
1154 }
1155
1156 dirp->dirData = __diropen(dirname);
1157 if (!dirp->dirData) {
1158 free(dirp);
1159 return NULL;
1160 }
1161
1162 dirp->position = 0; // 0th position means no file name has been returned yet
1163 dirp->fileData.d_ino = -1;
1164 dirp->fileData.d_name[0] = '\0';
1165
1166 return dirp;
1167}
1168
1169int closedir(DIR *dirp) {
1170 int res;
1171
1172 if (!dirp) {
1173 errno = EBADF;
1174 return -1;
1175 }
1176
1177 res = __dirclose(dirp->dirData);
1178 free(dirp);
1179 return res;
1180}
1181
1182struct dirent* readdir(DIR *dirp) {
1183 struct stat st;
1184 char filename[PATH_MAX];
1185 int res;
1186 int olderrno = errno;
1187
1188 if (!dirp) {
1189 errno = EBADF;
1190 return NULL;
1191 }
1192
1193 res = __dirnext(dirp->dirData, filename, &st);
1194
1195 if (res < 0) {
1196 if (errno == ENOENT) {
1197 // errno == ENONENT set by dirnext means it's end of directory
1198 // But readdir should not touch errno in case of dir end
1199 errno = olderrno;
1200 }
1201 return NULL;
1202 }
1203
1204 // We've moved forward in the directory
1205 dirp->position += 1;
1206
1207 if (strnlen(filename, PATH_MAX) >= sizeof (dirp->fileData.d_name)) {
1208 errno = EOVERFLOW;
1209 return NULL;
1210 }
1211
1212 strncpy(dirp->fileData.d_name, filename, sizeof (dirp->fileData.d_name));
1213 dirp->fileData.d_ino = st.st_ino;
1214 dirp->fileData.d_type = S_ISDIR(st.st_mode) ? DT_DIR : DT_REG;
1215 dirp->fileData.d_atime = st.st_atime;
1216 dirp->fileData.d_mtime = st.st_mtime;
1217 dirp->fileData.d_ctime = st.st_ctime;
1218 return &(dirp->fileData);
1219}
1220
1221void rewinddir(DIR *dirp) {
1222 if (!dirp) {
1223 return;
1224 }
1225
1226 __dirreset(dirp->dirData);
1227 dirp->position = 0;
1228}
1229
1230void seekdir(DIR *dirp, long int loc) {
1231 char filename[PATH_MAX];
1232
1233 if (!dirp || loc < 0) {
1234 return;
1235 }
1236
1237 if (dirp->position > loc) {
1238 // The entry we want is before the one we have,
1239 // so we have to start again from the begining
1240 __dirreset(dirp->dirData);
1241 dirp->position = 0;
1242 }
1243
1244 // Keep reading entries until we reach the one we want
1245 while ((dirp->position < loc) &&
1246 (__dirnext(dirp->dirData, filename, NULL) >= 0)) {
1247 dirp->position += 1;
1248 }
1249}
1250
1251long int telldir(DIR *dirp) {
1252 if (!dirp) {
1253 return -1;
1254 }
1255
1256 return dirp->position;
1257}
1258
1259int fcntl(int filedes, int cmd, ...) {
1260 return -1;
1261}
1262
1263int mkdir(const char *path, mode_t mode) {
1264 struct _reent *r = _REENT;
1265 int ret;
1266 int dev = FindDevice(path);
1267 ret = -1;
1268
1269 if (devoptab_list[dev]->mkdir_r) {
1270 ret = devoptab_list[dev]->mkdir_r(r, path, mode);
1271 } else {
1272 r->_errno = ENOSYS;
1273 }
1274
1275 return ret;
1276}
1277
1278int bdev_enum(int handle, const char **name) {
1279 do {
1280 ++handle;
1281 } while (handle < STD_MAX && !memcmp(devoptab_list[handle]->name, "std",3 ));
1282
1283 if (handle >= STD_MAX)
1284 return -1;
1285
1286 if (name)
1287 *name = devoptab_list[handle]->name;
1288
1289 return handle;
1290}
long long _off_t
Definition: _types.h:13
void lock(unsigned int *lock)
#define NULL
Definition: def.h:47
#define DT_DIR
Definition: dirent.h:13
#define DT_REG
Definition: dirent.h:15
u32 status
Definition: ehci_defs.h:15
#define TR
Definition: debug.h:15
@ STD_MAX
Definition: iosupport.h:18
#define isdigit(c)
Definition: ip_addr.c:116
int dir
Definition: iso9660.c:535
u32 ptr
Definition: iso9660.c:536
u32 size
Definition: iso9660.c:537
#define __lock_release_recursive(NAME)
Definition: lock.h:43
#define __lock_acquire_recursive(NAME)
Definition: lock.h:28
unsigned int __mf_uintptr_t __attribute__((__mode__(__pointer__)))
Definition: mf-runtime.h:34
int chdir(const char *path)
Definition: newlib.c:952
int mkfifo(const char *pathname, mode_t mode)
Definition: newlib.c:205
pid_t waitpid(pid_t pid, int *stat_loc, int options)
Definition: newlib.c:199
const devoptab_t * devoptab_list[STD_MAX]
Definition: newlib.c:432
void(* stdlog_hook)(const char *text, int len)=0
Definition: newlib.c:20
int kill(int pid, int sig)
Definition: newlib.c:263
int unlink(const char *name)
Definition: newlib.c:811
#define DIRECTORY_SEPARATOR_CHAR
Definition: newlib.c:859
#define MAX_HANDLES
Definition: newlib.c:344
const char DIRECTORY_SEPARATOR[]
Definition: newlib.c:860
void * getpwnam(const char *name)
Definition: newlib.c:324
char * dlerror(void)
Definition: newlib.c:154
int getpid()
Definition: newlib.c:193
int isatty(int file)
Definition: newlib.c:259
void(* stdout_hook)(const char *text, int len)=0
Definition: newlib.c:19
uid_t getuid(void)
Definition: newlib.c:291
int pclose(FILE *f)
Definition: newlib.c:164
int setgid(gid_t gid)
Definition: newlib.c:311
int dlclose(void *p)
Definition: newlib.c:150
int close(int fileDesc)
Definition: newlib.c:829
FILE * popen(const char *s1, const char *s2)
Definition: newlib.c:160
gid_t getegid(void)
Definition: newlib.c:303
void * dlsym(void *p, const char *s)
Definition: newlib.c:146
int fchmod(int fd, mode_t mode)
Definition: newlib.c:1042
long int telldir(DIR *dirp)
Definition: newlib.c:1251
int fcntl(int filedes, int cmd,...)
Definition: newlib.c:1259
int __alloc_handle(int size)
Definition: newlib.c:362
int mkdir(const char *path, mode_t mode)
Definition: newlib.c:1263
gid_t getgid(void)
Definition: newlib.c:299
void * getpwuid(uid_t uid)
Definition: newlib.c:319
int __libc_lock_acquire(int *lock)
Definition: newlib.c:93
int stat(const char *file, struct stat *st)
Definition: newlib.c:643
int ftruncate(int fileDesc, off_t len)
Definition: newlib.c:705
int __libc_lock_release(int *lock)
Definition: newlib.c:84
int execve(const char *path, char *const argv[], char *const envp[])
Definition: newlib.c:170
const char DIRECTORY_PARENT[]
Definition: newlib.c:862
void * dlopen(const char *c, int i)
Definition: newlib.c:142
const devoptab_t console_optab
Definition: newlib.c:36
int gettimeofday(struct timeval *ptimeval, void *ptimezone)
Definition: newlib.c:248
int fstat(int fileDesc, struct stat *st)
Definition: newlib.c:614
int _concatenate_path(struct _reent *r, char *path, const char *extra, int maxLength)
Definition: newlib.c:864
void setDefaultDevice(int device)
Definition: newlib.c:396
struct dirent * readdir(DIR *dirp)
Definition: newlib.c:1182
#define ROOT_UID
Definition: newlib.c:288
uid_t geteuid(void)
Definition: newlib.c:295
void abort(void)
Definition: newlib.c:136
int RemoveDevice(const char *name)
Definition: newlib.c:467
int read(int fileDesc, void *ptr, size_t len)
Definition: newlib.c:559
int AddDevice(const devoptab_t *device)
Definition: newlib.c:482
int gethostname(char *name, size_t len)
Definition: newlib.c:269
int execvp(const char *file, char *const argv[])
Definition: newlib.c:180
void * getgrnam(const char *name)
Definition: newlib.c:329
int fork()
Definition: newlib.c:186
int setuid(uid_t uid)
Definition: newlib.c:307
int write(int fileDesc, const void *ptr, size_t len)
Definition: newlib.c:584
int __libc_lock_close(int *lock)
Definition: newlib.c:75
void * getgrgid(gid_t gid)
Definition: newlib.c:334
int link(const char *existing, const char *new)
Definition: newlib.c:732
int FindDevice(const char *name)
Definition: newlib.c:443
int closedir(DIR *dirp)
Definition: newlib.c:1169
ssize_t vfs_console_write(struct _reent *r, int fd, const char *src, size_t len)
Definition: newlib.c:25
int fsync(int fileDesc)
Definition: newlib.c:678
void seekdir(DIR *dirp, long int loc)
Definition: newlib.c:1230
void _exit(int status)
Definition: newlib.c:116
int chmod(const char *path, mode_t mode)
Definition: newlib.c:1025
#define ROOT_GID
Definition: newlib.c:289
pid_t getppid(void)
Definition: newlib.c:315
int lstat(const char *path, struct stat *buf)
Definition: newlib.c:211
const char DIRECTORY_THIS[]
Definition: newlib.c:861
char * getcwd(char *buf, size_t size)
Definition: newlib.c:1006
_off_t lseek(int fileDesc, _off_t pos, int dir)
Definition: newlib.c:756
int open(const char *file, int flags, int mode)
Definition: newlib.c:522
void rewinddir(DIR *dirp)
Definition: newlib.c:1221
const devoptab_t dotab_stdnull
Definition: newlib.c:404
int getrusage(int who, struct rusage *usage)
Definition: newlib.c:242
void * sbrk(ptrdiff_t incr)
Definition: newlib.c:124
const devoptab_t * GetDeviceOpTab(const char *name)
Definition: newlib.c:506
void __malloc_unlock(struct _reent *ptr)
Definition: newlib.c:109
int rename(const char *existing, const char *newName)
Definition: newlib.c:787
__handle * __get_handle(int fd)
Definition: newlib.c:380
int execv(const char *path, char *const argv[])
Definition: newlib.c:176
DIR * opendir(const char *dirname)
Definition: newlib.c:1149
void __malloc_lock(struct _reent *ptr)
Definition: newlib.c:102
int bdev_enum(int handle, const char **name)
Definition: newlib.c:1278
int __libc_lock_init(int *lock, int recursive)
Definition: newlib.c:66
int access(const char *path, int mode)
Definition: newlib.c:217
int device
Definition: iosupport.h:29
void * dirStruct
Definition: iosupport.h:30
Definition: dirent.h:33
struct dirent fileData
Definition: dirent.h:36
DIR_ITER * dirData
Definition: dirent.h:35
long int position
Definition: dirent.h:34
int device
Definition: iosupport.h:23
void * fileStruct
Definition: iosupport.h:24
int(* gettod_r)(struct _reent *ptr, struct timeval *tp, struct timezone *tz)
Definition: iosupport.h:77
void *(* sbrk_r)(struct _reent *ptr, ptrdiff_t incr)
Definition: iosupport.h:69
int(* lock_release)(int *lock)
Definition: iosupport.h:72
void(* malloc_lock)(struct _reent *ptr)
Definition: iosupport.h:74
void(* exit)(int rc)
Definition: iosupport.h:76
int(* lock_close)(int *lock)
Definition: iosupport.h:71
void(* malloc_unlock)(struct _reent *ptr)
Definition: iosupport.h:75
int(* lock_acquire)(int *lock)
Definition: iosupport.h:73
int(* lock_init)(int *lock, int recursive)
Definition: iosupport.h:70
int(* dirclose_r)(struct _reent *r, DIR_ITER *dirState)
Definition: iosupport.h:54
int(* rename_r)(struct _reent *r, const char *oldName, const char *newName)
Definition: iosupport.h:46
int(* unlink_r)(struct _reent *r, const char *name)
Definition: iosupport.h:44
DIR_ITER *(* diropen_r)(struct _reent *r, DIR_ITER *dirState, const char *path)
Definition: iosupport.h:51
int(* statvfs_r)(struct _reent *r, const char *path, struct statvfs *buf)
Definition: iosupport.h:55
int(* dirreset_r)(struct _reent *r, DIR_ITER *dirState)
Definition: iosupport.h:52
int(* fsync_r)(struct _reent *r, int fd)
Definition: iosupport.h:57
int(* fstat_r)(struct _reent *r, int fd, struct stat *st)
Definition: iosupport.h:41
int(* fchmod_r)(struct _reent *r, int fd, mode_t mode)
Definition: iosupport.h:62
int(* close_r)(struct _reent *r, int fd)
Definition: iosupport.h:37
int(* dirnext_r)(struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *filestat)
Definition: iosupport.h:53
off_t(* seek_r)(struct _reent *r, int fd, off_t pos, int dir)
Definition: iosupport.h:40
int(* chmod_r)(struct _reent *r, const char *path, mode_t mode)
Definition: iosupport.h:61
int(* link_r)(struct _reent *r, const char *existing, const char *newLink)
Definition: iosupport.h:43
ssize_t(* write_r)(struct _reent *r, int fd, const char *ptr, size_t len)
Definition: iosupport.h:38
int(* ftruncate_r)(struct _reent *r, int fd, off_t len)
Definition: iosupport.h:56
int(* mkdir_r)(struct _reent *r, const char *path, int mode)
Definition: iosupport.h:47
int dirStateSize
Definition: iosupport.h:49
int(* open_r)(struct _reent *r, void *fileStruct, const char *path, int flags, int mode)
Definition: iosupport.h:36
int(* stat_r)(struct _reent *r, const char *file, struct stat *st)
Definition: iosupport.h:42
ssize_t(* read_r)(struct _reent *r, int fd, char *ptr, size_t len)
Definition: iosupport.h:39
const char * name
Definition: iosupport.h:34
Definition: dirent.h:24
char d_name[NAME_MAX+1]
Definition: dirent.h:27
time_t d_ctime
Definition: dirent.h:30
time_t d_mtime
Definition: dirent.h:29
ino_t d_ino
Definition: dirent.h:25
unsigned char d_type
Definition: dirent.h:26
time_t d_atime
Definition: dirent.h:28
__syscalls_t __syscalls
void putch(unsigned char c)
Definition: xenon_uart.c:5
#define pid
Definition: xenonsprs.h:6
u8 c
Definition: xenos_edid.h:7