1/** \file 2 * \brief inheritance of file descriptors 3 */ 4 5/* 6 * Copyright (c) 2010, 2012, ETH Zurich. 7 * All rights reserved. 8 * 9 * This file is distributed under the terms in the attached LICENSE file. 10 * If you do not find this file, copies can be found by writing to: 11 * ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich, 12 * Attn: Systems Group. 13 */ 14 15#include <stdio.h> 16#include <stdlib.h> 17 18#include <barrelfish/barrelfish.h> 19#include <barrelfish_kpi/init.h> 20 21#include "testdesc.h" 22 23 24static void print_file_fd(void *handle) 25{ 26 vfs_handle_t *vh = *(vfs_handle_t**)handle; 27 28 printf("reading from: %p\n", handle); 29 printf("FILE\n\thandle: %p\n", vh); 30} 31 32static void print_unixsock_fd(void *handle) 33{ 34 struct _unix_socket *ush = (struct _unix_socket *)handle; 35 36 printf("reading from: %p\n", handle); 37 printf("UNIX socket\n\ttype: %x protocol: %x\n\tpassive: %d nonblkng: %d\n", 38 ush->type, ush->protocol, ush->passive, ush->nonblocking); 39} 40 41static errval_t get_inherited_fds(void) 42{ 43 errval_t err; 44 45 /* Map the FD buffer into our address space. 46 * It stays there since the FD data structures will remain in there and be 47 * referenced from the FD table. 48 */ 49 struct capref frame = { 50 .cnode = cnode_task, 51 .slot = TASKCN_SLOT_FDSPAGE, 52 }; 53 54 void *fdspg; 55 err = vspace_map_one_frame(&fdspg, FDS_SIZE, frame, NULL, NULL); 56 if (err_is_fail(err)) { 57 return err_push(err, SPAWN_ERR_MAP_FDSPG_TO_SELF); 58 } 59 60 /* Set up to read the table */ 61 char *p = fdspg; 62 printf("fds at: %p\n", p); 63 64 int num_fds = *((int*)p); 65 printf("num fds: %d\n", num_fds); 66 67 struct fd_store *fd; 68 p += sizeof(int); 69 fd = (struct fd_store*)p; 70 p += (sizeof(struct fd_store)*num_fds); 71 72 /* Process all the FDs passed in the buffer */ 73 int i; 74 for (i = 0; i < num_fds; i++, fd++) { 75 76 /* add each to our fd table - replacing any fds already there */ 77 struct fdtab_entry fde; 78 fde.type = fd->type; 79 fde.handle = fd->handle; 80 81 if (fdtab_get(fd->num)->type != FDTAB_TYPE_AVAILABLE) { 82 fdtab_free(fd->num); 83 } 84 fdtab_alloc_from(&fde, fd->num); 85 86 /* print out some info about the FD */ 87 88 char *s = ""; 89 switch (fd->type) { 90 case FDTAB_TYPE_AVAILABLE: 91 s = "available"; 92 break; 93 case FDTAB_TYPE_FILE: 94 s = "file"; 95 break; 96 case FDTAB_TYPE_UNIX_SOCKET: 97 s = "unix socket"; 98 break; 99 case FDTAB_TYPE_STDIN: 100 s = "stdin"; 101 break; 102 case FDTAB_TYPE_STDOUT: 103 s = "stdout"; 104 break; 105 case FDTAB_TYPE_STDERR: 106 s = "stderr"; 107 break; 108 case FDTAB_TYPE_LWIP_SOCKET: 109 s = "lwip socket"; 110 break; 111 case FDTAB_TYPE_EPOLL_INSTANCE: 112 s = "epoll instance"; 113 break; 114 case FDTAB_TYPE_PTM: 115 s = "pseudo-terminal master"; 116 break; 117 case FDTAB_TYPE_PTS: 118 s = "pseudo-terminal slave"; 119 break; 120 } 121 printf("fd_store %d: num: %d, type: %d:%s handle: %p\n", 122 i, fd->num, fd->type, s, fd->handle); 123 124 switch (fd->type) { 125 case FDTAB_TYPE_FILE: 126 print_file_fd((void*)(p + (lpaddr_t)fd->handle)); 127 break; 128 case FDTAB_TYPE_UNIX_SOCKET: 129 print_unixsock_fd((void*)(p + (lpaddr_t)fd->handle)); 130 break; 131 default: 132 printf("[no handle data]\n"); 133 break; 134 } 135 136 } 137 138 return SYS_ERR_OK; 139 140} 141 142int main(int argc, char *argv[]) 143{ 144 errval_t err; 145 146 printf("Child. will print out file descriptors\n"); 147 148 /* Inherit all the FDs sent over */ 149 err = get_inherited_fds(); 150 if (err_is_fail(err)) { 151 DEBUG_ERR(err, "could not get inherited FDs\n"); 152 return EXIT_FAILURE; 153 } 154 155 /* print out all of our FDs */ 156 int i; 157 struct fdtab_entry *fde; 158 for (i = MIN_FD; i < MAX_FD; i++) { 159 fde = fdtab_get(i); 160 if (fde->type != FDTAB_TYPE_AVAILABLE) { 161 printf("fd[%d]: type: %d, handle: %p\n", i, fde->type, fde->handle); 162 } 163 } 164 165 return EXIT_SUCCESS; 166} 167