// dead-reckoning support bool AP_AHRS_NavEKF::get_position(struct Location &loc) const { Vector3f ned_pos; switch (active_EKF_type()) { case EKF_TYPE1: if (EKF1.getLLH(loc) && EKF1.getPosNED(ned_pos)) { // fixup altitude using relative position from AHRS home, not // EKF origin loc.alt = get_home().alt - ned_pos.z*100; return true; } break; case EKF_TYPE2: if (EKF2.getLLH(loc) && EKF2.getPosNED(ned_pos)) { // fixup altitude using relative position from AHRS home, not // EKF origin loc.alt = get_home().alt - ned_pos.z*100; return true; } break; default: break; } return AP_AHRS_DCM::get_position(loc); }
static void stats_print_diff(struct stats_file *file) { struct stats_record *begin, *end; begin = get_begin(file); begin = get_next(file, begin); end = get_end(file); printf("\n(begin + 1)\n"); printf("\t[%04d] ", get_index(file, begin)); stats_print_record(begin); printf("end\n"); printf("\t[%04d] ", get_index(file, end)); stats_print_record(end); if (file->home_first && get_home(file)) { printf("\nhome\n"); stats_print_rec_diff(file->home_first, get_home(file)); } if (file->roaming_first && get_roaming(file)) { printf("\roaming\n"); stats_print_rec_diff(file->roaming_first, get_roaming(file)); } }
// return a relative ground position in meters/second, North/East/Down // order. Must only be called if have_inertial_nav() is true bool AP_AHRS_NavEKF::get_relative_position_NED(Vector3f &vec) const { switch (active_EKF_type()) { case EKF_TYPE_NONE: return false; #if AP_AHRS_WITH_EKF1 case EKF_TYPE1: return EKF1.getPosNED(vec); #endif case EKF_TYPE2: default: return EKF2.getPosNED(-1,vec); #if CONFIG_HAL_BOARD == HAL_BOARD_SITL case EKF_TYPE_SITL: { Location loc; get_position(loc); Vector2f diff2d = location_diff(get_home(), loc); const struct SITL::sitl_fdm &fdm = _sitl->state; vec = Vector3f(diff2d.x, diff2d.y, -(fdm.altitude - get_home().alt*0.01f)); return true; } #endif } }
// return a relative ground position to the origin in meters // North/East/Down order. bool AP_AHRS_NavEKF::get_relative_position_NED_origin(Vector3f &vec) const { switch (active_EKF_type()) { case EKF_TYPE_NONE: return false; case EKF_TYPE2: default: { Vector2f posNE; float posD; if (EKF2.getPosNE(-1,posNE) && EKF2.getPosD(-1,posD)) { // position is valid vec.x = posNE.x; vec.y = posNE.y; vec.z = posD; return true; } return false; } case EKF_TYPE3: { Vector2f posNE; float posD; if (EKF3.getPosNE(-1,posNE) && EKF3.getPosD(-1,posD)) { // position is valid vec.x = posNE.x; vec.y = posNE.y; vec.z = posD; return true; } return false; } #if CONFIG_HAL_BOARD == HAL_BOARD_SITL case EKF_TYPE_SITL: { if (!_sitl) { return false; } Location loc; get_position(loc); const Vector2f diff2d = location_diff(get_home(), loc); const struct SITL::sitl_fdm &fdm = _sitl->state; vec = Vector3f(diff2d.x, diff2d.y, -(fdm.altitude - get_home().alt*0.01f)); return true; } #endif } }
std::string expand_path_home(const std::string &str) { const char *home = get_home(); if (home && str.size() > 0 && str[0] == '~') return home + str.substr(1); return str; }
int asill_load_pars(struct asill_s *A) { char fname[MAX_PATH]; FILE *f; snprintf(fname, MAX_PATH, "%s/.ASILL_%d_%d", get_home(), A->model, A->n); f = fopen(fname, "r"); if (f) { char b[200]; while(!feof(f)) { if (fgets(b, 200, f)) { int p = atoi(b); const char *vs = get_p(b); if (vs) { int v = atoi(vs); if (p >= 11 && p <= 21) { asill_set_int_par(A, p - 11, v); if (p == 16 || p == 17) sleep(1); /* without this column denoise is killed if row and bias cor are saved off */ } else { switch(p) { case 2: A->width = v; break; case 3: A->height = v; break; case 4: A->start_x = v; break; case 5: A->start_y = v; break; case 6: A->bin = v; break; case 7: A->fmt = v; break; case 8: A->pclk = v; break; case 9: A->exposure_us = v; break; } } } } } fclose(f); setup_frame(A); } else return -1; return 0; }
int asill_save_pars(struct asill_s *A) { char fname[MAX_PATH]; snprintf(fname, MAX_PATH, "%s/.ASILL_%d_%d", get_home(), A->model, A->n); return save_hdr(A, fname, time(NULL), 0); }
// get latest height above ground level estimate in metres and a validity flag bool AP_AHRS_NavEKF::get_hagl(float &height) const { switch (active_EKF_type()) { case EKF_TYPE_NONE: return false; case EKF_TYPE2: default: return EKF2.getHAGL(height); case EKF_TYPE3: return EKF3.getHAGL(height); #if CONFIG_HAL_BOARD == HAL_BOARD_SITL case EKF_TYPE_SITL: { if (!_sitl) { return false; } const struct SITL::sitl_fdm &fdm = _sitl->state; height = fdm.altitude - get_home().alt*0.01f; return true; } #endif } }
char * get_config_file_path (void) { char *upath = NULL, *rpath = NULL; /* determine which config file to open, default or custom */ if (conf.iconfigfile != NULL) { rpath = realpath (conf.iconfigfile, NULL); if (rpath == NULL) FATAL ("Unable to open the specified config file. %s", strerror (errno)); return rpath; } /* otherwise, fallback to global config file, or * attempt to use the user's config file */ if (conf.load_global_config) { upath = get_global_config (); rpath = realpath (upath, NULL); if (upath) { free (upath); } } if (rpath == NULL) { upath = get_home (); rpath = realpath (upath, NULL); if (upath) { free (upath); } } return rpath; }
char* xdg_get_path(const char *xdg_env, const char *default_path) { assert(xdg_env && default_path && default_path[0] != '/'); if (!xdg_env || !default_path || default_path[0] == '/') return NULL; const char *xdg_dir; if ((xdg_dir = getenv(xdg_env)) && xdg_dir[0] == '/') return strip_slash(ccopy(xdg_dir)); char *home; if (!(home = get_home())) return NULL; /** fatal! */ const size_t len = snprintf(NULL, 0, "%s/%s", home, default_path) + 1; char *path; if (!(path = calloc(1, len))) { free(home); return NULL; /** fatal! */ } snprintf(path, len, "%s/%s", home, default_path); free(home); return path; }
int main (int argc, char *argv[]) { GtkWidget *window; /* Init GTK stuffs */ gtk_set_locale(); gtk_init(&argc, &argv); /* Get command arguments */ if ( argc > 1 ) usage(); /* Add pixmap search path */ { char *home = get_home(); char path[strlen(home)+10]; snprintf(path, sizeof(path), "%s/icons", home); add_pixmap_directory(path); } add_pixmap_directory ("."); /* Start Report Config gui */ window = report_config_gui(NULL); gtk_signal_connect_object(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(gtk_main_quit), (gpointer) NULL); /* Setup control command handling */ command_id = gdk_input_add(fileno(stdin), GDK_INPUT_READ, (GdkInputFunction) command_handler, window); gtk_main(); return 0; }
// write a relative ground position in meters, Down // return true if the estimate is valid bool AP_AHRS_NavEKF::get_relative_position_D(float &posD) const { switch (active_EKF_type()) { case EKF_TYPE_NONE: return false; #if AP_AHRS_WITH_EKF1 case EKF_TYPE1: { bool position_is_valid = EKF1.getPosD(posD); return position_is_valid; } #endif case EKF_TYPE2: default: { bool position_is_valid = EKF2.getPosD(-1,posD); return position_is_valid; } #if CONFIG_HAL_BOARD == HAL_BOARD_SITL case EKF_TYPE_SITL: { const struct SITL::sitl_fdm &fdm = _sitl->state; posD = -(fdm.altitude - get_home().alt*0.01f); return true; } #endif } }
// passes a reference to the location of the inertial navigation origin // in WGS-84 coordinates // returns a boolean true when the inertial navigation origin has been set bool AP_AHRS_NavEKF::get_origin(Location &ret) const { switch (ekf_type()) { case EKF_TYPE_NONE: return false; #if AP_AHRS_WITH_EKF1 case EKF_TYPE1: if (!EKF1.getOriginLLH(ret)) { return false; } return true; #endif case EKF_TYPE2: default: if (!EKF2.getOriginLLH(ret)) { return false; } return true; #if CONFIG_HAL_BOARD == HAL_BOARD_SITL case EKF_TYPE_SITL: ret = get_home(); return ret.lat != 0 || ret.lng != 0; #endif } }
// write a relative ground position estimate in meters, North/East order // return true if estimate is valid bool AP_AHRS_NavEKF::get_relative_position_NE(Vector2f &posNE) const { switch (active_EKF_type()) { case EKF_TYPE_NONE: return false; #if AP_AHRS_WITH_EKF1 case EKF_TYPE1: { bool position_is_valid = EKF1.getPosNE(posNE); return position_is_valid; } #endif case EKF_TYPE2: default: { bool position_is_valid = EKF2.getPosNE(-1,posNE); return position_is_valid; } #if CONFIG_HAL_BOARD == HAL_BOARD_SITL case EKF_TYPE_SITL: { Location loc; get_position(loc); posNE = location_diff(get_home(), loc); return true; } #endif } }
static void stats_hdr_info(struct stats_file *file) { struct stats_file_header *hdr; struct stats_record *begin, *end, *home, *roaming; unsigned int home_idx, roaming_idx; hdr = get_hdr(file); begin = get_begin(file); end = get_end(file); home = get_home(file); if (!home) home_idx = UINT_MAX; else home_idx = get_index(file, home); roaming = get_roaming(file); if (!roaming) roaming_idx = UINT_MAX; else roaming_idx = get_index(file, roaming); printf("Data Structure Sizes\n"); printf(" sizeof header %zd/0x%02zx\n", sizeof(struct stats_file_header), sizeof(struct stats_file_header)); printf(" sizeof entry %zd/0%02zx\n\n", sizeof(struct stats_record), sizeof(struct stats_record)); printf("File\n"); printf(" addr %p\n", file->addr); printf(" len %zd\n", file->len); printf(" max nr entries %d\n", file->max_nr); printf(" nr entries %d\n\n", file->nr); printf("Header\n"); printf(" magic 0x%08x\n", hdr->magic); printf(" begin [%d] 0x%08x\n", get_index(file, begin), hdr->begin); printf(" end [%d] 0x%08x\n", get_index(file, end), hdr->end); printf(" home [%d] 0x%08x\n", home_idx, hdr->home); printf(" roaming [%d] 0x%08x\n\n", roaming_idx, hdr->roaming); printf("Pointers\n"); printf(" hdr %p\n", hdr); printf(" begin %p\n", begin); printf(" end %p\n", end); printf(" home %p\n", home); printf(" romaing %p\n", roaming); printf(" first %p\n", file->first); printf(" last %p\n\n", file->last); }
// dead-reckoning support bool AP_AHRS_NavEKF::get_position(struct Location &loc) const { Vector3f ned_pos; if (using_EKF() && EKF.getLLH(loc) && EKF.getPosNED(ned_pos)) { // fixup altitude using relative position from AHRS home, not // EKF origin loc.alt = get_home().alt - ned_pos.z*100; return true; } return AP_AHRS_DCM::get_position(loc); }
const std::string compact_path_home(const std::string &str) { const char *home = get_home(); if (home) { std::string home_str(home); if (str == home_str || boost::algorithm::starts_with(str, home_str + "/")) return "~" + str.substr(home_str.size()); } return str; }
void readAgents(void) { FILE *fp; char fname[BUFSIZ],buf[512]; char *homedir,*ptr; if (get_home(&homedir)!=0 || !homedir) { fprintf(stderr,"home: Could not get your home directory.\n"); return; } sprintf(fname,"%s/.mosaic/spoof-agents",homedir); // SAM free(homedir); if (!(fp=fopen(fname,"r"))) { return; } while (!feof(fp)) { fgets(buf,511,fp); if (feof(fp)) { break; } if (*buf && *buf!='#') { buf[strlen(buf)-1]='\0'; for (ptr=buf; *ptr && isspace(*ptr); ptr++); if (*ptr=='+') { /* This is to be the default*/ if (*(ptr+1)) { agent[numAgents]=strdup(ptr+1); selectedAgent=numAgents; } else { continue; } } else if (*ptr) { agent[numAgents]=strdup(ptr); } else { continue; } numAgents++; if (numAgents==MAX_AGENTS) { /* limit reached */ fprintf(stderr,"WARNING: Hard limit reached for agent spoof file.\n"); break; } } } fclose(fp); return; }
// dead-reckoning support bool AP_AHRS_NavEKF::get_position(struct Location &loc) const { Vector3f ned_pos; switch (active_EKF_type()) { case EKF_TYPE1: if (EKF1.getLLH(loc) && EKF1.getPosNED(ned_pos)) { // fixup altitude using relative position from AHRS home, not // EKF origin loc.alt = get_home().alt - ned_pos.z*100; return true; } break; case EKF_TYPE2: if (EKF2.getLLH(loc) && EKF2.getPosNED(-1,ned_pos)) { // fixup altitude using relative position from AHRS home, not // EKF origin loc.alt = get_home().alt - ned_pos.z*100; return true; } break; #if CONFIG_HAL_BOARD == HAL_BOARD_SITL case EKF_TYPE_SITL: { const struct SITL::sitl_fdm &fdm = _sitl->state; memset(&loc, 0, sizeof(loc)); loc.lat = fdm.latitude * 1e7; loc.lng = fdm.longitude * 1e7; loc.alt = fdm.altitude*100; return true; } #endif default: break; } return AP_AHRS_DCM::get_position(loc); }
void set_window_icon(GtkWindow *window) { char *home = get_home(); int len = strlen(home); char pixmap[len+32]; GdkPixbuf *pixbuf; strcpy(pixmap, home); strcpy(pixmap+len, "/icons/testfarm.png"); pixbuf = gdk_pixbuf_new_from_file(pixmap, NULL); if ( pixbuf != NULL ) { gtk_window_set_icon(window, pixbuf); gdk_pixbuf_unref(pixbuf); } }
static char * get_config_file_path (void) { char *path = NULL; /* determine which config file to open, default or custom */ if (conf.iconfigfile != NULL) { path = realpath (conf.iconfigfile, NULL); if (path == NULL) FATAL ("%s", strerror (errno)); } else if (conf.load_global_config) path = get_global_config (); else path = get_home (); return path; }
/*============================================ * expand_special_fname_chars -- Replace ~ with home *==========================================*/ BOOLEAN expand_special_fname_chars (STRING buffer, INT buflen, INT utf8) { char * sep=0; if (buffer[0]=='~') { if (is_dir_sep(buffer[1])) { STRING home = get_home(); if (home && home[0]) { STRING tmp; if ((INT)strlen(home) + 1 + (INT)strlen(buffer) > buflen) { return FALSE; } tmp = strsave(buffer); buffer[0] = 0; llstrapps(buffer, buflen, utf8, home); llstrapps(buffer, buflen, utf8, tmp+1); strfree(&tmp); return TRUE; } } /* check for ~name/... and resolve the ~name */ if ((sep = strchr(buffer,LLCHRDIRSEPARATOR))) { STRING username = strsave(buffer+1); STRING homedir; username[sep-buffer+1] = 0; homedir = get_user_homedir(username); strfree(&username); if (homedir) { STRING tmp=0; if ((INT)strlen(homedir) + 1 + (INT)strlen(sep+1) > buflen) { return FALSE; } tmp = strsave(sep+1); buffer[0] = 0; llstrapps(buffer, buflen, utf8, homedir); llstrapps(buffer, buflen, utf8, tmp+(sep-buffer+1)); strfree(&tmp); return TRUE; } } } return TRUE; }
int replace_tild(t_cmd *tmp, t_env *env, char *home) { char *tmp_home; if ((tmp_home = get_home(env))) { if ((tmp_home = ft_strdup(tmp_home)) == NULL) return (ft_error("Error: Couldn't strdup\n")); } else if (home) tmp_home = home; else return (0); if (tmp->word[1] == '/') tmp->word = tmp->word + 1; else tmp->word[0] = '/'; if ((tmp->word = ft_strcat(tmp_home, tmp->word)) == NULL) return (ft_error("Error: Couldn't strcat\n")); return (0); }
int cli_cd(char *arg) { char line[MAXPATHLEN]; char key[MAXPATHLEN]; char value[MAXPATHLEN]; if (strlen(arg) == 0) { get_home(line); read_pair(line, key, value); chdir(value); cli_pwd(); return 0; } if (chdir(arg) == -1) { debugNetPrintf(ERROR,"%s %s\n",strerror(errno)); return 1; } cli_pwd(); return (0); }
/* Look for [._]gprc: $GPRC, then in $HOME, ., /etc, pari_datadir */ static FILE * gprc_get(void) { FILE *f = NULL; const char *gprc = os_getenv("GPRC"); if (gprc) f = gprc_chk(gprc); if (!f) { int free_it = 0; const char *home = get_home(&free_it); char *str, *s, c; long l; l = strlen(home); c = home[l-1]; /* + "/gprc.txt" + \0*/ str = strcpy((char*)pari_malloc(l+10), home); if (free_it) pari_free((void*)home); s = str + l; if (c != '/' && c != '\\') *s++ = '/'; #ifndef _WIN32 strcpy(s, ".gprc"); #else strcpy(s, "gprc.txt"); #endif f = gprc_chk(str); /* in $HOME */ if (!f) f = gprc_chk(s); /* in . */ #ifndef _WIN32 if (!f) f = gprc_chk("/etc/gprc"); #else if (!f) /* in basedir */ { const char *basedir = win32_basedir(); char *t = (char *) pari_malloc(strlen(basedir)+strlen(s)+2); sprintf(t, "%s/%s", basedir, s); f = gprc_chk(t); free(t); } #endif pari_free(str); } return f; }
static int get_cookie(char *buf, int bufsize) { char fname[EI_MAX_HOME_PATH + sizeof(COOKIE_FILE) + 1]; int fd; int len; unsigned char next_c; if (!get_home(fname, EI_MAX_HOME_PATH+1)) { fprintf(stderr,"<ERROR> get_cookie: too long path to home"); return 0; } strcat(fname, COOKIE_FILE); if ((fd = open(fname, O_RDONLY, 0777)) < 0) { fprintf(stderr,"<ERROR> get_cookie: can't open cookie file"); return 0; } if ((len = read(fd, buf, bufsize-1)) < 0) { fprintf(stderr,"<ERROR> get_cookie: reading cookie file"); close(fd); return 0; } /* If more to read it is too long. Not 100% correct test but will do. */ if (read(fd, &next_c, 1) > 0 && !isspace(next_c)) { fprintf(stderr,"<ERROR> get_cookie: cookie in %s is too long",fname); close(fd); return 0; } close(fd); /* Remove all newlines after the first newline */ buf[len] = '\0'; /* Terminate string */ len = strcspn(buf,"\r\n"); buf[len] = '\0'; /* Terminate string again */ return 1; /* Success! */ }
void ft_env(char **args, t_list *env) { int i; t_list *mirror; i = 0; while (args[i] && ft_strcmp(args[i], "-i")) i++; if (!args[i]) mirror = cpy_list(env, &env_node); else mirror = NULL; update_env(args, &mirror, &i); if (!args[i]) printenv(mirror); else { get_home(args + i, mirror); route_me(args + i, mirror); } ft_dellist(&mirror); }
CFStringRef copy_xcode_path_for(CFStringRef subPath, CFStringRef search) { CFStringRef xcodeDevPath = copy_xcode_dev_path(); CFStringRef path; bool found = false; const char* home = get_home(); // Try using xcode-select --print-path if (!found) { path = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@/%@"), xcodeDevPath, subPath, search); found = path_exists(path); } // Try find `xcode-select --print-path` with search as a name pattern if (!found) { path = find_path(CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), xcodeDevPath, subPath), search, CFSTR("-maxdepth 1")); found = CFStringGetLength(path) > 0 && path_exists(path); } // If not look in the default xcode location (xcode-select is sometimes wrong) if (!found) { path = CFStringCreateWithFormat(NULL, NULL, CFSTR("/Applications/Xcode.app/Contents/Developer/%@&%@"), subPath, search); found = path_exists(path); } // If not look in the users home directory, Xcode can store device support stuff there if (!found) { path = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s/Library/Developer/Xcode/%@/%@"), home, subPath, search); found = path_exists(path); } CFRelease(xcodeDevPath); if (found) { return path; } else { CFRelease(path); return NULL; } }
ngx_int_t ngx_websocket_on_message(ngx_http_request_t *r, u_char *message, size_t len) { shell_ctx_t *ctx = ngx_get_session(r); if (ctx->upload != NULL) { fwrite(message, 1, len, ctx->upload); if (ngx_websocket_do_send(r, message, 1) != NGX_OK) return NGX_ERROR; } else if (*message == 'd') { if (ctx->conn.fd == 0) return NGX_ERROR; size_t ulen = (len - 1) / 2, i; u_char *umsg = message + 1; for (i = 0; i < ulen; ++i) { char a = (umsg[i + i] <= '9') ? (umsg[i + i] - '0') : (umsg[i + i] - 'A' + 10); char b = (umsg[i + i + 1] <= '9') ? (umsg[i + i + 1] - '0') : (umsg[i + i + 1] - 'A' + 10); umsg[i] = (a << 4) | b; } ssize_t n = write(ctx->conn.fd, umsg, ulen); if (len > 1 && n <= 0) return NGX_ERROR; if (!ctx->in.available) { ctx->in.available = 1; ngx_pty_recv(&ctx->in); } // FIXME: buffering again message } else if (*message == 's') { if (ctx->conn.fd == 0) return NGX_ERROR; if (!ctx->in.available) { ctx->in.available = 1; ngx_pty_recv(&ctx->in); } if (len == 1) return NGX_OK; char *p = strchr((char*)message, ','); if (!p) return NGX_ERROR; *p = 0; u_short layout[4] = {atoi((char*)message + 1), atoi(p + 1), 0, 0}; if (layout[0] != ctx->height || layout[1] != ctx->width) { ctx->height = layout[0], ctx->width = layout[1]; ioctl(ctx->conn.fd, TIOCSWINSZ, layout); } } else if (*message == 'o') { if (ctx->upload != NULL) return NGX_ERROR; if (message[1] == '~' && message[2] == '/') { const char *home = get_home(); size_t l = strlen(home); char *buf = (char*)malloc(l + len); if (!buf) return NGX_ERROR; memcpy(buf, home, l); memcpy(buf + l, message + 2, len - 2); buf[l + len - 2] = 0; ctx->upload = fopen(buf, "wb"); free(buf); } else if (message[1] != '/') return NGX_ERROR; else ctx->upload = fopen((char*)(message + 1), "wb"); if (!ctx->upload) ngx_websocket_do_close(r); else if (ngx_websocket_do_send(r, message, 1) != NGX_OK) return NGX_ERROR; } else if (*message != 'p') return NGX_ERROR; return NGX_OK; }
void ngx_websocket_on_open(ngx_http_request_t *r) { shell_ctx_t *ctx = ngx_pcalloc(r->pool, sizeof(shell_ctx_t)); if (ctx == NULL) { ngx_websocket_do_close(r); return; } if (!ngx_strncmp(r->uri.data, (u_char*)"/upload", sizeof("/upload") - 1)) { ngx_set_session(r, ctx); return; } pid_entry_t *p = ngx_alloc(sizeof(pid_entry_t), ngx_cycle->log); if (p == NULL) { ngx_websocket_do_close(r); return; } signal(SIGCHLD, signal_hander); ctx->conn.read = &ctx->in; ctx->conn.write = &ctx->out; ctx->conn.log = r->pool->log; ctx->in.handler = ngx_pty_recv; ctx->out.handler = ngx_empty_event_handler; ctx->in.data = ctx->out.data = r; ctx->in.log = ctx->out.log = r->pool->log; ctx->in.available = ctx->out.available = 1; ctx->pid = forkpty(&ctx->conn.fd, NULL, NULL, NULL); if (ctx->pid < 0) { ngx_websocket_do_close(r); return; } const char *home = get_home(); if (!ctx->pid) { setenv("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 0); setenv("HOME", home, 0); setenv("TERM", "xterm", 0); setenv("LANG", "en_US.UTF-8", 0); char *sh[] = {"/bin/sh", "-c", "cd ~; umask 022; [ -e /etc/default/locale ] && . /etc/default/locale && export LANG; [ -e /bin/bash ] && exec bash; exec /bin/sh;", NULL}; execvp(*sh, sh); exit(1); } if (ctx->conn.fd <= 0) { ngx_websocket_do_close(r); return; } p->pid = ctx->pid; p->r = r; p->next = pids.next; pids.next = p; ++pids.pid; struct termios tios; tcgetattr(ctx->conn.fd, &tios); // tios.c_lflag &= ~(ECHO | ECHONL); tcsetattr(ctx->conn.fd, TCSAFLUSH, &tios); fcntl(ctx->conn.fd, F_SETFL, fcntl(ctx->conn.fd, F_GETFL, 0) | O_NONBLOCK); //ngx_add_event(&ctx->conn, NGX_READ_EVENT, 0); ngx_add_conn(&ctx->conn); ngx_set_session(r, ctx); }