<commit_before>/*
 * asynch.cpp
 *   Asynchronous communication
 *   ____            _
 *  |  _ \ ___  __ _| |_ __ ___  ___
 *  | |_) / _ \/ _` | | '_ ` _ \/ __|
 *  |  _ <  __/ (_| | | | | | | \__ \
 *  |_| \_\___|\__,_|_|_| |_| |_|___/
 *
 * Permission to use, modify and distribute is granted via the
 *  GNU Affero General Public License v3 or later
 *
 *  Copyright (C) 2007-2018 <NAME>, <NAME>
 *     Contributions by <NAME>, <NAME>
 *  Based on Mordor (C) <NAME>, <NAME>, <NAME>
 *
 */
#include "asynch.hpp"
#include "creatures.hpp"
#include "mud.hpp"
#include "server.hpp"
#include "socket.hpp"

//*********************************************************************
//                      Async
//*********************************************************************
// Sample code:
//
//  Async async;
//  if(async.branch(player, CHILD_PRINT) == AsyncExternal) {
//      bstring output = somethingArduous();
//      printf("%s", output.c_str());
//      exit(0);
//  } else {
//      player->print("Doing something long and arduous.\n");
//  }
//
// Responses to asychronous communication are handled in Server::reapChildren().
// Create your own CHILD_XYZ type if you want to perform special handling. The
// CHILD_PRINT type simply prints the response back to the player.

Async::Async() {
}

//*********************************************************************
//                      branch
//*********************************************************************

AsyncResult Async::branch(const Player* player, childType type) {
    bstring user = (player ? player->getName() : "Someone");
    if(pipe(fds) == -1) {
        std::clog << "Error with pipe!\n";
        abort();
    }

    int pid = fork();
    if(!pid) {
        // this is the child process
        // Close the reading end, we'll only be writing
        close(fds[0]);
        // Remap stdout to fds[1] so cout will print to fds[1] and we can
        // read it in from the mud
        if(dup2(fds[1], STDOUT_FILENO) != STDOUT_FILENO) {
            std::clog << "Error with dup2.\n";
            abort();
        }

        return(AsyncExternal);
    } else {
        // this is the parent process
        // Close the writing end, we'll only be reading
        close(fds[1]);
        nonBlock(fds[0]);

        std::clog << "Watching Child " << (int)type << " for (" << user << ") running with pid " << pid << " reading from fd " << fds[0] << ".";

        // Let the server know we're monitoring this child process
        gServer->addChild(pid, type, fds[0], user);

        return(AsyncLocal);
    }
}


//********************************************************************
//                      runList
//********************************************************************

int Server::runList(Socket* sock, cmd* cmnd) {
    Async async;
    if(async.branch(sock->getPlayer(), CHILD_LISTER) == AsyncExternal) {
        bstring lister = Path::UniqueRoom;
        lister += "List";
        std::clog << "Running <" << lister << ">\n";

        execl(lister.c_str(), lister.c_str(), cmnd->str[1], cmnd->str[2], cmnd->str[3], cmnd->str[4], nullptr);
        std::clog << "Error!";
<commit_msg>Point list to the right place<commit_after>/*
 * asynch.cpp
 *   Asynchronous communication
 *   ____            _
 *  |  _ \ ___  __ _| |_ __ ___  ___
 *  | |_) / _ \/ _` | | '_ ` _ \/ __|
 *  |  _ <  __/ (_| | | | | | | \__ \
 *  |_| \_\___|\__,_|_|_| |_| |_|___/
 *
 * Permission to use, modify and distribute is granted via the
 *  GNU Affero General Public License v3 or later
 *
 *  Copyright (C) 2007-2018 <NAME>, <NAME>
 *     Contributions by <NAME>, <NAME>
 *  Based on Mordor (C) <NAME>, <NAME>, <NAME>
 *
 */
#include "asynch.hpp"
#include "creatures.hpp"
#include "mud.hpp"
#include "server.hpp"
#include "socket.hpp"

//*********************************************************************
//                      Async
//*********************************************************************
// Sample code:
//
//  Async async;
//  if(async.branch(player, CHILD_PRINT) == AsyncExternal) {
//      bstring output = somethingArduous();
//      printf("%s", output.c_str());
//      exit(0);
//  } else {
//      player->print("Doing something long and arduous.\n");
//  }
//
// Responses to asychronous communication are handled in Server::reapChildren().
// Create your own CHILD_XYZ type if you want to perform special handling. The
// CHILD_PRINT type simply prints the response back to the player.

Async::Async() {
}

//*********************************************************************
//                      branch
//*********************************************************************

AsyncResult Async::branch(const Player* player, childType type) {
    bstring user = (player ? player->getName() : "Someone");
    if(pipe(fds) == -1) {
        std::clog << "Error with pipe!\n";
        abort();
    }

    int pid = fork();
    if(!pid) {
        // this is the child process
        // Close the reading end, we'll only be writing
        close(fds[0]);
        // Remap stdout to fds[1] so cout will print to fds[1] and we can
        // read it in from the mud
        if(dup2(fds[1], STDOUT_FILENO) != STDOUT_FILENO) {
            std::clog << "Error with dup2.\n";
            abort();
        }

        return(AsyncExternal);
    } else {
        // this is the parent process
        // Close the writing end, we'll only be reading
        close(fds[1]);
        nonBlock(fds[0]);

        std::clog << "Watching Child " << (int)type << " for (" << user << ") running with pid " << pid << " reading from fd " << fds[0] << ".";

        // Let the server know we're monitoring this child process
        gServer->addChild(pid, type, fds[0], user);

        return(AsyncLocal);
    }
}


//********************************************************************
//                      runList
//********************************************************************

int Server::runList(Socket* sock, cmd* cmnd) {
    Async async;
    if(async.branch(sock->getPlayer(), CHILD_LISTER) == AsyncExternal) {
        bstring lister = "/mud/List";
        std::clog << "Running <" << lister << ">\n";

        execl(lister.c_str(), lister.c_str(), cmnd->str[1], cmnd->str[2], cmnd->str[3], cmnd->str[4], nullptr);
        std::clog << "Error!";

{'fraction_non_alphanumeric': 0.27553107789142406, 'fraction_numerical': 0.007867820613690008, 'mean_word_length': 2.6340766152086905, 'pattern_counts': {'":': 0, '<': 81, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7274463', 'n_tokens_mistral': 1949, 'n_tokens_neox': 1849, 'n_words': 479}