int pipe_exec_fg(char const **argv, int in, int out) { int pid; pid = fork(); if (pid < 0) { ropen(0, fd_rp(in), STAT_READER); ropen(1, fd_rp(out), STAT_WRITER); if (execv(argv[0], argv)) { if (errno == ENOENT) { fprintf(stderr, "%s: %s: command not found\n", getname_s(), argv[0]); } else { perror(argv[0]); } abort(); } } close(in); close(out); mwait(PORT_CHILD, pid); return 0; }
DIR *opendir(const char *dirname) { DIR *dirp; char *list; dirp = malloc(sizeof(DIR)); if (!dirp) return NULL; dirp->fd = open(dirname, STAT_READER); if (dirp->fd < 0) { free(dirp); return NULL; } if (!rp_type(fd_rp(dirp->fd), "dir")) { errno = ENOTDIR; close(dirp->fd); free(dirp); return NULL; } list = rp_list(fd_rp(dirp->fd)); dirp->entryv = strparse(list, "\t"); if (!dirp->entryv) { free(dirp); return NULL; } dirp->dirpos = 0; return dirp; }
int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) { if (!dirp) { return -1; } if (dirp->fd < 0) { errno = EBADF; return -1; } if (!dirp->entryv[dirp->dirpos]) { return -1; } strlcpy(entry->d_name, dirp->entryv[dirp->dirpos], NAME_MAX); entry->d_ino = rp_find(fd_rp(dirp->fd), dirp->entryv[dirp->dirpos]); dirp->dirpos++; if (result) { *result = entry; } return 0; }
DIR *opendir(const char *dirname) { DIR *dirp; char *list; dirp = malloc(sizeof(DIR)); if (!dirp) return NULL; dirp->fd = open(dirname, ACCS_READ); if (dirp->fd < 0) { free(dirp); return NULL; } list = rp_list(fd_rp(dirp->fd)); dirp->entryv = strparse(list, "\t"); if (!dirp->entryv) { free(dirp); return NULL; } dirp->dirpos = 0; return dirp; }
void *load_exec(const char *name) { int fd; uint64_t size; char *path; void *image; /* attempt to find requested file */ if (name[0] == '/' || name[0] == '@') { path = strdup(name); } else { path = strvcat(getenv("PATH"), "/", name, NULL); } fd = ropen(-1, fs_find(path), STAT_READER); if (fd < 0 || !rp_type(fd_rp(fd), "file")) { /* file not found */ return NULL; } else { /* read whole file into buffer */ size = rp_size(fd_rp(fd)); if (!size) { return NULL; } image = aalloc(size, PAGESZ); if (!image) { return NULL; } if (rp_read(fd_rp(fd), image, size, 0) != size) { free(image); close(fd); return NULL; } close(fd); return image; } }
int execiv(uint8_t *image, size_t size, char const **argv) { struct dl_list *list; char *argv_pack; if (!image) { errno = ENOENT; return -1; } /* build list for linker */ list = malloc(sizeof(struct dl_list)); list[0].type = DL_EXEC; list[0].base = image; list[0].size = size; list[0].name[0] = '\0'; /* save standard streams and filesystem root */ fdsave(0, fd_rp(0)); fdsave(1, fd_rp(1)); fdsave(2, fd_rp(2)); fdsave(3, fs_root); /* save argument list */ if (argv) { argv_pack = packarg(argv); __pack_add(PACK_KEY_ARG, argv_pack, msize(argv_pack)); free(argv_pack); } /* save environment variables */ __saveenv(); /* persist saved stuff */ __pack_save(); if (dl_exec(list, 1)) { errno = ENOEXEC; return -1; } return 0; }
int close(int fd) { int mode = fd_mode(fd); rp_t rp = fd_rp(fd); if (!rp) { // is not valid file descriptor return -1; } if (rp_clrstat(rp, mode)) { // could not close connection return -1; } // clear file descriptor entry return fd_set(fd, rp, 0); }
int fflush(FILE *stream) { size_t size; if (!stream) { return -1; } mutex_spin(&stream->mutex); if (stream->buffer && stream->buffpos) { size = rp_write(fd_rp(stream->fd), stream->buffer, stream->buffpos, stream->position); stream->position += size; stream->buffpos -= size; } mutex_free(&stream->mutex); return 0; }
int close(int fd) { rp_t rp = fd_rp(fd); if (!rp) { // is not valid file descriptor return -1; } if (fd_mode(fd) & ACCS_EVENT) { // stop listening to events free(rcall(rp, fd_getkey(fd, AC_EVENT), "un-listen")); } if (fd_mode(fd) & ACCS_WRITE) { // finish writing free(rcall(rp, fd_getkey(fd, AC_WRITE), "finish")); } // clear file descriptor entry return fd_set(fd, rp, 0); }
struct dirent *readdir(DIR *dirp) { static struct dirent dirent; if (!dirp) { return NULL; } if (dirp->fd < 0) { errno = EBADF; return NULL; } if (!dirp->entryv[dirp->dirpos]) { return NULL; } strlcpy(dirent.d_name, dirp->entryv[dirp->dirpos], NAME_MAX); dirent.d_ino = rp_find(fd_rp(dirp->fd), dirp->entryv[dirp->dirpos]); dirp->dirpos++; return &dirent; }
FILE *fdopen(int fd, const char *mode) { FILE *stream; int status; if (fd < 0) { return NULL; } // check mode if (mode[0] != 'a' && mode[0] != 'w' && mode[0] != 'r') { errno = EINVAL; return NULL; } // check if the object is not a file if (!rp_type(fd_rp(fd), "file")) { errno = EISDIR; return NULL; } status = 0; // check read permissions if (mode[0] == 'r' || mode[1] == '+') { status |= STAT_READER; } // check write permissions if (mode[0] == 'w' || mode[0] == 'a' || mode[1] == '+') { status |= STAT_WRITER; } // open file for real fd = ropen(fd, fd_rp(fd), status); if (fd < 0) { return NULL; } // reset (erase) the file contents if (mode[0] == 'w') { rp_reset(fd_rp(fd)); } stream = calloc(sizeof(FILE), 1); if (!stream) { errno = ENOMEM; return NULL; } stream->fd = fd; stream->mutex = false; stream->position = 0; stream->size = rp_size(fd_rp(fd)); stream->buffer = NULL; stream->buffsize = 0; stream->buffpos = 0; stream->revbuf = EOF; stream->flags = FILE_NBF | FILE_READ; if (mode[0] == 'w' || mode[0] == 'a' || mode[1] == '+') { stream->flags |= FILE_WRITE; } // position the stream properly if (mode[0] == 'a' && mode[1] != '+') { fseek(stream, 0, SEEK_END); } else { fseek(stream, 0, SEEK_SET); } return stream; }
int fevent(int fd, const char *value) { return event(fd_rp(fd), value); }