最常见于使用SecureCRT等工具远程创建打开终端,下面的代码演示在代码中创建打开终端:
- // filename: term.cpp
- // g++ -g -o term term.cpp -lutil
- // login_tty()等在-lutil中
- #include fcntl.h>
- #include pty.h> // openpty and forkpty
- #include signal.h>
- #include stdio.h>
- #include stdlib.h>
- #include string.h>
- #include stropts.h> // ioctl
- #include sys/prctl.h> // prctl
- #include unistd.h>
- #include utmp.h> // login_tty
-
- static void on_signal(int signo)
- {
- printf("[%d]signal: %s\n", getpid(), strsignal(signo));
- }
-
- int main()
- {
- int amaster = 0;
- char name[100];
- struct termios termp; // termios.h (bits/termios.h)
- struct winsize winp; // term.h(bits/ioctl-types.h)
-
- // forkpty的实现调用了openpty()、fork()和login_tty()
- pid_t pid = forkpty(&amaster, name, &termp, &winp);
- if (pid 0)
- {
- perror("forkpty");
- exit(1);
- }
- else if (0 == pid)
- {
- // 子进程隶属于新的终端
- // 子进程中的printf()在父进程隶属的终端上看不见
-
- // 父进程被中断或挂掉时,会向子进程发送SIGHUP
- signal(SIGHUP, on_signal);
- printf("child: %d\n", getpid());
-
- while (true)
- {
- sleep(1);
- }
-
- exit(0);
- }
- else if (pid > 0)
- {
- // 父进程仍然使用之前的终端
- // 如果中断会向了进程发送SIGHUP
-
- printf("pid: %d/%d\n", getpid(), pid);
- printf("name: %s\n", name);
- printf("amaster: %d\n", amaster);
- printf("win.row: %d\n", winp.ws_row);
- printf("win.col: %d\n", winp.ws_col);
- printf("win.xpixel: %d\n", winp.ws_xpixel);
- printf("win.ypixel: %d\n", winp.ws_ypixel);
-
- getchar();
- }
-
- return 0;
- }