1

I am writing a C program that should able to take and run command prompt commands and then spit out the output to stdout. This is easy enough, as all it takes is system("dir") which works perfectly and does what you would think it does.

The problem is that I would like this cmd session to be persistent. What does not work but I would like to be able to do is

system("cd ..");
system("dir");

to print the contents of the parent directory. This does not work it seems because the cmd session between the cd call and dir call is not the same, and the cd has no effect on the working directory when we call dir.

Ideally I would like to be able to create a cmd process where I could run commands in it, do other stuff in the program, then continue to run commands and have it be the same cmd process the whole time until I manually close it.

How would I accomplish this?

Edit: This is supposed to run on Windows.

Ribs30
  • 13
  • 3
  • Is this meant to run under Windows? – Jeremy Friesner Jul 14 '22 at 01:40
  • Basically sounds like you are wanting to implement a shell. In general that means you need to parse the input and convert those to lower level function calls such as `fork` and `chdir` (posix specific) when needed. Commands like `dir` can be called via `system` if you really want as it has no state. – kaylum Jul 14 '22 at 01:43
  • I should have specified. This is meant to run under Windows. Because of this I do not believe their is a fork() function that I can use. – Ribs30 Jul 14 '22 at 01:56
  • That's just an example. You would use whatever OS APIs are available on your system, e.g CreateProcess. – kaylum Jul 14 '22 at 01:59
  • I've looked into CreateProcess a bit, but I can't seem to find a way to make it persistent. The top answer to this question (https://stackoverflow.com/questions/27474289/run-persistent-command-prompt-commands) may lead to the answer, but that is for C++ and I am coding in C. – Ribs30 Jul 14 '22 at 02:03
  • To "persist" the results of the commands you need to call functions in the same process instead of calling `system` which creates a new process and does the work in that process. For example, instead of `system("cd ..")` you would call `SetCurrentDirectory`. – kaylum Jul 14 '22 at 02:18

1 Answers1

0

Each process has its own current directory, so the shell launched by system changes its current directory, but this has no effect on the calling process nor after the shell exits. The simplest way to achieve your goal is to parse certain commands and execute them locally:

#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int run_cmd(char *cmd) {
    int len;
    cmd += strspn(cmd, " \t");
    len = strlen(cmd);
    while (len > 0 && isspace((unsigned char)cmd[len - 1]))
        cmd[--len] = '\0';
    len = strcspn(cmd, " \t");
    if (len == 2 && !strncmp(cmd, "cd")) {
        char *arg = cmd + 2;
        arg += strspn(arg, " \t");
        int arglen = strcspn(arg, " \t");      
        if (arglen > 0) {
            arg[arglen] = '\0';
            if (chdir(arg)) {
                fprintf(stderr, "cd: %s: %s\n", arg, strerror(errno));
                return 1;
            }
            return 0;
        }
    }
    if (!*cmd || *cmd == '#') // ignore comment and empty lines
        return 0;
    return system(cmd);
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189