Você está deixando um zumbi, de forma trivial, porque não usou wait no seu processo filho.
Seu shell está saindo imediatamente porque você configurou seu STDIN de maneira absurda. pipe retorna um canal de comunicação unidirecional. Você write to pipefd[1] e read de pipefd[0] . Você fez um buch de dup2 chamadas que levam o shell a tentar ler (STDIN) a partir da extremidade de gravação do pipe.
Depois de trocar os números em seu enum, você obtém o shell para sempre em read . Isso provavelmente não é o que você quer, mas é tudo o que você pode esperar quando você tem um shell canalizado para si mesmo.
Supondo que você esteja tentando usar o shell a partir do seu processo pai, você precisa chamar pipe duas vezes (e ambos no pai): um dos pipes que você escreve (e o shell lê, no stdin) e o outro o shell escreve para (stdout / stderr) e você lê. Ou se você quiser, use socketpair .