static int do_epoll_create1(int flags) { int rval = libc.epoll_create1(flags); if( rval >= 0 ) { fdinfo_t* info = alloc_info(EPOLL); fd_save(rval, info); } return rval; }
static Retcode make_reg_prop(Environ *e, Allocator *a, Byte *propname) { Package *savepkg = e->currpkg; Cell saveinst = e->currinst; Retcode ret; Byte *prop; Int plen = 0; Int i; Allocator_block *b = NULL; uInt addr[1]; uInt size[1]; e->currpkg = e->mmu; e->currinst = (uPtr)NULL; alloc_info(a, &b, addr, size); for (i = 1; b; alloc_info(a, &b, addr, size), i++) ; prop = prop_alloc(e, i * 2 * sizeof (Int)); b = NULL; alloc_info(a, &b, addr, size); for (i = 1; b; alloc_info(a, &b, addr, size), i++) { /* first encode the single-cell virtual address */ prop_encode_int(prop + plen, &plen, addr[0]); /* next encode the single-cell block size */ prop_encode_int(prop + plen, &plen, size[0]); } ret = add_property(e->mmu->props, propname, CSTR, prop, plen); e->currpkg = savepkg; e->currinst = saveinst; return ret; }
info_s *new_info (info_s *parent, char *name, unint mode) { info_s *info; u64 ino; FN; ino = alloc_ino(parent->in_tree.t_dev); info = alloc_info(strlen(name) + 1, get_species(mode), parent->in_tree.t_dev); init_inode( &info->in_inode, ino, mode, name); add_info(ino, info); return info; }
bool yay::test() { vk::ApplicationInfo app_info = vk::ApplicationInfo() .sType(vk::StructureType::eApplicationInfo) .pApplicationName("vulkan test") .applicationVersion(1) .pEngineName("faze") .engineVersion(1) .apiVersion(VK_API_VERSION); vk::InstanceCreateInfo inst_info = vk::InstanceCreateInfo() .sType(vk::StructureType::eInstanceCreateInfo) .pApplicationInfo(&app_info); /* inst_info.enabledExtensionCount = 0; inst_info.ppEnabledExtensionNames = NULL; inst_info.enabledLayerCount = 0; inst_info.ppEnabledLayerNames = NULL; */ vk::AllocationCallbacks alloc_info(nullptr, allocs::pfnAllocation, allocs::pfnReallocation, allocs::pfnFree, allocs::pfnInternalAllocation, allocs::pfnInternalFree); FazPtr<vk::Instance> instance([=](vk::Instance ist) { ist.destroy(&alloc_info); }); vk::Result res = vk::createInstance(&inst_info, &alloc_info, instance.Get()); if (res != vk::Result::eSuccess) { // quite hot shit baby yeah! std::cout << vk::getString(res) << std::endl; return false; } return true; }
static int find_search ( void *data, u64 rec_key, void *rec, unint len) { find_search_s *s = data; inode_s *inode = rec; info_s *info; FN; if (s->ino != rec_key) { return qERR_NOT_FOUND; } /* * Found the inode, allocate a structure and fill it in */ info = alloc_info(len - sizeof(inode_s), get_species(inode->i_mode), Inode_tree.t_dev); memcpy( &info->in_inode, inode, len); s->info = info; return 0; }
int main( int argc, char *argv[]) { int c; int error; int mr_flag, alloc_flag, handle_flag, event_flag; void *hanp; size_t hlen; char *filename; dm_sessid_t sid; Progname = argv[0]; mr_flag = alloc_flag = handle_flag = event_flag = 0; while ((c = getopt(argc, argv, "maeh")) != EOF) { switch (c) { case 'm': mr_flag = 1; break; case 'a': alloc_flag = 1; break; case 'e': event_flag = 1; break; case 'h': handle_flag = 1; break; case '?': default: usage(Progname); exit(1); } } if (optind >= argc) { usage(Progname); exit(1); } filename = argv[optind]; if (filename == NULL) { usage(Progname); exit(1); } /* * Set up our link to the DMAPI, and get a handle for * the file we want to query */ error = setup_dmapi(&sid); if (error) exit(1); if (dm_path_to_handle(filename, &hanp, &hlen) == -1) { printf("Can't get handle for path %s", filename); error = 1; goto out; } printf("File %s:\n", filename); if (mr_flag) { error = mr_info(sid, hanp, hlen); if (error) { error = 1; goto out; } } if (alloc_flag) { error = alloc_info(sid, hanp, hlen); if (error) { error = 1; goto out; } } if (event_flag) { error = event_info(sid, hanp, hlen); if (error) { error = 1; goto out; } } if (handle_flag) { error = handle_info(sid, hanp, hlen); if (error) { error = 1; goto out; } } out: if (dm_destroy_session(sid)) { errno_msg("Can't shut down session"); error = 1; } return(error); }
static int impl_dummy_server(void) { int dummy_server = -1; /* Create our dummy sock. */ struct sockaddr_un dummy_addr; char *socket_path = tempnam("/tmp", ".huptime"); memset(&dummy_addr, 0, sizeof(struct sockaddr_un)); dummy_addr.sun_family = AF_UNIX; strncpy(dummy_addr.sun_path, socket_path, sizeof(dummy_addr.sun_path)-1); /* Create a dummy server. */ dummy_server = socket(AF_UNIX, SOCK_STREAM, 0); if( dummy_server < 0 ) { fprintf(stderr, "Unable to create unix socket?"); return -1; } if( fcntl(dummy_server, F_SETFD, FD_CLOEXEC) < 0 ) { close(dummy_server); fprintf(stderr, "Unable to set cloexec?"); return -1; } if( libc.bind( dummy_server, (struct sockaddr*)&dummy_addr, sizeof(struct sockaddr_un)) < 0 ) { close(dummy_server); fprintf(stderr, "Unable to bind unix socket?"); return -1; } if( libc.listen(dummy_server, 1) < 0 ) { close(dummy_server); fprintf(stderr, "Unable to listen on unix socket?"); return -1; } /* Connect a dummy client. */ int dummy_client = socket(AF_UNIX, SOCK_STREAM, 0); if( dummy_client < 0 ) { close(dummy_server); fprintf(stderr, "Unable to create unix socket?"); return -1; } if( fcntl(dummy_client, F_SETFD, FD_CLOEXEC) < 0 ) { close(dummy_server); close(dummy_client); fprintf(stderr, "Unable to set cloexec?"); return -1; } if( connect( dummy_client, (struct sockaddr*)&dummy_addr, sizeof(struct sockaddr_un)) < 0 ) { close(dummy_server); close(dummy_client); fprintf(stderr, "Unable to connect dummy client?"); return -1; } /* Put the client into an error state. */ int dummy_fd = libc.accept(dummy_server, NULL, 0); if( dummy_fd < 0 ) { fprintf(stderr, "Unable to accept internal client?"); close(dummy_server); close(dummy_client); return -1; } close(dummy_fd); /* Save the dummy info. */ fdinfo_t* dummy_info = alloc_info(DUMMY); if( dummy_info == NULL ) { fprintf(stderr, "Unable to allocate dummy info?"); return -1; } dummy_info->dummy.client = dummy_client; fd_save(dummy_server, dummy_info); inc_ref(dummy_info); fd_save(dummy_client, dummy_info); /* Ensure that it's unlinked. */ unlink(socket_path); free(socket_path); return dummy_server; }
void impl_init(void) { const char* mode_env = getenv("HUPTIME_MODE"); const char* multi_env = getenv("HUPTIME_MULTI"); const char* revive_env = getenv("HUPTIME_REVIVE"); const char* debug_env = getenv("HUPTIME_DEBUG"); const char* pipe_env = getenv("HUPTIME_PIPE"); const char* wait_env = getenv("HUPTIME_WAIT"); if( debug_env != NULL && strlen(debug_env) > 0 ) { debug_enabled = !strcasecmp(debug_env, "true") ? TRUE: FALSE; } DEBUG("Initializing..."); /* Initialize our lock. */ impl_init_lock(); /* Save this pid as our master pid. * This is done to handle processes that use * process pools. We remember the master pid and * will do the full fork()/exec() only when we are * the master. Otherwise, we will simply shutdown * gracefully, and all the master to restart. */ master_pid = getpid(); /* Grab our exit strategy. */ if( mode_env != NULL && strlen(mode_env) > 0 ) { if( !strcasecmp(mode_env, "fork") ) { exit_strategy = FORK; DEBUG("Exit strategy is fork."); } else if( !strcasecmp(mode_env, "exec") ) { exit_strategy = EXEC; DEBUG("Exit strategy is exec."); } else { fprintf(stderr, "Unknown exit strategy."); libc.exit(1); } } /* Check if we have something to unlink. */ to_unlink = getenv("HUPTIME_UNLINK"); if( to_unlink != NULL && strlen(to_unlink) > 0 ) { DEBUG("Unlink is '%s'.", to_unlink); } /* Clear up any outstanding child processes. * Because we may have exited before the process * could do appropriate waitpid()'s, we try to * clean up children here. Note that we may have * some zombies that hang around during the life * of the program, but at every restart they will * be cleaned up (so at least they won't grow * without bound). */ int status = 0; while( waitpid((pid_t)-1, &status, WNOHANG) > 0 ); /* Check if we're in multi mode. */ if( multi_env != NULL && strlen(multi_env) > 0 ) { multi_mode = !strcasecmp(multi_env, "true") ? TRUE: FALSE; } #ifndef SO_REUSEPORT if( multi_mode == TRUE ) { fprintf(stderr, "WARNING: Multi mode not supported.\n"); fprintf(stderr, "(Requires at least Linux 3.9 and recent headers).\n"); } #endif /* Check if we're in revive mode. */ if( revive_env != NULL && strlen(revive_env) > 0 ) { revive_mode = !strcasecmp(revive_env, "true") ? TRUE : FALSE; } /* Check if we are in wait mode. */ if( wait_env != NULL && strlen(wait_env) > 0 ) { wait_mode = !strcasecmp(wait_env, "true") ? TRUE : FALSE; } /* Check if we're a respawn. */ if( pipe_env != NULL && strlen(pipe_env) > 0 ) { int fd = -1; fdinfo_t *info = NULL; int pipefd = strtol(pipe_env, NULL, 10); DEBUG("Loading all file descriptors."); /* Decode all passed information. */ while( !info_decode(pipefd, &fd, &info) ) { fd_save(fd, info); DEBUG("Decoded fd %d (type %d).", fd, info->type); info = NULL; } if( info != NULL ) { dec_ref(info); } /* Finished with the pipe. */ libc.close(pipefd); unsetenv("HUPTIME_PIPE"); DEBUG("Finished decoding."); /* Close all non-encoded descriptors. */ for( fd = 0; fd < fd_max(); fd += 1 ) { info = fd_lookup(fd); if( info == NULL ) { DEBUG("Closing fd %d.", fd); libc.close(fd); } } /* Restore all given file descriptors. */ for( fd = 0; fd < fd_limit(); fd += 1 ) { info = fd_lookup(fd); if( info != NULL && info->type == SAVED ) { fdinfo_t *orig_info = fd_lookup(info->saved.fd); if( orig_info != NULL ) { /* Uh-oh, conflict. Move the original (best effort). */ do_dup(info->saved.fd); do_close(info->saved.fd); } /* Return the offset (ignore failure). */ if( info->saved.offset != (off_t)-1 ) { lseek(fd, info->saved.offset, SEEK_SET); } /* Move the SAVED fd back. */ libc.dup2(fd, info->saved.fd); DEBUG("Restored fd %d.", info->saved.fd); } } } else { DEBUG("Saving all initial file descriptors."); /* Save all of our initial files. These are used * for re-execing the process. These are persisted * effectively forever, and on restarts we close * everything that is not a BOUND socket or a SAVED * file descriptor. */ for( int fd = 0; fd < fd_max(); fd += 1 ) { fdinfo_t *info = fd_lookup(fd); if( info != NULL ) { /* Encoded earlier. */ continue; } /* Make a new SAVED FD. */ int newfd = libc.dup(fd); if( newfd >= 0 ) { fdinfo_t *saved_info = alloc_info(SAVED); if( saved_info != NULL ) { saved_info->saved.fd = fd; saved_info->saved.offset = lseek(fd, 0, SEEK_CUR); fd_save(newfd, saved_info); DEBUG("Saved fd %d (offset %lld).", fd, (long long int)saved_info->saved.offset); } } } } /* Save the environment. * * NOTE: We reserve extra space in the environment * for our special start-up parameters, which will be added * in impl_exec() below. (The encoded BOUND/SAVED sockets). * * We also filter out the special variables above that were * used to pass in information about sockets that were bound. */ free(environ_copy); environ_copy = (char**)read_nul_sep("/proc/self/environ"); DEBUG("Saved environment."); /* Save the arguments. */ free(args_copy); args_copy = (char**)read_nul_sep("/proc/self/cmdline"); DEBUG("Saved args."); for( int i = 0; args_copy[i] != NULL; i += 1 ) { DEBUG(" arg%d=%s", i, args_copy[i]); } /* Save the cwd & exe. */ free(cwd_copy); cwd_copy = (char*)read_link("/proc/self/cwd"); DEBUG("Saved cwd."); free(exe_copy); exe_copy = (char*)read_link("/proc/self/exe"); DEBUG("Saved exe."); /* Install our signal handlers. */ impl_install_sighandlers(); /* Initialize our thread. */ impl_init_thread(); /* Unblock our signals. * Note that we have specifically masked the * signals prior to the exec() below, to cover * the race between program start and having * installed the appropriate handlers. */ sigset_t set; sigemptyset(&set); sigaddset(&set, SIGHUP); sigprocmask(SIG_UNBLOCK, &set, NULL); /* Done. */ DEBUG("Initialization complete."); }
static int do_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) { int rval = -1; fdinfo_t *info = NULL; if( sockfd < 0 ) { errno = EINVAL; return -1; } DEBUG("do_accept4(%d, ...) ...", sockfd); L(); info = fd_lookup(sockfd); if( info == NULL || (info->type != BOUND && info->type != DUMMY) ) { U(); /* Should return an error. */ rval = libc.accept4(sockfd, addr, addrlen, flags); DEBUG("do_accept4(%d, ...) => %d (no info)", sockfd, rval); return rval; } /* Check that they've called listen. */ if( info->type == BOUND && !info->bound.stub_listened ) { U(); DEBUG("do_accept4(%d, ...) => -1 (not listened)", sockfd); errno = EINVAL; return -1; } /* Check if this is a dummy. * There's no way that they should be calling accept(). * The dummy FD will never trigger a poll, select, epoll, * etc. So we just act as a socket with no clients does -- * either return immediately or block forever. NOTE: We * still return in case of EINTR or other suitable errors. */ if( info->type == DUMMY && info->dummy.client >= 0 ) { rval = info->dummy.client; info->dummy.client = -1; U(); DEBUG("do_accept4(%d, ...) => %d (dummy client)", sockfd, rval); return rval; } U(); if( !(flags & SOCK_NONBLOCK) ) { /* Wait for activity on the socket. */ struct pollfd poll_info; poll_info.fd = sockfd; poll_info.events = POLLIN; poll_info.revents = 0; if( poll(&poll_info, 1, -1) < 0 ) { return -1; } } L(); /* Check our status. */ if( is_exiting == TRUE ) { /* We've transitioned from not exiting * to exiting in this period. This will * circle around a return a dummy descriptor. */ U(); DEBUG("do_accept4(%d, ...) => -1 (interrupted)", sockfd); errno = flags & SOCK_NONBLOCK ? EAGAIN : EINTR; return -1; } /* Do the accept for real. */ fdinfo_t *new_info = alloc_info(TRACKED); if( new_info == NULL ) { U(); DEBUG("do_accept4(%d, ...) => -1 (alloc error?)", sockfd); return -1; } inc_ref(info); new_info->tracked.bound = info; rval = libc.accept4(sockfd, addr, addrlen, flags); if( rval >= 0 ) { /* Save the reference to the socket. */ fd_save(rval, new_info); } else { /* An error occured, nothing to track. */ dec_ref(new_info); } U(); DEBUG("do_accept4(%d, ...) => %d (tracked %d) %s", sockfd, rval, total_tracked, rval == -1 ? strerror(errno) : ""); return rval; }
static int do_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { fdinfo_t *info = NULL; int rval = -1; if( sockfd < 0 ) { errno = EINVAL; return -1; } /* At this point, we can reasonably assume * the program has started up and has installed * whatever signal handlers it wants. We check * that our own signal handler is installed. * If the user doesn't want us to override the * built-in signal handlers, they shouldn't use * huptime. */ impl_install_sighandlers(); DEBUG("do_bind(%d, ...) ...", sockfd); L(); /* See if this socket already exists. */ for( int fd = 0; fd < fd_limit(); fd += 1 ) { fdinfo_t *info = fd_lookup(fd); if( info != NULL && info->type == BOUND && info->bound.addrlen == addrlen && !memcmp(addr, (void*)info->bound.addr, addrlen) ) { DEBUG("Found ghost %d, cloning...", fd); /* Give back a duplicate of this one. */ int rval = do_dup2(fd, sockfd); if( rval < 0 ) { /* Dup2 failed? */ DEBUG("Failed."); continue; } if( info->bound.is_ghost ) { /* Close the original (not needed). */ info->bound.is_ghost = 0; do_close(fd); } /* Success. */ U(); DEBUG("do_bind(%d, ...) => 0 (ghosted)", sockfd); return 0; } } #ifdef SO_REUSEPORT /* Multi mode? Set socket options. */ if( multi_mode == TRUE ) { int optval = 1; if( setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)) < 0 ) { U(); DEBUG("do_bind(%d, ...) => -1 (no multi?)", sockfd); return -1; } DEBUG("Multi mode enabled."); } #endif /* Try a real bind. */ info = alloc_info(BOUND); if( info == NULL ) { U(); DEBUG("do_bind(%d, ...) => -1 (alloc error?)", sockfd); return -1; } rval = libc.bind(sockfd, addr, addrlen); if( rval < 0 ) { dec_ref(info); U(); DEBUG("do_bind(%d, ...) => %d (error)", sockfd, rval); return rval; } /* Ensure that this socket is non-blocking, * this is because we override the behavior * for accept() and we require non-blocking * behavior. We deal with the consequences. */ rval = fcntl(sockfd, F_SETFL, O_NONBLOCK); if( rval < 0 ) { dec_ref(info); U(); DEBUG("do_bind(%d, ...) => %d (fcntl error)", sockfd, rval); return -1; } /* Save a refresh bound socket info. */ info->bound.stub_listened = 0; info->bound.real_listened = 0; info->bound.addr = (struct sockaddr*)malloc(addrlen); info->bound.addrlen = addrlen; memcpy((void*)info->bound.addr, (void*)addr, addrlen); fd_save(sockfd, info); /* Success. */ U(); DEBUG("do_bind(%d, ...) => %d", sockfd, rval); return rval; }
void MemoryHeap::mark_allocated(void* addr, size_t size, bool largeAlloc) { lassert(size > 0); mPages.insert(std::make_pair(addr, alloc_info(size, largeAlloc))); mHeapSize += size; }