1

I'm tasked with creating a popen() function using Pipes, which I have already completed. The catch is that the function must ALSO be named popen, not mypopen or popen2 etc.

I'm looking for someone to guide me in the right direction as to how I can accomplish this.

Currently I have a header file popen.h and another filed popen.c that I have created.

popen.h just has

void popen(char *arr[]);

While popen.c has the actual popen function code (Which works, just not when the function name is popen).

Currently I'm getting a previous declaration error upon compilation when my function is called popen.

How can I let the compiler choose between the two different popen functions, mine and stdio.h version.

rod-emerson
  • 113
  • 1
  • 4
  • the name is the same, then how about the parameters? Are they the same too? – tcf01 Mar 22 '20 at 02:13
  • no, the parameters are not the same between the two popens –  Mar 22 '20 at 02:14
  • If you code in C++, you can overload function names; if you code in C, you can't. You should probably write your `popen()` with the same interface as the (POSIX) standard [`popen()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/popen.html) (and write [`pclose()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pclose.html) too). You can then probably get away with using your code instead of the system provided code. The standards (C and POSIX) don't guarantee that you will (and imply that you won't), but you probably will. – Jonathan Leffler Mar 22 '20 at 02:15
  • If you don't conform to the standard interface, you will be unable to use standard headers (such as ``) with your code — which is making life extremely complicated for yourself. If the interface is different, use a different name. You'll confuse everyone if you don't. – Jonathan Leffler Mar 22 '20 at 02:16
  • From the best of my knowledge,this feature is called overloading, I have found [this](https://stackoverflow.com/questions/479207/how-to-achieve-function-overloading-in-c). Hope it helps. – tcf01 Mar 22 '20 at 02:18
  • *why* must the function name be the same? – Joshua Yonathan Mar 22 '20 at 03:08
  • @JonathanLeffler Your solution worked, I just had to change my driver program a little to make my popen work with the same interface as the POSIX standard. Thanks –  Mar 22 '20 at 04:00

2 Answers2

2

Just #define popen my_popen before declaring, defining and using your function, but after including <stdio.h>.

popen.h

#define popen   my_popen
void popen(char *arr[]);

popen.c

#include <stdio.h>
#include "popen.h"
void popen(char *arr[]){ printf("that's NOT the stdio's popen\n"); }

main.c

#include <stdio.h>
#include "popen.h"
int main(void){
        popen(0); printf("done\n");
}

Similarly, you can hide the stdio's popen by defining popen to stdio_popen before including <stdio.h> and undefining it afterwards, if you really want to have a symbol named popen:

#define popen   stdio_popen
#include <stdio.h>
#undef popen

void popen(char *arr[]){ printf("that's NOT the stdio's popen\n"); }

int main(void){
        popen(0); printf("done\n");
}
$ nm a.out | grep popen
0000000000001160 T popen

Such nasty tricks are only useful when having to combine ornery source codes which pollute each other's namespace. There's zero reason to name a function you just wrote popen() and not something else, unless it's a drop-in replacement, with the same interface as the standard one.

  • This totally works, and Is useful information as I did not know you could do this (Still in university for comp sci). I changed my popen to have the same arguments as stdio.h version of popen, and it worked fine after that, just required me to change some of my driver program. –  Mar 22 '20 at 03:59
  • 1
    The second proposal is likely to create linking issues as the local popen symbol will have the same name as some external symbol from system librairies. That can be managed but is indeed dirty. – kriss Mar 23 '20 at 00:20
1

If you want to have popen safely you must also make sure that you aren’t using <stdio.h>as this is where the normal popen is located, and your linker will not like it if there are two identical symbols named popen.

Plasma_000
  • 21
  • 3