(file) Return to main.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus_unsupported / utils / mash

File: [Pegasus] / pegasus_unsupported / utils / mash / main.cpp (download)
Revision: 1.2, Thu Jan 26 20:14:40 2006 UTC (18 years, 4 months ago) by mike
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +7 -1 lines
PEP#: 9999
TITLE: MASH Tool

DESCRIPTION: Fixed bug in MASH tool

#include <cstdio>
#include <cassert>
#include <cstring>
#include <fstream>
#include <cstdlib>
#include <unistd.h>
#include <vector>
#include <cctype>
#include <string>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;

const char* arg0;

void putline()
{
    for (size_t i = 0; i < 80; i++)
	putchar('*');
    putchar('\n');
}

void read_exclude_file(vector<string>& commands)
{
    // Get HOME environment variable:

    const char* home = getenv("HOME");

    if (!home)
    {
	fprintf(stderr, "%s: HOME environment variable is undefined\n", 
	    arg0);
	exit(1);
    }

    // Open the file:

    string path = string(home) + string("/.mashexclude");

    ifstream is(path.c_str());

    if (!is)
	return;

    // Read in the commands to be excluded:

    string line;

    while (getline(is, line))
    {
	// Trim trailing spaces:

	while (line.size() > 0 && isspace(line[line.size()-1]))
	    line.erase(line.size()-1, 1);

	commands.push_back(line);
    }
}

void print_cwd()
{
    char buffer[1024];
    getcwd(buffer, sizeof(buffer));
    printf("%s: CWD=%s\n", arg0, buffer);
}

int main(int argc, char** argv)
{
    arg0 = argv[0];

    FILE* log = fopen("/tmp/mash.log", "wb");

    for (size_t i = 0; i < argc; i++)
	fprintf(log, "arg: %s\n", argv[i]);

    // Check args.

    if (argc != 3 || strcmp(argv[1], "-c") != 0)
    {
	fprintf(stderr, "Usage: %s -c command\n", arg0);
	exit(1);
    }

    // Print command.

    fprintf(log, "%s: %s\n", arg0, argv[2]);

    // Extract command verb:

    const char* p = argv[2];

    while (*p && !isspace(*p))
	p++;

    string command(argv[2], p - argv[2]);

    // Exec system shell.

    argv[0] = "/bin/sh";

    int pid = fork();

    if (pid == 0)
    {
	execv("/bin/sh", argv);
	fprintf(stderr, "%s: failed to exec %s\n", arg0, argv[2]);
	exit(1);
    }
    else if (pid < 0)
    {
	fprintf(stderr, "%s: fork() failed\n", arg0, argv[2]);
	exit(1);
    }

    // Wait for child to exit:

    int status;

    if (waitpid(pid, &status, 0) != pid)
    {
	fprintf(stderr, "%s: waitpid() failed\n", arg0, argv[2]);
    }

    status = WEXITSTATUS(status);

    // Process failing command:

    if (status != 0)
    {
	// Don't process certain commands (return whatever they returned).

	vector<string> commands;
	read_exclude_file(commands);

	for (size_t i = 0; i < commands.size(); i++)
	{
	    if (commands[i] == command)
	    {
		printf("%s: excluded command: %s\n", arg0, argv[2]);
		return 1;
	    }
	}

	// Notify use of failure and ask whether to ignore or abort.

	putchar('\n');
	putline();
	printf("**\n");
	printf("** MASH (Make Shell)\n");
	printf("**\n");
	putline();
	putchar('\n');

	printf("%s: command failed: \"%s\"\n", arg0, argv[2]);
	print_cwd();
	putchar('\n');

	for (;;)
	{
	    printf("[i]gnore, [a]bort: ");

	    char buffer[1024];
	    scanf("%s", buffer);

	    if (buffer[0] == 'i')
		return 0;

	    if (buffer[0] == 'a')
		return 1;
	}
    }

    return status;
}

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2