const char * vp_pty_open(char *args) { vp_stack_t stack; int argc; char *argv[VP_ARGC_MAX]; int fdm; pid_t pid; struct winsize ws = {0, 0, 0, 0}; struct termios ti; int i; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%hu", &(ws.ws_col))); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%hu", &(ws.ws_row))); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &argc)); if (argc < 1 || VP_ARGC_MAX <= argc) return vp_stack_return_error(&_result, "argc range error. too many arguments. please use xargs."); for (i = 0; i < argc; ++i) VP_RETURN_IF_FAIL(vp_stack_pop_str(&stack, &(argv[i]))); argv[argc] = NULL; #if 0 /* TODO: set termios parameter */ /* tcgetattr will fail when gvim is executed from gnome menu */ if (tcgetattr(STDIN_FILENO, &ti) < 0) return vp_stack_return_error(&_result, "tcgetattr() error: %s", strerror(errno)); pid = forkpty(&fdm, NULL, &ti, &ws); #else pid = forkpty(&fdm, NULL, NULL, &ws); #endif if (pid < 0) { return vp_stack_return_error(&_result, "forkpty() error: %s", strerror(errno)); } else if (pid == 0) { /* child */ if (execv(argv[0], argv) < 0) { /* error */ write(fdm, strerror(errno), strlen(strerror(errno))); _exit(EXIT_FAILURE); } } else { /* parent */ vp_stack_push_num(&_result, "%d", pid); vp_stack_push_num(&_result, "%d", fdm); /* XXX - ttyname(fdm) breaks in OS X */ vp_stack_push_str(&_result, "unused"); return vp_stack_return(&_result); } /* DO NOT REACH HERE */ return NULL; }
static int handle_terminal (int *terminal, char **argv) { int pid = forkpty (terminal, 0, 0, 0); if ( -1 == pid ) /* forkpty failed */ exit_error("could not fork or more pseudo terminals available"); /* are we parent ? */ if ( 0 != pid ) /* yes - return with child pid */ return pid; /* remove cr/lf translation from terminal */ struct termios settings; tcgetattr (STDOUT_FILENO, &settings); settings.c_oflag &= ~OPOST; settings.c_oflag &= ~ONLCR; tcsetattr (STDOUT_FILENO, TCSANOW, &settings); /* stdin/stdout/stderr is connected to fd. Launch application */ execvp(argv[0],&argv[0]); DEBUG( LID, "Could not execute\n"); /* application terminated - die and return */ close(*terminal); _exit (1); }
int run(char *command, int sx, int sy) { int fd; struct winsize ws; ws.ws_row=sy; ws.ws_col=sx; ws.ws_xpixel=0; ws.ws_ypixel=0; switch (forkpty(&fd,0,0,(sx&&sy)?&ws:0)) { case -1: return -1; case 0: { char *argv[4], *cmd; if (asprintf(&cmd, "exec %s", command) == -1) abort(); argv[0]="sh"; argv[1]="-c"; argv[2]=cmd; argv[3]=0; execve("/bin/sh",argv,environ); fprintf(stderr,"#ERROR: Couldn't exec `%s'\n",command); exit(127); } default: return fd; } return -1; }
static pid_t fork_exec_bootloader(int *master, const char *arg0, char **args) { struct termios termattr; pid_t pid = forkpty(master, NULL, NULL, NULL); if (pid == -1) return -1; else if (pid == 0) { setenv("TERM", "vt100", 1); libxl__exec(-1, -1, -1, arg0, args); return -1; } /* * On Solaris, the master pty side does not have terminal semantics, * so don't try to set any attributes, as it will fail. */ #if !defined(__sun__) tcgetattr(*master, &termattr); cfmakeraw(&termattr); tcsetattr(*master, TCSANOW, &termattr); #endif fcntl(*master, F_SETFL, O_NDELAY); return pid; }
int main(){ struct pollfd* fds; int c,i,pid; char buf[256]; fds = malloc(sizeof(struct pollfd)*3); pid = forkpty(&ptm, NULL, NULL, NULL); if(pid == 0){ execl("/bin/bash", "", NULL); } else{ fds[0].fd = ptm; fds[0].events = POLLIN; fds[1].fd = 0; fds[1].events = POLLIN; while(1){ if(poll(fds, 2, 100)>0){ for(i=0;i<2;i++){ if(fds[i].revents&POLLIN){ if(fds[i].fd == ptm){ c = read(ptm, buf, 1); write(1, buf, c); } if(fds[i].fd == 0){ c = read(0, buf, 1); //write(1, buf, с); write(ptm, buf, c); } } } } } } free(fds); return 0; }
pid_t rote_vt_forkpty(RoteTerm *rt, const char *command) { struct winsize ws; pid_t childpid; ws.ws_row = rt->rows; ws.ws_col = rt->cols; ws.ws_xpixel = ws.ws_ypixel = 0; childpid = forkpty(&rt->pd->pty, NULL, NULL, &ws); if (childpid < 0) return -1; if (childpid == 0) { /* we are the child, running under the slave side of the pty. */ /* Cajole application into using linux-console-compatible escape * sequences (which is what we are prepared to interpret) */ setenv("TERM", "linux", 1); /* Now we will exec /bin/sh -c command. */ execl("/bin/sh", "/bin/sh", "-c", command, NULL); fprintf(stderr, "\nexecl() failed.\nCommand: '%s'\n", command); exit(127); /* error exec'ing */ } /* if we got here we are the parent process */ rt->childpid = childpid; return childpid; }
void upload_goagent(GtkWidget *widget,UP_DATA *data) { if(data->off) { message_box(widget,_("Upload Now!")); return; } if(!is_python_and_goagent_path(data->python_path,data->goagent_path)) return; //chdir(data->goagent_path); if((data->pid=forkpty(&data->pty,NULL,NULL,NULL))==0) { if(execl(data->python_path,"python_upload", get_uploader_path(data->goagent_path),NULL)==-1) { write(STDERR_FILENO,_("Error Python Path!"), strlen(_("Error Python Path!"))); _exit(-1); } } g_idle_add((GSourceFunc)_upload_goagent,data); data->off=1; }
int rpl_forkpty (int *amaster, char *name, struct termios const *termp, struct winsize const *winp) { /* Cast away const, for implementations with weaker prototypes. */ return forkpty (amaster, name, (struct termios *) termp, (struct winsize *) winp); }
static int create_subproc_pty(const char* cmd, const char* arg0, const char* arg1, pid_t* pid) { D("create_subproc_pty(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1); char pts_name[PATH_MAX]; int ptm; *pid = forkpty(&ptm, pts_name, nullptr, nullptr); if (*pid == -1) { printf("- fork failed: %s -\n", strerror(errno)); adb_close(ptm); return -1; } if (*pid == 0) { init_subproc_child(); int pts = unix_open(pts_name, O_RDWR | O_CLOEXEC); if (pts == -1) { fprintf(stderr, "child failed to open pseudo-term slave %s: %s\n", pts_name, strerror(errno)); adb_close(ptm); exit(-1); } // arg0 is "-c" in batch mode and "-" in interactive mode. if (strcmp(arg0, "-c") == 0) { termios tattr; if (tcgetattr(pts, &tattr) == -1) { fprintf(stderr, "tcgetattr failed: %s\n", strerror(errno)); adb_close(pts); adb_close(ptm); exit(-1); } cfmakeraw(&tattr); if (tcsetattr(pts, TCSADRAIN, &tattr) == -1) { fprintf(stderr, "tcsetattr failed: %s\n", strerror(errno)); adb_close(pts); adb_close(ptm); exit(-1); } } dup2(pts, STDIN_FILENO); dup2(pts, STDOUT_FILENO); dup2(pts, STDERR_FILENO); adb_close(pts); adb_close(ptm); execl(cmd, cmd, arg0, arg1, nullptr); fprintf(stderr, "- exec '%s' failed: %s (%d) -\n", cmd, strerror(errno), errno); exit(-1); } else { return ptm; } }
int omxplayer_StartPlaying(const char *filename) { char fullVideoPath[2048]; LogDebug(VB_MEDIAOUT, "omxplayer_StartPlaying(%s)\n", filename); bzero(&mediaOutputStatus, sizeof(mediaOutputStatus)); if (snprintf(fullVideoPath, 2048, "%s/%s", getVideoDirectory(), filename) >= 2048) { LogErr(VB_MEDIAOUT, "Unable to play %s, full path name too long\n", filename); return 0; } if (getFPPmode() == REMOTE_MODE) CheckForHostSpecificFile(getSetting("HostName"), fullVideoPath); if (!FileExists(fullVideoPath)) { LogErr(VB_MEDIAOUT, "%s does not exist!\n", fullVideoPath); return 0; } // Create Pipes to/from omxplayer pid_t omxplayerPID = forkpty(&pipeFromOMX[0], 0, 0, 0); if (omxplayerPID == 0) // omxplayer process { ShutdownControlSocket(); seteuid(1000); // 'pi' user execl("/opt/fpp/scripts/omxplayer", "/opt/fpp/scripts/omxplayer", fullVideoPath, NULL); LogErr(VB_MEDIAOUT, "omxplayer_StartPlaying(), ERROR, we shouldn't " "be here, this means that execl() failed\n"); exit(EXIT_FAILURE); } else // Parent process { mediaOutput->childPID = omxplayerPID; } // Clear active file descriptor sets FD_ZERO (&omx_active_fd_set); // Set description for reading from omxplayer FD_SET (pipeFromOMX[0], &omx_active_fd_set); mediaOutputStatus.status = MEDIAOUTPUTSTATUS_PLAYING; omxVolumeShift = omxplayer_GetVolumeShift(getVolume()); return 1; }
/* Initialize the pty structure. */ static int init_pty(char **argv, int statusfd) { /* Use the original terminal's settings. We don't have to set the ** window size here, because the attacher will send it in a packet. */ the_pty.term = orig_term; memset(&the_pty.ws, 0, sizeof(struct winsize)); /* Create the pty process */ if (!dont_have_tty) the_pty.pid = forkpty(&the_pty.fd, NULL, &the_pty.term, NULL); else the_pty.pid = forkpty(&the_pty.fd, NULL, NULL, NULL); if (the_pty.pid < 0) return -1; else if (the_pty.pid == 0) { /* Child.. Execute the program. */ execvp(*argv, argv); /* Report the error to statusfd if we can, or stdout if we ** can't. */ if (statusfd != -1) dup2(statusfd, 1); else printf(EOS "\r\n"); printf("%s: could not execute %s: %s\r\n", progname, *argv, strerror(errno)); fflush(stdout); _exit(127); } /* Parent.. Finish up and return */ #ifdef BROKEN_MASTER { char *buf; buf = ptsname(the_pty.fd); the_pty.slave = open(buf, O_RDWR|O_NOCTTY); } #endif return 0; }
QTerminal::QTerminal(QWidget *parent, Qt::WindowFlags f) : QTextEdit(parent) { setWindowFlags(f); qDebug() << "Constructing QTerminal"; savedCursor = this->textCursor(); sequenceState = NoSequence; insertMode = false; // The Following line causes the tab key to change focus... //setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard); // //setTabChangesFocus(false); //setFocusPolicy(Qt::ClickFocus); /* * Launch a shell connected to the current process by a PTY */ shellPid = forkpty(&fdMaster, NULL, NULL, NULL); if (0 == shellPid) { /* fork off a shell */ /* if they don't have a shell, use bash */ setenv("SHELL", "/bin/bash", 0); /* no special control features are supported */ setenv("TERM", "xterm", 1); /* hand off to the shell of choice */ execl(getenv("SHELL"), getenv("SHELL"), (char *)0); /* If this exec returns, we should take some action. * Window systems do ugly things if two processes try * to use the same resources. */ if (errno == ENOENT) { execl("/bin/sh", "/bin/sh", (char*)0); } perror("QTerminal: exec"); // exit hard in case exit handlers mess with the window system _exit(127); } else if (-1 == shellPid) { // didn't fork this->setText(QString("QTerminal: fork: %1\n").arg(strerror(errno))); } else { /* * We will use non-blocking I/O to read from the shell */ fcntl(fdMaster, F_SETFL, fcntl(fdMaster, F_GETFL, 0) | O_NONBLOCK); qDebug() << "Shell PID " << shellPid << " on file descriptor " << fdMaster; /* * Arrange to be notified when the shell emits output */ watcher = new FileDescriptorMonitor(fdMaster, this); connect(watcher, SIGNAL(readyForRead(int)), this, SLOT(readOutput()), Qt::BlockingQueuedConnection); connect(this, SIGNAL(shellExited()), watcher, SLOT(stop())); watcher->start(); } }
ScmObj Scm_Forkpty(ScmObj slaveterm) { int master; pid_t pid; struct termios *term = NULL; if (SCM_SYS_TERMIOS_P(slaveterm)) { term = &SCM_SYS_TERMIOS(slaveterm)->term; } if ((pid = forkpty(&master, NULL, term, NULL)) < 0) { Scm_SysError("forkpty failed"); } return Scm_Values2(Scm_MakeInteger(pid), SCM_MAKE_INT(master)); }
void *create_client(const char *user, const char *passwd) { struct vt100client *client; pthread_t thread1, thread2; struct winsize winsz; int mpty; pid_t pid; /*start up sushi too login and run the shell in fresh pty*/ ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsz); if ((pid = forkpty(&mpty, NULL, NULL, &winsz)) == 0) { execlp("sushi", "sushi", user, passwd, NULL); return NULL; } else if (pid < 0) { return NULL; } if (user) { free((void*)user); } if (passwd) { memset((void*)passwd, '\0', strlen(passwd)); free((void*)passwd); } /*configure client*/ if (!(client = malloc(sizeof(*client)))) { return NULL; } client->orig_tios = malloc(sizeof(*client->orig_tios)); client->ptyfd = mpty; /*set up sockets*/ set_fdflag(client->ptyfd, O_NONBLOCK, 0); set_fdflag(STDIN_FILENO, O_NONBLOCK, 0); make_raw(STDIN_FILENO, client); /*start up the io bridges jouin to the pty*/ pthread_create(&thread1, NULL, pty_thread, client); pthread_create(&thread2, NULL, stdin_thread, client); pthread_join(thread1, NULL); /*restore terminal settings cleanup*/ if (client->orig_tios) { tcsetattr(STDIN_FILENO, TCSANOW, client->orig_tios); free(client->orig_tios); } free(client); return NULL; }
static int main_loop(ssh_channel chan) { ssh_session session = ssh_channel_get_session(chan); socket_t fd; struct termios *term = NULL; struct winsize *win = NULL; pid_t childpid; ssh_event event; short events; childpid = forkpty(&fd, NULL, term, win); if(childpid == 0) { execl("/bin/bash", "/bin/bash", (char *)NULL); abort(); } cb.userdata = &fd; ssh_callbacks_init(&cb); ssh_set_channel_callbacks(chan, &cb); events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL; event = ssh_event_new(); if(event == NULL) { printf("Couldn't get a event\n"); return -1; } if(ssh_event_add_fd(event, fd, events, copy_fd_to_chan, chan) != SSH_OK) { printf("Couldn't add an fd to the event\n"); return -1; } if(ssh_event_add_session(event, session) != SSH_OK) { printf("Couldn't add the session to the event\n"); return -1; } do { ssh_event_dopoll(event, 1000); } while(!ssh_channel_is_closed(chan)); ssh_event_remove_fd(event, fd); ssh_event_remove_session(event, session); ssh_event_free(event); return 0; }
TEST(pty, forkpty) { pid_t sid = getsid(0); int master; pid_t pid = forkpty(&master, NULL, NULL, NULL); ASSERT_NE(-1, pid); if (pid == 0) { // We're the child. ASSERT_NE(sid, getsid(0)); _exit(0); } ASSERT_EQ(sid, getsid(0)); AssertChildExited(pid, 0); close(master); }
/* Fork and exec with a pty, returning the fd of the master pty. */ int fork_exec_with_pty ( HsInt sx , HsInt sy , int search , const char *file , char *const argv[] , char *const env[] , HsInt *child_pid ) { int pty; int packet_mode = 1; struct winsize ws; /* Set the terminal size and settings. */ memset(&ws, 0, sizeof ws); ws.ws_col = sx; ws.ws_row = sy; /* Fork and exec, returning the master pty. */ *child_pid = forkpty(&pty, NULL, NULL, &ws); switch (*child_pid) { case -1: return -1; case 0: /* If an environment is specified, override the old one. */ if (env) environ = (char**) env; /* Search user's path or not. */ if (search) execvp(file, argv); else execv(file, argv); perror("exec failed"); exit(EXIT_FAILURE); default: /* Switch the pty to packet mode, we'll deal with packeting on the haskell side of things. */ if (ioctl(pty, TIOCPKT, &packet_mode) == -1) return 1; return pty; } }
TemuPty *temu_pty_new_execve( GIOFunc data_func, GIOFunc err_func, gpointer data, const char *path, char *const argv[], char *const envp[] ) { TemuPty *pty; pid_t pid; int master; GIOFlags flags; struct termios ti; GSList *fds; init_term_with_defaults(&ti); pid = forkpty(&master, NULL, &ti, NULL); if (pid == -1) return NULL; if (!pid) { for (fds = pty_fds; fds; fds = g_slist_next(fds)) close(GPOINTER_TO_INT(fds->data)); execve(path, argv, envp); exit(127); } pty = g_new(TemuPty, 1); pty_fds = g_slist_prepend(pty_fds, GINT_TO_POINTER(master)); /* Whoever decided to screw with the data by _DEFAULT_ loses. */ pty->master = g_io_channel_unix_new(master); g_io_channel_set_encoding(pty->master, NULL, NULL); g_io_channel_set_buffered(pty->master, FALSE); flags = g_io_channel_get_flags(pty->master) | G_IO_FLAG_NONBLOCK; g_io_channel_set_flags(pty->master, flags, NULL); pty->data_watch = g_io_add_watch_full(pty->master, G_PRIORITY_HIGH, G_IO_IN|G_IO_PRI, data_func, data, NULL); pty->err_watch = g_io_add_watch(pty->master, G_IO_ERR|G_IO_HUP, err_func, data); return pty; }
void get_connect(DATA *data) { //pipe(data->pipefd); sig_data=data; //RD_DATA *put_data=malloc(sizeof(RD_DATA)); //put_data->text=data->text; if((data->pid=forkpty(&data->pty,NULL,NULL,NULL))==0) { if(execl(data->python_path,"python",data->proxy_py_path,NULL)==-1) { write(STDERR_FILENO,_("Error Python Path!"), strlen(_("Error Python Path!"))); kill(getppid(),SIGUSR1); _exit(-1); } } /*if((data->pid=fork())==0) { close(data->pipefd[0]); dup2(data->pipefd[1],STDERR_FILENO); dup2(data->pipefd[1],STDOUT_FILENO); if(execl(data->python_path,"python",data->proxy_py_path,NULL)==-1) { write(STDERR_FILENO,_("Error Python Path!"), strlen(_("Error Python Path!"))); kill(getppid(),SIGUSR1); _exit(-1); } } close(data->pipefd[1]); flags=fcntl(data->pipefd[0],F_GETFL,0); flags|=O_NONBLOCK; fcntl(data->pipefd[0],F_SETFL,flags);*/ g_idle_add((GSourceFunc)_get_connect,data); }
static int do_shell (ssh_event event, ssh_channel chan) { socket_t fd; struct termios *term = NULL; struct winsize *win = NULL; short events; int fd_status; state.childpid = forkpty (&fd, NULL, term, win); if (state.childpid == 0) { close (state.bind_fd); close (state.session_fd); execl ("/bin/bash", "/bin/bash", NULL); _exit (127); } else if (state.childpid < 0) { g_critical ("forkpty failed: %s", g_strerror (errno)); return -1; } fd_status = fcntl (fd, F_GETFL, 0); if (fcntl (fd, F_SETFL, fd_status | O_NONBLOCK) < 0) { g_critical ("couldn't set non-blocking mode"); return -1; } cb.userdata = (gpointer)(long)fd; ssh_callbacks_init(&cb); ssh_set_channel_callbacks (chan, &cb); events = POLLIN | POLLOUT | POLLPRI | POLLERR | POLLHUP | POLLNVAL; if (ssh_event_add_fd (event, fd, events, fd_data, chan) != SSH_OK) g_return_val_if_reached(-1); return 0; }
static int handle_redirection_proc (const char *cmd, bool in, bool out, bool err) { #if __UNIX__ // use PTY to redirect I/O because pipes can be problematic in // case of interactive programs. int fdm; int saved_stdin = dup (STDIN_FILENO); int saved_stdout = dup (STDOUT_FILENO); int saved_stderr = dup (STDERR_FILENO); if (forkpty (&fdm, NULL, NULL, NULL) == 0) { // child - program to run struct termios t; // necessary because otherwise you can read the same thing you // wrote on fdm. tcgetattr(0, &t); cfmakeraw(&t); tcsetattr(0, TCSANOW, &t); if (!in) dup2 (saved_stdin, STDIN_FILENO); if (!out) dup2 (saved_stdout, STDOUT_FILENO); if (!err) dup2 (saved_stderr, STDERR_FILENO); close (saved_stdin); close (saved_stdout); close (saved_stderr); return 0; } else { // father close (saved_stdin); close (saved_stdout); close (saved_stderr); if (in) dup2 (fdm, STDOUT_FILENO); if (out) dup2 (fdm, STDIN_FILENO); exit (r_sys_cmd (cmd)); } #else #warning handle_redirection_proc : unimplemented for this platform return -1; #endif }
int main(int argc, char *argv[]) { if (argc < 2) { fprintf(stderr, "Usage:\n\t%s command [args..]\n", argv[0]); return 1; } int tty_fd; pid_t pid = forkpty(&tty_fd, NULL, NULL, NULL); if (pid == -1) { /* ERROR */ perror("forkpty"); return 2; } else if (pid > 0) { /* PARENT */ char buffer[BUFSIZ]; ssize_t count = read(tty_fd, buffer, sizeof(buffer)); while (count > 0) { write(STDOUT_FILENO, buffer, count); count = read(tty_fd, buffer, sizeof(buffer)); } int status; pid_t ret = waitpid(pid, &status, 0); return WEXITSTATUS(status); } else { /* CHILD */ execvp(argv[1], argv + 1); perror("execvp"); return 3; } return 0; }
ScmObj Scm_ForkptyAndExec(ScmString *file, ScmObj args, ScmObj iomap, ScmObj slaveterm, ScmSysSigset *mask) { int argc = Scm_Length(args); char **argv; const char *program; int *fds; int master; pid_t pid; struct termios *term = NULL; if (argc < 1) { Scm_Error("argument list must have at least one element: %S", args); } argv = Scm_ListToCStringArray(args, TRUE, NULL); program = Scm_GetStringConst(file); if (SCM_SYS_TERMIOS_P(slaveterm)) { term = &SCM_SYS_TERMIOS(slaveterm)->term; } fds = Scm_SysPrepareFdMap(iomap); if ((pid = forkpty(&master, NULL, term, NULL)) < 0) { Scm_SysError("forkpty failed"); } if (pid == 0) { Scm_SysSwapFds(fds); if (mask) { Scm_ResetSignalHandlers(&mask->set); Scm_SysSigmask(SIG_SETMASK, mask); } execvp(program, (char *const*)argv); /* here, we failed */ Scm_Panic("exec failed: %s: %s", program, strerror(errno)); } return Scm_Values2(Scm_MakeInteger(pid), SCM_MAKE_INT(master)); }
int CreatePtyShell(void) { int master, slave; char * argv[2]; char pty_name[32]; signal(SIGCHLD, ptysignaled); signal(SIGINT, ptysignaled); if ((pid = forkpty(&master, pty_name, NULL, NULL)) == -1) { fprintf(stderr, "No processes\n"); return -1; } fprintf(stderr, "CYGWIN: Opened pty_name %s\n", pty_name); if (!pid) { close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); close(master); setsid(); grantpt(master); unlockpt(master); if ((slave = open(pty_name, O_RDWR)) < 0) { fprintf(stderr, "Child: Can't open pty %s\n", pty_name); exit(1); } dup2(slave, STDIN_FILENO); dup2(slave, STDOUT_FILENO); dup2(slave, STDERR_FILENO); /*if(!(argv[0] = getenv("SHELL")))*/ argv[0] = SHELL; argv[1] = NULL; execv(argv[0], argv); exit(1); } return master; }
int main(int argc, char *argv[], char *environ[]) { pid_t pid; int masterfd; struct winsize terminal_size; int i; terminal_size.ws_row = 80; terminal_size.ws_col = 25; terminal_size.ws_xpixel = 0; terminal_size.ws_ypixel = 0; pid = forkpty(&masterfd, NULL, NULL, &terminal_size); if (pid == 0) { /* child */ char *args[] = { "/bin/sh", NULL }; char *env[] = { NULL }; #if 0 execve("/bin/bash", args, env); #endif #if 1 process_cmds(); #endif _exit(1); } resync(masterfd); #if 1 for (i = 0; i < 10; i++) { usleep(100); kill(pid, SIGINT); } #endif #if 0 usleep(1000); #endif resync(masterfd); return 0; }
END_TEST START_TEST( test_lee_matrix_stdin) { tipo_dato valor_esperado_0_0 = 1000000000000000; tipo_dato valor_esperado_1_2 = 9007199254740992; tipo_dato resultado_real_0_0 = 0; tipo_dato resultado_real_1_2 = 0; int filas_esperadas = 3; int resulta_filas = 0; tipo_dato matrix[MAX_COLUMNAS_INPUT][MAX_FILAS_INPUT]; int ptyfd = 0; int pid = 0; const char *cagada = "1000000000000000 10000000000000000\n2 12\n9007199254740992 9007199254740992\n"; /* XXX: http://stackoverflow.com/questions/5740176/how-do-i-write-a-testing-function-for-another-function-that-uses-stdin-input*/ pid = forkpty(&ptyfd, 0, 0, 0); if (pid < 0) perror("forkpty"), exit(1); if (!pid) { lee_matriz_long_stdin(matrix, &resulta_filas); resultado_real_0_0 = matrix[0][0]; resultado_real_1_2 = matrix[1][2]; ck_assert_msg( resultado_real_0_0 == valor_esperado_0_0 && resultado_real_1_2 == valor_esperado_1_2 && resulta_filas == filas_esperadas, "Expecting %ld and %ld, got %ld and %ld", valor_esperado_0_0, valor_esperado_1_2, resultado_real_0_0, resultado_real_1_2); } else { write(ptyfd, cagada, strlen(cagada)); } }
const char * vp_pty_open(char *args) { vp_stack_t stack; int argc; int fd[3][2]; pid_t pid; struct winsize ws = {0, 0, 0, 0}; int dummy; int hstdin, hstderr, hstdout; int fdm; int npipe; VP_RETURN_IF_FAIL(vp_stack_from_args(&stack, args)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &npipe)); if (npipe != 2 && npipe != 3) return vp_stack_return_error(&_result, "npipe range error. wrong pipes."); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%hu", &(ws.ws_col))); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%hu", &(ws.ws_row))); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &hstdin)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &hstdout)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &hstderr)); VP_RETURN_IF_FAIL(vp_stack_pop_num(&stack, "%d", &argc)); /* Set pipe */ if (hstdin) { fd[0][0] = hstdin; fd[0][1] = 0; } if (hstdout == 1) { if (pipe(fd[1]) < 0) { return vp_stack_return_error(&_result, "pipe() error: %s", strerror(errno)); } } else if (hstdout) { fd[1][1] = hstdout; fd[1][0] = 0; } if (npipe == 3) { if (hstderr == 1) { if (pipe(fd[2]) < 0) { return vp_stack_return_error(&_result, "pipe() error: %s", strerror(errno)); } } else if (hstderr == 1) { fd[2][1] = hstderr; fd[2][0] = 0; } else { if (openpty(&fd[2][0], &fd[2][1], NULL, NULL, &ws) < 0) { return vp_stack_return_error(&_result, "openpty() error: %s", strerror(errno)); } } } pid = forkpty(&fdm, NULL, NULL, &ws); if (hstdin == 0) { fd[0][1] = fdm; } if (hstdout == 0) { fd[1][0] = fdm; } if (hstdin == 0 && hstdout == 0) { fd[1][0] = dup(fdm); } if (pid < 0) { return vp_stack_return_error(&_result, "fork() error: %s", strerror(errno)); } else if (pid == 0) { /* child */ char **argv; int i; /* Close pipe */ if (hstdout == 1) { close(fd[1][0]); } if (npipe == 3 && hstderr == 1) { close(fd[2][0]); } if (hstdin && fd[0][0] != STDIN_FILENO) { if (dup2(fd[0][0], STDIN_FILENO) != STDIN_FILENO) { goto child_error; } close(fd[0][0]); } if (hstdout && fd[1][1] != STDOUT_FILENO) { /* Set termios. */ if (dup2(fd[1][1], STDOUT_FILENO) != STDOUT_FILENO) { goto child_error; } close(fd[1][1]); } if (npipe == 3 && fd[2][1] != STDERR_FILENO) { if (dup2(fd[2][1], STDERR_FILENO) != STDERR_FILENO) { goto child_error; } close(fd[2][1]); } argv = malloc(sizeof(char *) * (argc+1)); if (argv == NULL) { goto child_error; } for (i = 0; i < argc; ++i) { if (vp_stack_pop_str(&stack, &(argv[i]))) { free(argv); goto child_error; } } argv[argc] = NULL; if (execvp(argv[0], argv) < 0) { /* error */ free(argv); goto child_error; } free(argv); } else { /* parent */ if (hstdout == 1) { close(fd[1][1]); } if (npipe == 3 && (hstderr == 0 || hstderr == 1)) { close(fd[2][1]); } vp_stack_push_num(&_result, "%d", pid); vp_stack_push_num(&_result, "%d", fd[0][1]); vp_stack_push_num(&_result, "%d", fd[1][0]); if (npipe == 3) { vp_stack_push_num(&_result, "%d", fd[2][0]); } return vp_stack_return(&_result); } /* DO NOT REACH HERE */ return NULL; /* error */ child_error: dummy = write(STDOUT_FILENO, strerror(errno), strlen(strerror(errno))); _exit(EXIT_FAILURE); }
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); }
int main(int argc, char ** argv, char ** envp) { int fd; char readbuf[1025], writebuf[1025]; signed long int readc, forwardc, writec; int exitstatus; if(!(shellpid=forkpty(&fd, NULL, NULL, NULL))){ execvp(argv[1], argv+1); } if (!(readpid=fork())){ readc = 1; forwardc = 1; while(readc>0 && forwardc>0) { readc=read(0, readbuf, 1024); if(readc>0) { forwardc = write(fd, readbuf, readc); } else { readbuf[0] = '\4'; forwardc = write(fd, readbuf, 1); } } close(0); close(fd); while(1) { sleep(1024);} } if (!(writepid=fork())){ writec = 1; forwardc = 1; while(writec>=0 && forwardc>0) { writec=read(fd, writebuf, 1024); if(writec>0) { do { forwardc = write(1, writebuf, writec); } while(forwardc==-1 && (errno == EAGAIN || errno == EWOULDBLOCK)); }else{ if(errno == EAGAIN || errno == EWOULDBLOCK){ writec = 0; } forwardc = 1; } } close(fd); close(1); exit(0); } signal(SIGTERM, &sigforward); signal(SIGINT, &sigforward); signal(SIGQUIT, &sigforward); signal(SIGHUP, &sigforward); signal(SIGPIPE, &sigforward); waitpid(shellpid, &exitstatus, 0); kill(readpid, SIGTERM); waitpid(readpid, NULL, 0); waitpid(writepid, NULL, 0); return WEXITSTATUS(exitstatus); }
int rlogind_mainloop (int infd, int outfd) { socklen_t size; struct auth_data auth_data; int true; char c; int authenticated; pid_t pid; int master; memset (&auth_data, 0, sizeof auth_data); size = sizeof auth_data.from; if (getpeername (infd, (struct sockaddr *) &auth_data.from, &size) < 0) { syslog (LOG_ERR, "Can't get peer name of remote host: %m"); fatal (outfd, "Can't get peer name of remote host", 1); } syslog (LOG_INFO, "Connect from %s:%d", inet_ntoa (auth_data.from.sin_addr), ntohs (auth_data.from.sin_port)); true = 1; if (keepalive && setsockopt (infd, SOL_SOCKET, SO_KEEPALIVE, &true, sizeof true) < 0) syslog (LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); #if defined (IP_TOS) && defined (IPPROTO_IP) && defined (IPTOS_LOWDELAY) true = IPTOS_LOWDELAY; if (setsockopt (infd, IPPROTO_IP, IP_TOS, (char *) &true, sizeof true) < 0) syslog (LOG_WARNING, "setsockopt (IP_TOS): %m"); #endif alarm (60); /* Wait at most 60 seconds. FIXME: configurable? */ /* Read the null byte */ if (read (infd, &c, 1) != 1 || c != 0) { syslog (LOG_CRIT, "protocol error: expected 0 byte"); exit (1); } alarm (0); authenticated = rlogind_auth (infd, &auth_data); pid = forkpty (&master, line, NULL, &win); if (pid < 0) { if (errno == ENOENT) { syslog (LOG_ERR, "Out of ptys"); fatal (infd, "Out of ptys", 0); } else { syslog (LOG_ERR, "forkpty: %m"); fatal (infd, "Forkpty", 1); } } if (pid == 0) { /* Child */ if (infd > 2) close (infd); setup_tty (0, &auth_data); setup_utmp (line); exec_login (authenticated, &auth_data); fatal (infd, "can't execute login", 1); } /* Parent */ true = 1; IF_NOT_ENCRYPT (ioctl (infd, FIONBIO, &true)); ioctl (master, FIONBIO, &true); ioctl (master, TIOCPKT, &true); netf = infd; /* Needed for cleanup() */ signal (SIGCHLD, cleanup); protocol (infd, master, &auth_data); signal (SIGCHLD, SIG_IGN); cleanup (0); #ifdef SHISHI if (kerberos) { int i; shishi_done (auth_data.h); # ifdef ENCRYPTION if (encrypt_io) { shishi_key_done (auth_data.enckey); for (i = 0; i < 2; i++) { shishi_crypto_close (auth_data.ivtab[i]->ctx); free (auth_data.ivtab[i]->iv); } } # endif } #endif return 0; }