I have an application where I need to write a new getpid function to replace the original one of the OS. The implementation would be similar to:
pid_t getpid(void)
{
if (gi_PID != -1)
{
return gi_PID;
}
else
{
// OS level getpid() function
}
}
How can I call the original getpid() implementation of the OS through this function?
EDIT: I tried:
pid_t getpid(void)
{
if (gi_PID != -1)
{
return gi_PID;
}
else
{
return _getpid();
}
}
as Jonathan has suggested. This gave me the following errors when compiling with g++:
In function pid_t getpid()':
SerendibPlugin.cpp:882: error:
_getpid' undeclared (first use this
function) SerendibPlugin.cpp:882:
error: (Each undeclared identifier is
reported only once for each function
it appears in.)
EDIT 2: I've managed to get this to work by using a function pointer and setting it to the next second symbol with the id "getpid", using dlsym(RTLD_NEXT, "getpid").
Here's my sample code:
vi xx.c
"xx.c" 23 lines, 425 characters
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <iostream>
#include <dlfcn.h>
using namespace std;
pid_t(*___getpid)();
pid_t getpid(void)
{
cout << "My getpid" << endl;
cout << "PID :" << (*___getpid)() << endl;
return (*___getpid)();
}
int main(void)
{
___getpid = (pid_t(*)())dlsym(RTLD_NEXT, "getpid");
pid_t p1 = getpid();
printf("%d \n", (int)p1);
return(0);
}
g++ xx.c -o xout
My getpid
PID :7802
7802
On many systems, you will find that getpid() is a 'weak symbol' for _getpid(), which can be called in lieu of getpid().
The first version of the answer mentioned __getpid(); the mention was removed swiftly since it was erroneous.
This code works for me on Solaris 10 (SPARC) - with a C++ compiler:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
extern "C" pid_t _getpid();
pid_t getpid(void)
{
return(-1);
}
int main(void)
{
pid_t p1 = getpid();
pid_t p2 = _getpid();
printf("%d vs %d\n", (int)p1, (int)p2);
return(0);
}
This code works for me on Solaris 10 (SPARC) - with a C compiler:
Black JL: cat xx.c
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
pid_t getpid(void)
{
return(-1);
}
int main(void)
{
pid_t p1 = getpid();
pid_t p2 = _getpid();
printf("%d vs %d\n", (int)p1, (int)p2);
return(0);
}
Black JL: make xx && ./xx
cc xx.c -o xx
"xx.c", line 13: warning: implicit function declaration: _getpid
-1 vs 29808
Black JL:
You can use a macro:
in a .h, included in every file where you want to replace the getpid function
#define getpid() mygetpid()
Then, put your own implementation in a .cpp
pid_t mygetpid() {
// do what you want
return (getpid)();
}
You're using the terminology a bit incorrectly. It's not possible to override getpid() because it's not a virtual function. All you can do is attempt to replace getpid with a different function by various evil means.
But I must ask, why are you doing this? Replacing getpid means that any component which was depending on the return of getpid will now be receiving you're presumably modified result. This change has a very high risk of changing some other component.
What you're offering is a new functionality and hence should be a different function.
That being said if you truly want to take this approach the best way is to dynamic loading of the function. The original DLL will still contain the getpid function and you can access that via a combination of LoadLibrary/GetProcAddress on Windows or dlopen/dlsym on Linux. If you're using a different OS please specify.
EDIT Responding to comments that getpid needs to be testable
If testing is the concern then why not instead have a custom getpid method for you're application. For example, applicationGetPid(). For normal execution this could be forwarded off to the system getpid function. But during Unit Testing it could be used to produce more predictable values.
pid_t applicationGetPid() {
#if UNIT_TEST
return SomeCodeForUnitTests;
#else
return getpid();
#endif
}
Related
I use chdir() to switch the directory, and then use execvp() to execute "java Main". I'm sure there is Main.class, but something went wrong. I want to know why.
#include <cstdio>
#include <unistd.h>
using namespace std;
int main(){
char buf[80];
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
chdir("/home/keane/Judge/temp");
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
char *array[3];
array[0] = "java";
array[1] = "Main";
array[2] = NULL;
execvp("java", array);
return 0;
}
the error is could not find the main class , and I can run java Main in that directory.
What drives me crazy is that I can't use system("java Main"), and the error is that Error: Could not find or load main class Main, and it's just like this on my computer
update:
#include <unistd.h>
#include <cstdlib>
int main(){
chdir("/home/keane/Judge/temp");
system("pwd");
system("ls");
system("java Main");
return 0;
}
the output on console is:
/home/keane/Judge/temp
1.out 3.out 5.out Main.class stdout_spj.txt
2.out 4.out ce.txt Main.java
Error: Could not find or load the main class Main
my final solution is to reboot the computer and add -cp . to the java command.
althought I don't why is necessary.
thanks everyone!
This works as intended on my system, maybe you need to add -cp . to your java call.
EDIT: to elaborate: -cp (for classpath) tells java where to look for user provided .class files. This does not necessarily include the current working directory by default.
The execution of execvp() is non-blocking and takes ownership of the caller, that means that when it starts if the program ends too quickly you will never be able to see the result, to solve this I use fork(). The wait is just to avoid using sleep as I used at the begining. Its all in c.
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char** argv){
char buf[80];
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
chdir("/home/");
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
char *array[3] = {"java", "Main", NULL};
if(fork() == 0) {
if(execvp("java", array) < 0) {
fprintf(stderr, "Error spawning command: %s\n", strerror(errno));
}
} else {
printf("Command spawned\n");
wait(NULL); // Wait to the forked process to end (avoid using sleep)
}
return 0;
}
I have a small program that loads 2 modules (X11, and my own):
#include <fcntl.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
int main(int c, char* argv[])
{
pid_t PID = c > 1 ? atoi(argv[1]) : -1;
if (PID <= 0)
{
fprintf(stderr, "Invalid PID\n");
return -1;
}
const char* path = "/home/brandon/Desktop/mylib.so";
void* x11 = dlmopen(LM_ID_NEWLM, "libX11.so.6", RTLD_NOW);
/*Lmid_t id = 0;
dlinfo(dl, RTLD_DI_LMID, &id);
dl = dlmopen(id, path, RTLD_LAZY);*/
void* dl = dlopen(path, RTLD_LAZY);
if (dl)
{
printf("Loading dll\n");
void (*ptrace_info)(pid_t pid) = (decltype(ptrace_info))dlsym(dl, "ptrace_info");
if (ptrace_info)
{
ptrace_info(PID);
}
dlclose(dl);
printf("Unloaded\n");
}
return 0;
}
If I use dlopen(path, RTLD_*) my module fails to ptrace the specified pid. However, if I uncommented the code above that uses dlmopen everything works fine (even if I create a new namespace, it works)..
If I do not dlmopen(.., X11, ..), it works fine. The only time it does NOT work is if I dlmopen anything and then try to dlopen something else.
Seeing as the only difference is the namespace, is there a way I can use dlopen after using dlmopen?
I am doing a cross compilation test in Eclipse IDE for meta-toolchain made with Yocto, for arm cortex A9 processor. After performing hello world test, which ran successfully, I created a basic program to test pthreads.
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <pthread.h>
#define MILLION 1000000 /* one million = 10^6*/
#define sec_to_nsec 1000000000 /* ns to s conversion = 10^9 */
#define FILENAME "Schd.txt"
#define FLUSH_TIME 10.0
#define SIG_LLP_TIMER SIGRTMIN+1
int isr_idx; /* counter of ISR occurred -- starts from 0 and increments at each interrupt*/
volatile float clk_k, /* MY_CLOCK() value for the current sample*/
clk_k_1; /* MY_CLOCK() value for the previous sample*/
/*clock and timer values*/
struct itimerspec custom_itimerspec;
timer_t timer_id;
clockid_t USED_CLK;
struct timespec tv;
float a_n;
/*THREAD DATA*/
pthread_t thread0;
pthread_attr_t attr;
struct sched_param param;
using namespace std;
void* thread_scheduler(){
//function pointer
//mainThread
//make thread for scheduling
//exit after max cycle
}
int main(void)
{
cout << "Starting the program!" << endl; /* prints Hello World */
cout<< "Creating a Thread to deploy" << endl;
int status;
param.__sched_priority = 99;
int retc;
/*PTHREAD ATTR setup*/
retc = pthread_attr_init(&attr);
retc |= pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
retc |= pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
retc |= pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
retc |= pthread_attr_setschedparam(&attr,¶m);
if (retc != 0) {
//fail
while(1){}
}
retc = pthread_create(&thread0, &attr, (void * (*)(void *))thread_scheduler, NULL);
printf("Exiting here!");
return 0;
}
But I get this error, undefined reference to `pthread_create', followed with some make errors.
Though after doing some search I found that adding '-pthread' command in configure and autogen settings works for building the project, as described here. But I am puzzled why the compiler can't see these files even if this file is present in 'includes' in the drop down folder of project explorer.
The error about undefined reference is coming from linking step, not from compiling and assembling step, compile step would look for header files and its rightly finding the pthread.h from sysroot include directory as you see as well. After compiling, it has to invoke the linker to create the executable binary and thats where it fails.
When linking it need to add libpthread to linker commandline so linker can find the pthread_create function and link it into final executable, this is usually done via specifying LDFLAGS which then get appended to linker invocation.
compiler driver ( gcc ) can be used to drive both compiling and linking steps.
so when you add -pthread option to compiler and compiler is also used to perform linking then it translates this option into -lpthread to linker cmdline which would then find libpthread and link it in.
All, the first part of my homework assignment is simply a demo program that I need to compile, and then modify. It was provided by the teacher, however I simply cannot get it to compile using g++. I will be creating a make file at the end of the assignment, but for the moment I am simply trying to test it out, and am having no luck. I've tried the most basic g++ command: g++ -o main TwoPipesTwoChildren.cpp . Can someone please help? I can't even get started on this until I can get this working.
// description: This program will execute "ls -ltr | grep 3376"
// by using a parent and child process
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char **argv){
printf("TEST");
int status;
int childpid;
char *cat_args[] = {"ls", "-ltr", NULL};
char *grep_args[] = {"grep", "3376", NULL};
// create one pipe to send the output of "ls" process to "grep" process
int pipes[2];
pipe(pipes);
// fork the first child (to execute cat)
if((childpid = fork()) == -1)
{
perror("Error creating a child process");
exit(1);
}
// replace cat's stdout with write part of 1st pipe
if (childpid == 0)
{
dup2(pipes[1], 1);
printf("AFTER FORK CHILD");
//close all pipes (very important!); end we're using was safely copied
close(pipes[0]);
close(pipes[1]);
execvp(*cat_args, cat_args);
exit(0);
}
else
{
// replace grep's stdin with read end of 1st pipe
dup2(pipes[0], 0);
close(pipes[0]);
close(pipes[1]);
execvp(*grep_args, grep_args);
}
return (0);
}
I am trying to print the path of the current directory using
this
execl ("/bin/pwd", "pwd", NULL);
output: /home/user/Ubuntu
and want to print a desired text before the current path.
for example:
my name /home/user/ubntu
how this will be done?
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
using namespace std;
int main(){
string command;
while(command != "exit"){
cout<< "B-17235"<<return execl ("/bin/pwd", "pwd", NULL);
cin>> command;
}
return 0;
}
Think that the majority of Unix-Linux-Gnu commands are written in C or C++. Generally there are direct API calls either system calls (man 2) or standard C library (man 3) to get the information or do the job.
To get working directory, just use getcwd() as suggested by alk.
char buffer[256];
if (NULL == getcwd(buffer, sizeof(buffer))) {
perror("can't get current dir");
return 1;
}
If you wanted to get the output of a more complex command, the most direct way would be to use popen that encloses the fork, exec, and pipe management for you :
FILE *fd = popen("/bin/pwd", "r");
char buffer[256];
if (fgets(buffer, sizeof(buffer), fd) == NULL) {
perror("can't read command");
return 1;
}
if (buffer[strlen(buffer) - 1] != '\n') {
fprintf(stderr, "path too long";
return 1;
}
pclose(fd);
// ok the working directory is is buffer
You should not use that for a command as simple as pwd.
And don't forget : man is your friend ! man getcwd and man popen will give you plenty of information ...
I am trying to print the path of the current directory
Use the library function getcwd().
To have the function available it might be necessary to #define _XOPEN_SOURCE 500 or similar (please see the man-page linked above for details on this).