gpt4 book ai didi

c - 为什么我不能在busybox中用 '\t'模拟自动补全

转载 作者:太空宇宙 更新时间:2023-11-04 12:01:37 25 4
gpt4 key购买 nike

我想利用 busybox 中的自动完成功能,使用“yp\t\n\0”来运行“ypdomainname”命令,但它失败了。我的代码和结果如下:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <fcntl.h>

#define DEFAULT_BUSYBOX_PATH "/bin/busybox"
#define MAX_BUF 1000

int main()
{
int fd[2];
pid_t pid;
FILE *file;
int status;

if(pipe(fd) < 0){
fprintf(stderr, "pipe error!\n");
return -1;
}

if((pid = fork()) < 0){
fprintf(stderr, "pipe error!\n");
}else if(pid == 0){ //child
close(fd[1]);

int fd_output;
fd_output = open("result", O_CREAT | O_RDWR, 777);

if(fd_output != STDOUT_FILENO){
if(dup2(fd_output, STDOUT_FILENO) != STDOUT_FILENO)
fprintf(stderr, "dup2 error to stdout\n");
}

if(fd[0] != STDIN_FILENO){
if(dup2(fd[0], STDIN_FILENO) != STDIN_FILENO)
fprintf(stderr, "dup2 error to stdin\n");
}
execl(DEFAULT_BUSYBOX_PATH, DEFAULT_BUSYBOX_PATH, "ash", NULL);
close(fd[0]);
close(fd_output);
return 0;
}else{ //parent
close(fd[0]);

char buf[MAX_BUF] = "yp";
buf[2] = '\t';
buf[3] = '\n';
buf[4] = '\0';

write(fd[1], buf, strlen(buf));

close(fd[1]);
return 0;
}

}

Result of my code

让我感到困惑的是,文件 lineedit.c 中的函数 lineedit_read_key() 中的字符没有更改,当字符出现时它将运行函数 input_tab()是'\t'。 input_tab will be executed when character is '\t'

最近花时间学习了终端模拟自动补全,还是失败了。我的代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <signal.h>
#include <pty.h>

#define DEFAULT_BUSYBOX_PATH "/bin/busybox"
#define MAX_BUF 1000
#define BUFFSIZE 512

typedef void Sigfunc(int);

static void sig_term(int);
static volatile sig_atomic_t sigcaught;

ssize_t writen(int fd, const void *ptr, size_t n){
size_t nleft;
ssize_t nwritten;

nleft = n;
while(nleft > 0){
if((nwritten = write(fd, ptr, nleft)) < 0){
if(nleft == n){
return(-1);
}else{
break;
}
}else if(nwritten == 0) {
break;
}
nleft -= nwritten;
ptr += nwritten;
}
return(n - nleft);
}

Sigfunc *signal_intr(int signo, Sigfunc *func){
struct sigaction act;
struct sigaction oact;

act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
#ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT;
#endif
if (sigaction(signo, &act, &oact) < 0)
return(SIG_ERR);
return(oact.sa_handler);
}

int ptym_open(char *pts_name, int pts_namesz)
{
char ptr[50];
int fdm;
int err;

if((fdm = posix_openpt(O_RDWR)) < 0){
return(-1);
}
if(grantpt(fdm) < 0){
goto errout;
}
if(unlockpt(fdm) < 0){
goto errout;
}

if(ptsname_r(fdm, ptr, 50) != 0){
goto errout;
}

strncpy(pts_name, ptr, pts_namesz);
pts_name[pts_namesz - 1] = '\0';
return(fdm); /* return fd of master */
errout:
err = errno;
close(fdm);
errno = err;
return(-1);
}

int ptys_open(char *pts_name){
int fds;

if((fds = open(pts_name, O_RDWR)) < 0)
return(-1);

return(fds);
}

pid_t pty_fork(int *ptrfdm, char *slave_name, int slave_namesz, const struct termios *slave_termios, const struct winsize *slave_winsize){
int fdm, fds;
pid_t pid;
char pts_name[20];

if((fdm = ptym_open(pts_name, sizeof(pts_name))) < 0){
fprintf(stderr, "can't open master pty: %s, error %d", pts_name, fdm);
}

if(slave_name != NULL) {
strncpy(slave_name, pts_name, slave_namesz);
slave_name[slave_namesz - 1] = '\0';
}

if((pid = fork()) < 0) {
return(-1);
}else if (pid == 0) { /* child */
if(setsid() < 0){
fprintf(stderr, "setsid error");
}

if((fds = ptys_open(pts_name)) < 0){
fprintf(stderr, "can't open slave pty");
}
close(fdm);

if(slave_termios != NULL) {
if (tcsetattr(fds, TCSANOW, slave_termios) < 0)
fprintf(stderr, "tcsetattr error on slave pty");
}
if(slave_winsize != NULL) {
if (ioctl(fds, TIOCSWINSZ, slave_winsize) < 0)
fprintf(stderr, "TIOCSWINSZ error on slave pty");
}

if(dup2(fds, STDIN_FILENO) != STDIN_FILENO){
fprintf(stderr, "dup2 error to stdin");
}
if(dup2(fds, STDOUT_FILENO) != STDOUT_FILENO){
fprintf(stderr, "dup2 error to stdout");
}
if(dup2(fds, STDERR_FILENO) != STDERR_FILENO){
fprintf(stderr, "dup2 error to stderr");
}
if(fds != STDIN_FILENO && fds != STDOUT_FILENO && fds != STDERR_FILENO){
close(fds);
}
return(0);
} else { /* parent */
*ptrfdm = fdm;
return(pid);
}
}

void loop(int ptym, int ignoreeof)
{
pid_t child;
int nread;
char buf[BUFFSIZE];

if((child = fork()) < 0) {
fprintf(stderr, "fork error");
}else if(child == 0) {
/*for ( ; ; ){
if((nread = read(STDIN_FILENO, buf, BUFFSIZE)) < 0){
fprintf(stderr, "read error from stdin");
}else if(nread == 0){
break;
}

if(writen(ptym, buf, nread) != nread)
fprintf(stderr, "writen error to master pty");
}*/
char *temp_buf = "yp\t\n";
if(writen(ptym, temp_buf, strlen(temp_buf)) != strlen(temp_buf)){
fprintf(stderr, "writen error to master pty");
}

if(ignoreeof == 0){
kill(getppid(), SIGTERM);
}

exit(0);
}

if (signal_intr(SIGTERM, sig_term) == SIG_ERR)
fprintf(stderr, "signal_intr error for SIGTERM");

for( ; ; ){
if ((nread = read(ptym, buf, BUFFSIZE)) <= 0){

}
//printf("nread = %d\n", nread);
if (writen(STDOUT_FILENO, buf, nread) != nread){
fprintf(stderr, "writen error to stdout");
}
}

if (sigcaught == 0){
printf("sigcaught == 0 and kill child\n");
kill(child, SIGTERM);
}
}

static void sig_term(int signo)
{
sigcaught = 1;
}

int main(int argc, char *argv[]){
int fd[2];
pid_t pid;
FILE *file;
int status;
int fdm;
int ignoreeof;
char slave_name[40];
struct termios orig_termios;
struct winsize size;

pid = pty_fork(&fdm, slave_name, sizeof(slave_name), &orig_termios, &size);
if(pid < 0){
fprintf(stderr, "fork error!\n");
}else if(pid == 0){ //child
if(execl(DEFAULT_BUSYBOX_PATH, DEFAULT_BUSYBOX_PATH, "ash", NULL) < 0){
fprintf(stderr, "can't execute: %s", DEFAULT_BUSYBOX_PATH);
}
/*if(execvp(argv[1], &argv[1]) < 0){
fprintf(stderr, "can't execute: %s", argv[1]);
}*/
}

loop(fdm, ignoreeof);
}

像我第一次尝试的结果,结果是:ash: yp: not found。

最佳答案

您的代码失败,因为管道不是终端。许多程序会使用 isatty(3)以及检测标准输入是否连接到终端并根据结果调整它们的行为。

您可以做的是使用openpty(3) 打开一个伪终端对。并使用复制到其标准输入、输出和错误描述符的从站运行命令,并使用主站与其通信。不幸的是,我现在没有时间写一个完整的解决方案,因为它相当复杂;我曾经用 Python 做过,即使在那里也很棘手。

关于c - 为什么我不能在busybox中用 '\t'模拟自动补全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52186394/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com