为什么popen不与pog123沟通?

我正在为我的覆盆子pi写一个媒体服务器。 我能够创建一个程序,使用popen通过遥控器控制omxplayer。

我现在想控制mpg123音乐。 我使用与popen在omxplayer程序中工作的相同代码并将其应用于mpg123,但它无法正常工作。 它启动,但不会确认发送给它的任何输入。 我不知道为什么一个会工作而另一个不会。

这是我的代码:

void play_music (char *list, int random) { FILE *pp; char c; char command[501]; struct stat buf; if(access(list, R_OK) == -1) { fprintf(stderr, "%s: play_music: access failed (%s) (%s)\n", program_name, strerror(errno), list); exit(EXIT_FAILURE); } if(stat(list, &buf) == -1) { fprintf(stderr, "%s: play_music: stat failed (%s) (%s)\n", program_name, strerror(errno), list); exit(EXIT_FAILURE); } strcpy(command, "/usr/bin/mpg123 -C "); if(random == 1) strcat(command, "-z "); if(S_ISREG(buf.st_mode) == 1) { strcat(command, "-@ "); strcat(command, list); } else if(S_ISDIR(buf.st_mode) == 1) { strcat(command, list); if(list[strlen(list) - 1] != '*') { if(list[strlen(list) - 1] != '/') strcat(command, "/"); strcat(command, "*"); } } else { fprintf(stderr, "%s: play_music: stat reported unknown (%s)\n", program_name, list); exit(EXIT_FAILURE); } strcat(command, " > /dev/null 2>&1"); if((pp = popen(command, "w")) == NULL) { fprintf(stderr, "%s: play_music popen failed (%s)\n", program_name, strerror(errno)); exit(EXIT_FAILURE); } while((c = get_code())) { if(system("pidof mpg123 > /dev/null") != 0) return; switch(c) { case 31: fputc('f', pp); break; case 32: fputc('d', pp); break; case 33: fputc('s', pp); break; case 34: fputc('q', pp); } if(fflush(pp) == EOF) { fprintf(stderr, "%s: play_music fflush failed (%s)\n", program_name, strerror(errno)); exit(EXIT_FAILURE); } } } 

我一直试图解决这个问题太久了,有人可以帮忙!

笔记:

  • get_code()是一个工作函数,它根据按下的远程控制按钮返回一个int。

  • 变量’list’是目录路径或播放列表文件名。

  • 变量’random’是一个int标志(1表示随机播放)。

正如JF Sebastian在评论中所说的那样,“自己提供一个假tty”,结果certificate是我需要做的。 创建一个伪终端,就像来自键盘的输入一样,是需要工作的。

这是修改后的代码:

 void play_music (char *playlist, int random) { char c; int fdm; int fds = 0; int x = 0; pid_t pid; char *flag1 = "/usr/bin/mpg123"; char *flag2 = "-C"; char *flag3 = "-z"; char *flag4 = "-@"; char *flag5 = TEMP_FILE; // /tmp/temp_playlist.pls char *slave_name; char *argv[6]; struct stat buf; if(stat(playlist, &buf) == -1) { fprintf(stderr, "%s: play_music: stat failed (%s) (%s)\n", program_name, strerror(errno), playlist); exit(EXIT_FAILURE); } if((fdm = posix_openpt(O_RDWR)) == -1) { fprintf(stderr, "%s: posix_openpt failed (%s)\n", program_name, strerror(errno)); exit(EXIT_FAILURE); } if(grantpt(fdm) == -1) { fprintf(stderr, "%s: grantpt failed (%s)\n", program_name, strerror(errno)); close(fdm); exit(EXIT_FAILURE); } if(unlockpt(fdm) == -1) { fprintf(stderr, "%s: unlockpt failed (%s)\n", program_name, strerror(errno)); close(fdm); exit(EXIT_FAILURE); } if((slave_name = ptsname(fdm)) == NULL) { fprintf(stderr, "%s: ptsname failed\n", program_name); close(fdm); exit(EXIT_FAILURE); } if((pid = fork()) == -1) { fprintf(stderr, "%s: fork failed (%s)\n", program_name, strerror(errno)); close(fdm); exit(EXIT_FAILURE); } if(pid == 0) // Child { if(setsid() == -1) { fprintf(stderr, "%s: setsid failed (%s)\n", program_name, strerror(errno)); close(fdm); exit(EXIT_FAILURE); } if((fds = open(slave_name, O_RDWR)) == -1) { fprintf(stderr, "%s: open failed (%s)\n", program_name, strerror(errno)); close(fdm); exit(EXIT_FAILURE); } if(dup2(fds, STDIN_FILENO) == -1) { fprintf(stderr, "%s: dup2(1) failed (%s)\n", program_name, strerror(errno)); close(fdm); close(fds); exit(EXIT_FAILURE); } if(dup2(fds, STDOUT_FILENO) == -1) { fprintf(stderr, "%s: dup2(2) failed (%s)\n", program_name, strerror(errno)); close(fdm); close(fds); exit(EXIT_FAILURE); } if(dup2(fds, STDERR_FILENO) == -1) { fprintf(stderr, "%s: dup2(3) failed (%s)\n", program_name, strerror(errno)); close(fdm); close(fds); exit(EXIT_FAILURE); } argv[x++] = flag1; argv[x++] = flag2; if(random == 1) argv[x++] = flag3; argv[x++] = flag4; if(S_ISREG(buf.st_mode) == 1) argv[x++] = playlist; else if(S_ISDIR(buf.st_mode) == 1) { if(make_playlist(playlist) == RETURN_FAILURE) { fprintf(stderr, "%s: play_music: make_playlist failed (%s)\n", program_name, playlist); close(fdm); close(fds); exit(EXIT_FAILURE); } argv[x++] = flag5; } else { fprintf(stderr, "%s: play_music: stat reported unknown (%s)\n", program_name, playlist); close(fdm); close(fds); exit(EXIT_FAILURE); } argv[x++] = NULL; if(execv("/usr/bin/mpg123", argv) == -1) { fprintf(stderr, "%s: execv failed (%s)\n", program_name, strerror(errno)); close(fdm); close(fds); exit(EXIT_FAILURE); } } else // Parent { while((c = get_code()) != 31) { switch(c) { case 30: case 19: write(fdm, " ", 1); break; case 20: // Up write(fdm, "+", 1); break; case 22: // Down write(fdm, "-", 1); break; case 21: // Right write(fdm, "f", 1); break; case 23: // Left write(fdm, "d", 1); break; } } write(fdm, "q", 1); wait(&pid); close(fdm); if(fds != 0) close(fds); } }