I am just porting a code to Mac OS X which is using _tspawnl on Windows.
Is there anything equivalent to _tspawnl on Mac OS X or Linux?
Or is there any posix equivalent to _tspawnl
You can use fork and execv system call together in the following way :
if (!fork()){ // create the new process
execl(path, *arg, ...); // execute the new program
}
The fork system call creates a new process, while the execv system call starts the execution of the application specify in path.
For example, you can use the following function spawn whose argument are the name of the application to be executed and the list of its arguments.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int spawn (char* program, char** arg_list)
{
pid_t child_pid;
/* Duplicate this process. */
child_pid = fork ();
if (child_pid != 0)
/* This is the parent process. */
return child_pid;
else {
/* Now execute PROGRAM, searching for it in the path. */
execvp (program, arg_list);
/* The execvp function returns only if an error occurs. */
fprintf (stderr, “an error occurred in execvp\n”);
abort ();
}
}
int main ()
{
/* The argument list to pass to the “ls” command. */
char* arg_list[] = {
“ls”, /* argv[0], the name of the program. */
“-l”,
“/”,
NULL /* The argument list must end with a NULL. */
};
spawn (“ls”, arg_list);
printf (“done with main program\n”);
return 0;
}
This example has been taken from the chapter 3.2.2 of this book. (Really good reference for development in Linux).
You can use fork()/exec(), as already pointed out, however a closer system call is posix_spawn() (manpage).
It can be a bit of a pain to set-up, however, but there is some example code using it is here (note that this code also provides functionality for Windows using the CreateProcess() API, which is probably what you should be using under Windows anyway).
Related
Now imagine you have two programs with different lua instances. One is the main program, the second is the dll you coded for it.
In my question, I will name the main program as main, dll i child from now on. We load the child into the Main process, detouring it and somehow accessing lua_State.
My main question is, can we do lua_pcall or dofile via the lua_State we grab while the main program is running?
Sample code
Main program:
#include <lua.hpp>
bool loadFile(lua_State* L) {
// run the Lua script
luaL_dofile(L, "helloworld.lua");
if (lua_pcall(L, 0, 0, eh) != 0)
{
std::string err = luaL_checkstring(L, -1);
lua_pop(L, 1);
}
}
int main()
{
// create new Lua state
lua_State *lua_state;
lua_state = luaL_newstate();
loadFile(lua_state);
}
Child program:
#include <lua.hpp>
#include "hookingLibrary.h"
typedef int(__fastcall* main_loadFile_Proto)(lua_State* L);
main_loadFile_Proto main_loadFile_Ptr;
lua_State * L lastState;
uint64_t main_loadFile_Addr = 0x0;
int main_loadFile_Detour(lua_State* L) {
lastState = L;
return main_loadFile_Ptr(L);
}
int main()
{
// detouring etc.
// I do not put detouring codes here. I am just declaring it as an
// opinion.
HookingLibrary::hook((LPVOID)(uintptr_t)main_loadFile_Addr, &main_loadFile_Detour, (LPVOID*)&main_loadFile_Ptr);
do{
Sleep(100);
}while(!lastState);
// create new Lua state
lua_State *lua_state;
lua_state = lastState;
// run the Lua script
luaL_dofile(lua_state, "helloworld.lua");
// close the Lua state
lua_close(lua_state);
}
Now imagine you have two programs with different lua instances. One is the main program, the second is the dll you coded for it.
This statement is not very clear, it depends on your expectations. I see 2 possible answers.
Create a DLL which implement some additional functions for Lua. The DLL library can be used later by the main program. In this case, there is only 1 instance of lua_state, there is only 1 Lua interpreter. This Lua interpreter may be created by the DLL or by the main function.
The interface of DLL is something like that:
#ifndef DLL_AUGMENTED
#define DLL_AUGMENTED
#include "lua.h"
lua_State *DLL_CreateAugmentedLuaInterpreter ();
void DLL_FreeLuaInterpreter ();
#endif
And can be used by main:
#include "lua-augmented.h"
int main (int argc, char **argv)
{
lua_State *LuaState = DLL_CreateAugmentedLuaInterpreter ();
// TODO: use the augmented Lua instance
DLL_FreeLuaInterpreter(LuaState);
return 0;
}
There is a need to have 2 Lua instances, as written One is the main program, the second is the dll. In this case, it's more difficult because a IPC Interprocess Communication need to be implemented with sockets or pipes. The best is to look for LuaSocket library.
Interprocess communication in Lua with Example?
So I am trying to call a program from within a c file I am making but the only way I've been able to do that is by using the system() function which causes error on its own. To run the program in terminal I use;
~/odas/bin/odaslive -vc ~/odas/config/odaslive/matrix_creator.cfg
This is what I am currently trying to use to run that same program, it compiles and will run in terminal but nothing happens.
pid_t pid=fork();
if (pid==0){
//static char *argv[] ={"echo","-vc ~/odas/config/odaslive/matrix_creator.cfg", NULL};
execl("~/odas/bin", "~/odas/bin/odaslive", "-vc", "~/odas/config/odaslive/matrix_creator.cfg", (char *)NULL);
exit(127);
} else {
waitpid(pid,0,0);
}
execl requires file path in the first argument.
It doesn't expand ~ with the home for path. The full path must be supplied.
Check a returned value and errno. It will inform you about a failure reason if any.
int ret = execl("/home/username/odas/bin/odaslive", "/home/username/odas/bin/odaslive", "-vc", "/home/username/odas/config/odaslive/matrix_creator.cfg", (char *)NULL);
Background: Downloaded google-coredumper-1.2.1.tar.gz from code.google.com. built the code and make install. Added library and function call to my application and execute. No core file, Logs state Operation not permitted. So I created a simple example and stepped through it and found that the library believes that the executable is already being traced. Any ideas?
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include "crashtest.h"
#include <google/coredumper.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
FILE * backtrace_file = NULL;
#define SIZE 100
void CREATE_COREDUMP()
{
printf("NOTICE, Creating a core dump for debugging\n");
char extension[64];
time_t t = time((time_t*)NULL);
tm * theTime = localtime(&t);
snprintf( extension,
sizeof(extension) - 1,
"core.crashtest_02d_%02d_%02d_%02d", (theTime->tm_mday),
(theTime->tm_hour),
(theTime->tm_min) ,
(theTime->tm_sec) );
if (WriteCoreDump(extension) != 0) {
std::string errmsg(extension);
errmsg.append(" : ");
errmsg.append(strerror(errno));
printf("WARNING, Failed to create coredump: %s\n", errmsg.c_str() );
}
}
static void mysighandler(int sig)
{
printf("ERROR, Somebody Segmentation Faulted. About to Exit\n");
CREATE_COREDUMP();
exit(0);
}
crashtest::crashtest() {
char * errcond = NULL;
memcpy(errcond, "Crash This", 10);
}
crashtest::~crashtest() {}
int main(int argc, char** argv) {
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sa.sa_handler = &mysighandler;
sigaction(SIGSEGV, &sa, NULL);
crashtest ct;
return 0;
}
The point of the exercise is that the main code generates a segmentation fault occasionally which does not make sense because all the values are initialized. Therefore I am trying to discover why there is a segmentation fault and would like to get a core to track down the offending line of code. I cannot just kill since the code is required to recover and continue. That is why google-coredumper is thought to be used.
According to http://www.gossamer-threads.com/lists/linux/kernel/622686, it seems that coredumper in its current state is not usable anymore:
I believe, if I interpret the data on kernel.org correctly, this
change was made by Linus and shipped with 2.6.15.
Both perftools and coredumper need to locate all threads in the active
application in order to work. As libpthread has had changing and
poorly documented APIs to get this information, and as our intent is
to support all kernel versions and all libc versions, we resorted to
ptracing any process that is suspected to be one of our threads in
order to determine if it actually is. This has the added benefit of
finding all threads (including ones not managed by libpthread) and
of temporarily suspending them, so that we have a stable memory image
that we can inspect. Think of both tools as something like a
lightweight in-process debugger.
Obviously, special care has to be taken to not ptrace our own thread,
and to avoid any library calls that could deadlock.
Before the patch, attaching ptrace to my own threads was a valid
operation. With this new patch, I can no longer do that.
I want to call a user space program from a kernel module periodically.But the kernel program is freezing the system, while I try to load it.
following is the program,
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
#include <linux/jiffies.h>
#include <linux/time.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <linux/hrtimer.h>
#include <linux/sched.h>
#include <linux/delay.h>
#define TIME_PERIOD 50000
static struct hrtimer hr_timer;
static ktime_t ktime_period_ns;
static enum hrtimer_restart timer_callback(struct hrtimer *timer){
char userprog[] = "test.sh";
char *argv[] = {userprog, "2", NULL };
char *envp[] = {"HOME=/", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
printk("\n Timer is running");
hrtimer_forward_now(&hr_timer, ktime_period_ns);
printk("callmodule: %s\n", userprog);
call_usermodehelper(userprog, argv, envp, UMH_WAIT_PROC);
return HRTIMER_RESTART;
}
static int __init timer_init() {
ktime_period_ns= ktime_set( 0, TIME_PERIOD);
hrtimer_init ( &hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
hr_timer.function = timer_callback;
hrtimer_start( &hr_timer, ktime_period_ns, HRTIMER_MODE_REL );
return 0;
}
static int __exit timer_exit(){
int cancelled = hrtimer_cancel(&hr_timer);
if (cancelled)
printk(KERN_ERR "Timer is still running\n");
else
printk(KERN_ERR "Timer is cancelled\n");
}
module_init(timer_init);
module_exit(timer_exit);
MODULE_LICENSE("GPL");
test.sh is a script which just echoes a comment.
I have tested the call_usermodehelper part and timer part individually and it is working fine. But while I am combining the two codes, the system hangs.
Can anybody please help me to solve the problem.
Quick look around strongly suggests that hrtimer callbacks are executed from an irq context, which is expected - how else are you going to get high resoluton?
But this also means you must no block, while your callback can block due to call_usermodehelper regardless of NOWAIT passed.
So it seems you are testing your module on a kernel with debugging disabled, which is fundamentally wrong.
But this is less relevant as the thing you are trying to achieve in the first place looks fundamentally wrong.
I can only recommend you elaborate what is the actual problem. There is absolutely now way that forking + execing has anything to do with something requiring a high resolution timer.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
how to find the location of the executable in C
I'm writting an multi-platform app in C++ using GTK+ and I have a problem. I must get program path. E.g., when program is in /home/user/program (or C:\Users\user\program.exe), i have /home/user/ (or C:\Users\user\).
Can and how I can do this?
For Win32/MFC c++ programs:
char myPath[_MAX_PATH+1];
GetModuleFileName(NULL,myPath,_MAX_PATH);
Also observe the remarks at
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683156%28v=vs.85%29.aspx,
In essence: WinMain does not include the program name in lpCmdLine, main(), wmain() and _tmain() should have it at argv[0], but:
Note: The name of the executable in the command line that the
operating system provides to a process is not necessarily identical to
that in the command line that the calling process gives to the
CreateProcess function. The operating system may prepend a fully
qualified path to an executable name that is provided without a fully
qualified path.
argv[0] contains the program name with path. Am I missing something here?
On windows..
#include <stdio.h> /* defines FILENAME_MAX */
#ifdef WINDOWS
#include <direct.h>
#define GetCurrentDir _getcwd
#else
#include <unistd.h>
#define GetCurrentDir getcwd
#endif
char cCurrentPath[FILENAME_MAX];
if (!GetCurrentDir(cCurrentPath, sizeof(cCurrentPath)))
{
return errno;
}
cCurrentPath[sizeof(cCurrentPath) - 1] = '/0'; /* not really required */
printf ("The current working directory is %s", cCurrentPath);
Linux
char szTmp[32];
sprintf(szTmp, "/proc/%d/exe", getpid());
int bytes = MIN(readlink(szTmp, pBuf, len), len - 1);
if(bytes >= 0)
pBuf[bytes] = '\0';
return bytes;
And you should look at this question..
How do I get the directory that a program is running from?