2

I'm writing a basic postscript to retrieve some informations after the build of a an embedded project, but I'm facing issues with popen(), that won't change the working directory during code execution. The command string is the following, and works fine in prompt/terminal:

>cd C:/path_to_embedded_project_with_git/ && git rev-parse --short HEAD

But when I input the same string into my code and run it, I always get the head of the actual postscript project, not the targeted embedded project.

/**
  * @brief  Get GIT short identifier (first SHA digits)
  *
  * @param  char* git_repository_path
  *         uint8_t* git_short_sha
  * @retval int retval
  */
int i_Git_GetShortSHA( char* git_repository_path, uint8_t* git_short_sha ){

    git_str_buffer[1024] = {0};
    
    // b) Open the pipe to redirect the command output to a file
    FILE* pipe = NULL;
    if( (pipe = popen("cd C:/path_to_embedded_project_with_git/ && git rev-parse --short HEAD", "r")) == NULL ){
        PRINTFFFLUSH("[Git][ERROR] Cannot open pipe!" );
        return 0;
    }

    // c) Read till end of process:
    while (!feof(pipe)) {
        // use buffer to read and add to result
        fgets(git_str_buffer, 1024, pipe);
    }

    // d) Close the pipe, the process has ended
    pclose(pipe);

    // e) Copy the retrieved GIT SHA, always at the start of the buffered string
    memcpy(git_short_sha, git_str_buffer, GIT_SHORT_SHA_SIZE);
    return 1;
}

Thanks a lot, Raggio

I've also tried to create a dedicated .bat that collects:

cd C:/path_to_embedded_project_with_git/
git rev-parse --short HEAD

It agains runs well in prompt, giving out the short SHA of the pointed project, but still returns the SHA of the PostScript Project, when executed via popen()

RebRaggio
  • 21
  • 2
  • 1
    Not related to the problem, but see [Why `while(!feof(file))` is always wrong](https://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) – Barmar Aug 25 '23 at 22:15
  • you're overwriting the buffer each time through the `while` loop. So you're only copying the last line to `git_short_sha`. Could that be the problem? – Barmar Aug 25 '23 at 22:16
  • As i remember, in DOS working directory is disk-specific. I.e. if your current disk is `D:` and you run `cd C:\path`, you are still on disk `D:`. You have to change disk as well entering `C:`. – dimich Aug 25 '23 at 22:18
  • @dimich Why would it work for him when typing it in the command prompt window? – Barmar Aug 25 '23 at 22:20
  • 1
    What do you get if you execute `cd C:/path_to_embedded_project_with_git/ && pwd` – Barmar Aug 25 '23 at 22:20
  • @Barmar Maybe because command prompt is already on C: – dimich Aug 25 '23 at 22:20
  • 5
    I'm not sure why the shell in which `popen` is running your command seems not to honor the `cd`, but for your purpose it would be better in any case to use `git`'s `-C` option to specify the directory, rather than manipulating the working directory. – John Bollinger Aug 25 '23 at 22:24
  • @Barmar Thanks for the kind reply and the suggestion about using foef(): this code is just a quick demonstrator of the concept, but I'm sure I can learn! Regarding the overwriting of the git_str_buffer is intentional, as I am interested only in the first 7 character of the last line, that's the 7-digit shot SHA generated by GIT. – RebRaggio Aug 25 '23 at 22:24
  • 3
    However, since you're on Windows, perhaps your C library's `popen` is running your command with a Windows command interpreter (`cmd.exe`, for example) instead of with a POSIX shell. – John Bollinger Aug 25 '23 at 22:29
  • @Barmar under Win I have to use `cd C:/path_to_embedded_project_with_git/ && cd`, but I get `C:\\ path_to_embedded_project_with_git\n` – RebRaggio Aug 25 '23 at 22:31
  • @JohnBollinger I think that it's the command interpreter. I'll give a try to the git -C option! – RebRaggio Aug 25 '23 at 22:33
  • @JohnBollinger I've used `git -c rev-parse --short HEAD` but unfortunately I get `Access is Denied. Did I do something wrong? Thanks! – RebRaggio Aug 25 '23 at 22:42
  • You don't put `<>` around it. That's the file redirection operator. – Barmar Aug 25 '23 at 22:42
  • @Barmar Thanks a lot, now it works in prompt `git -C C:/path_to_embedded_project_with_git/ rev-parse --short HEAD`, but within the program it still output the PostBuild SHA! I'm actually using the same working command I put in prompt in a constant string that I pass to popen(). – RebRaggio Aug 25 '23 at 22:50
  • It is actually ignoring the path when called with popen(), I've tried putting a path to nowhere, it still outputs the PostBuild SHA. The only times it fails, it's when the path doesn't exits, in any other case it outputs the PostBuild SHA. – RebRaggio Aug 25 '23 at 22:56
  • Why not change your working directory before doing popen so you don't need a compound command? – stark Aug 26 '23 at 12:48
  • @stark thanks for the suggestion, do you think of doing that by calling a CD this system() before the popen() or other methods? To my understanding the system() or popen() commands live in a dedicated shell instance, generated by the command itself, and one is not effected by the other. But maybe I'm wrong. – RebRaggio Aug 26 '23 at 15:19
  • @JohnBollinger, @Barmar, I've tried the popen() command in a Linux Env and `git -C /home/path_to_embedded_project_with_git/ rev-parse --short HEAD` works, with the only requirement to add first the pointed path to the safe directories `sudo git config --global --add safe.directory /home/path_to_embedded_project_with_git/`. Unfortunately I really need for it to works in Windows – RebRaggio Aug 26 '23 at 15:38
  • See https://man7.org/linux/man-pages/man2/chdir.2.html – stark Aug 26 '23 at 16:01
  • @stark Unfortunately chdir is not available via MinGW in Windows – RebRaggio Aug 26 '23 at 16:12
  • 1
    On Mingw it may be in io.h or direct.h – stark Aug 26 '23 at 16:27
  • @stark At this point I think I'm stuck with an incomplete version of MiniGW, that I cannot change as it is part of the build pipeline of the embedded project. Anyway I have found a workaround by parsing the 2nd token of the last line of "/.git/logs/HEAD". It doesn't require any permission and it is very easy. It's really not the best, but it works fine. I really wold like to thank all of you. – RebRaggio Aug 26 '23 at 17:08
  • Are you sure the program you are running is actually built from the same version of the sources that you are working on? That an external command is involved makes this more difficult to troubleshoot, but it seems more and more likely that the behavior you observe is not attributable to the code you claim to be running. – John Bollinger Aug 26 '23 at 17:52

0 Answers0