1

I'm writing a program that speeds up the git push operation. Here's what it needs to do:

printf("[github-username]\n[github-password]");

I'd then use it like so:

git-autologin | git push

But I don't want there to be any chance of someone simply typing git-autologin or git-autologin > file.txt and being able to see my username and password. I know it sounds silly 'cause anyone can still automate the git commands but it's unlikely that any untrusted user will ever get on my system.

My question: How could I tell if standard output is writing to a file/terminal or if it's being piped?
Edit: The git push pipe was simply an idea, not the only reason I'm asking.
Edit: Is there any way to determine the PID or more information about the process it's being piped to?

MD XF
  • 7,860
  • 7
  • 40
  • 71
  • BTW if the 'git' tag needs to be removed please feel free to remove it, or comment. – MD XF Oct 30 '16 at 02:04
  • 3
    For this particular solution you may want to read up on [git credentials helpers](https://git-scm.com/docs/gitcredentials). Actually, you would better off just using an ssh key for authentication, rather than a username/password. – larsks Oct 30 '16 at 02:04
  • @larsks Thanks, I'll look into that but this isn't the only reason I'm asking, just the most explainable one – MD XF Oct 30 '16 at 02:06
  • 1
    [This](http://stackoverflow.com/questions/911168/how-to-detect-if-my-shell-script-is-running-through-a-pipe) isn't exactly a duplicate, because it's shell rather than C, but I think it provides the general answer (which is, you can't really do what you want). – larsks Oct 30 '16 at 02:08
  • 5
    `git-autologin | cat`. Now what. – that other guy Oct 30 '16 at 02:12
  • 2
    You can't seek on a pipe or terminal; you can on files. You can tell if a device is a terminal by looking at the type information (`stat()` on the output file descriptor and `S_ISCHR` macro, or maybe check for `S_ISREG`); if it looks looks like a regular file, (`S_ISREG`), but you can't seek on it (`errno == ESPIPE` after an attempt to seek), it is probably a pipe. You can't tell if the command on the receiving end is `cat` very easily, though. – Jonathan Leffler Oct 30 '16 at 02:21
  • 1
    This is silly. All someone has to do is run `strings git-autologin` and they'll see your credentials. – Barmar Oct 30 '16 at 02:36
  • 3
    The literal answer is the `isatty` function (this is what libc uses internally to choose stdout buffering), but as already noted, `git-autologin | cat` makes this a bad idea. – torek Oct 30 '16 at 02:46

1 Answers1

4

You can detect when stdout is a terminal by using (on Linux & POSIX!) the isatty(3) function, probably as isatty(STDOUT_FILENO)

So you could guess that if isatty(STDOUT_FILENO) is false, the standard output is would be redirected or piped.

Alternatively, use fstat(2) as fstat(STDOUT_FILENO, &stdoutstat);

But you should set up ssh correctly (with credentials, STFW for any SSH tutorial!) on your system, to avoid having git asking any password.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547