• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 265
  • Last Modified:

Callling a program from a main C program, letting it run independently

HELP!

Is it possible to call another exe file from C programming? I understand that there is the spawn functions... but I need this program to run independently when called AND the main program continues running...

Somebody please help... would appreciate any codes if possible.

Thanks!
0
qwertbabe
Asked:
qwertbabe
  • 11
  • 7
  • 2
  • +5
1 Solution
 
akshayxxCommented:
tell me the OS u r working on ..
it can be done using .. fork and execlp.. to spawn the process and keep the main running..
0
 
akshayxxCommented:
and windows doesnt have fork .. so if u r on linux or any oother unix .. then i can help
0
 
fridomCommented:
The only ANSI compliant way is using system, that will work on any platform.

All other solutions depend on the Operating System used.

Regards
Friedrich
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
qwertbabeAuthor Commented:
erm... yah, forgot to mention that i'm trying to work on dos. doesn't matter if it's c or assembly language.

from what i hear and searched from the internet, that seems like an impossible task?

yes, i realised the only possible for now seems to be only to use a linux system where i can call fork().

What i;m trying to do is actually to run a clocking signal for a short while, while programming my ADC so as to prepare my program to read in the bits via the parallel port. The clocking signal is to allow the ADC to strobe in the bits that i am sending to program it.
0
 
rajeev_devinCommented:
Use the system() command. Hope this amy help...
0
 
jcaldwelCommented:
The system command blocks... I think that is probably undesirable.
0
 
plusheyCommented:
You really need to use one of the spawn family of functions. There are 8 in total and spawnl() is the very basic one. The spawn functions are a combination of fork() and exec() all-in-one.

For the specific problem here is an example:

#include <stdio.h>
#include <process.h>
#include <stdlib.h>
#include <errno.h>
 
main()
{
    int result;
 
    result = spawnl(P_NOWAIT, "child.exe", "child", "arg1", "arg2", (char *)NULL);
    if (result != -1)
        printf("exit status of child.exe = %d\n", result);
    else {
        if (errno == ENOENT)
            printf("child.exe not found in current directory\n");
        else if (errno == ENOMEM)
            printf("not enough memory to execute child.exe\n");
        else
            printf("error #%d trying to spawn child.exe\n", errno);
    }
}

I hope that helps.
0
 
jcaldwelCommented:
<snip>
Is it possible to call another exe file
</snip>

Sounds like DOS... Fork would be nice if I were writing in DOS.
0
 
plusheyCommented:
Yes it is possible to call another .exe file. Not all versions of DOS like the P_NOWAIT option and will return an error.
It is DOS and there is no implementation of fork() under DOS :-(
0
 
KocilCommented:
Dear, I think your intention is this
> What i;m trying to do is actually to run a clocking signal for a short while, while programming my ADC so as to prepare my program to read in the bits via the parallel port. The clocking signal is to allow the ADC to strobe in the bits that i am sending to program it.

In DOS you may achieve it by using interrupt service routine (ISR) that you hoot into the Timer interrupt.
The ISR will be running 18.2 times / seconds, but you may change it until as fast as 1000 times / seconds.
You can do this easily with Turbo Pascal or Turbo C.

/* this will be called each 1/18.2 seconds */
interrupt ClokISR()
{
   /* strobe here */
   /* then return */
}

/* the main program */
main()
{
   void interrupt* old_isr();  

   /* hook ISR to the timer interrupt */
   old_int = getvect(TIMER_INT);
   setvect(TIMER_INT, ClokISR);

   /* do your business here, program the AD etc */

   /* stop the ISR now */
   setvect(TIMER_INT, old_isr);
}


I'll tell you more if you interested.
0
 
ssnkumarCommented:
qwertbabe,
By looking at your question, I think what you are trying to implement is a daemon.
If that's so, then there are series of steps that you have to follow.
Two most important steps are:
1. Spawn a new process from the main process.
2. Using exec family of call, execute the .exe file.

With this the new (child) process, continues independently of the parent and the parent continues inspite of child.

So, you need to know spawning a new process and exec family of calls.

-Narendra
0
 
qwertbabeAuthor Commented:
plushey> the example that you've written makes use of spawnl(), but the problem with the spawn set of functions is that it requires the the child to complete the exe and exit, before the parent can continue with the main program isn't it? please correct me if i'm wrong. whereas for linux, fork() can run both simultaneously and independently.

kocil> yes, i would appreciate if u could elaborate more on that... if you're calling an interrupt, would it still send a clock signal (sq wave) to the adc? That is a requirement of the adc to read the serial data. (AD7716)

perhaps what you're saying would be something like this??

i found this code on the web, but i don't really quite understand it.

void set_sample_rate(int change)
{
     int number;              
     int ratehi,ratelo;  
     static rate=65000;                

     number=65536/(rate/18.2);    // calculate divisor

     ratehi=number&0xff00;  // calculate hi byte for timer
     ratehi=ratehi/256;
     ratelo=number&0x00ff;  // calculate lo byte for timer

     if (change==18) {  // if change=18 then reset original tick
          ratehi=0xff;
          ratelo=0xff;
     }

     outportb(0x43,0x36); // program 8253 timer for square wave
     outportb(0x40,ratelo);  // output lo byte of divisor
     outportb(0x40,ratehi);  // output hi byte of divisor

thanks.
0
 
qwertbabeAuthor Commented:
plushey> the example that you've written makes use of spawnl(), but the problem with the spawn set of functions is that it requires the the child to complete the exe and exit, before the parent can continue with the main program isn't it? please correct me if i'm wrong. whereas for linux, fork() can run both simultaneously and independently.

kocil> yes, i would appreciate if u could elaborate more on that... if you're calling an interrupt, would it still send a clock signal (sq wave) to the adc? That is a requirement of the adc to read the serial data. (AD7716)

perhaps what you're saying would be something like this??

i found this code on the web, but i don't really quite understand it.

void set_sample_rate(int change)
{
     int number;              
     int ratehi,ratelo;  
     static rate=65000;                

     number=65536/(rate/18.2);    // calculate divisor

     ratehi=number&0xff00;  // calculate hi byte for timer
     ratehi=ratehi/256;
     ratelo=number&0x00ff;  // calculate lo byte for timer

     if (change==18) {  // if change=18 then reset original tick
          ratehi=0xff;
          ratelo=0xff;
     }

     outportb(0x43,0x36); // program 8253 timer for square wave
     outportb(0x40,ratelo);  // output lo byte of divisor
     outportb(0x40,ratehi);  // output hi byte of divisor

thanks.
0
 
KocilCommented:
Well your code is the one that I said to change the Timer interrupt up till 1000 times / secs (1 Kilo Hertz).

But to be clear, how is your ADC connected to the computer ? Or to be specific, what is your ADC ? If you can send me the specification I may think the best trick for this.
It's a little bit odd for me that we have to manually send the clock to ADC. Modern ADC usually has built-in clock.



0
 
qwertbabeAuthor Commented:
the code seems to be able to change the interrupt up to 65kHz?

AD 7716 The ADC actually does have a built in clock. It operates in two possible modes, master or slave. and the frequency is 8MHz for the built in clock.

I'm thinking that it is only in the slave mode i may be able to control the serial data better, especially so when i am trying to use the parallel port to read in the data.
0
 
qwertbabeAuthor Commented:
oh and i forgot to add that whether or not i am using the internal clock, i would still need a sclk to do the initial programming of the adc...
0
 
qwertbabeAuthor Commented:
and the mode P_NOWAIT doesn't work as well...
0
 
plusheyCommented:
P_NOWAIT will work with some of the later DOS versions, it all depends which version of DOS you are using. Can you be more specific with this last point?
0
 
qwertbabeAuthor Commented:
it gives me an error saying that it was an unaccepted argument.

how do i check what version of dos i am using? Erm, not sure if it is 4.10?
0
 
plusheyCommented:
Do you have P_NOWAIT defined in process.h?
If not which P_xxxxx values are defined?

It appears that you might be running Win98, then DOS is at least at version 7. If you are running windows then there are some other ways of creating a child process.

You could CreateProcess instead - this is the function within win32 to do a spawn...

BOOL CreateProcess(

   LPCTSTR lpApplicationName,     // pointer to name of executable module
   LPTSTR lpCommandLine,     // pointer to command line string
   LPSECURITY_ATTRIBUTES lpProcessAttributes,     // pointer to process security attributes
   LPSECURITY_ATTRIBUTES lpThreadAttributes,     // pointer to thread security attributes
   BOOL bInheritHandles,     // handle inheritance flag
   DWORD dwCreationFlags,     // creation flags
   LPVOID lpEnvironment,     // pointer to new environment block
   LPCTSTR lpCurrentDirectory,     // pointer to current directory name
   LPSTARTUPINFO lpStartupInfo,     // pointer to STARTUPINFO
   LPPROCESS_INFORMATION lpProcessInformation      // pointer to PROCESS_INFORMATION  
  );

The PROCESS_INFORMATION structure returned will give you the PID in the dwProcessId member

typedef struct _PROCESS_INFORMATION { // pi
   HANDLE hProcess;
   HANDLE hThread;
   DWORD dwProcessId;
   DWORD dwThreadId;
} PROCESS_INFORMATION;

Members

hProcess: Returns a handle to the newly created process. The handle is used to specify the process in all functions that perform operations on the process object.

hThread: Returns a handle to the primary thread of the newly created process. The handle is used to specify the thread in all functions that perform operations on the thread object.

dwProcessId: Returns a global process identifier that can be used to identify a process. The value is valid from the time the process is created until the time the process is terminated.

dwThreadId: Returns a global thread identifiers that can be used to identify a thread. The value is valid from the time the thread is created until the time the thread is terminated.

Here's an example:

STARTUPINFO         si;
PROCESS_INFORMATION pi;

   si.cb=sizeof(STARTUPINFO);
   si.lpReserved = NULL;
   si.lpTitle = NULL;
   si.lpDesktop = NULL;
   si.dwX = si.dwY = si.dwYSize = si.dwXSize = 0;
   si.dwFlags = 0;
   si.wShowWindow = SW_SHOW;
   si.lpReserved2 = NULL;
   si.cbReserved2 = 0;

if (CreateProcess(NULL,
                  "child.exe",
                  NULL,
                  NULL,
                  FALSE,
                  CREATE_NEW_CONSOLE,
                  NORMAL_PRIORITY_CLASS,
                  NULL,
                  NULL,
                  &si,
                  &pi))
{
   printf("Process ID = %i\n", pi.dwProcessId);
}
0
 
qwertbabeAuthor Commented:
Apologies if I may need more elaborated explanations coz I'm quite a beginner to programming.

On searching the Internet, P_NOWAIT appears only to work for OS/2 and Win32. And explicitly mentions that it does not work on dos?!... Yes you are right, I'm using win98.

And if I were to make use of your code, I would need now to program in  Windows? Can I just add this code to my C program?

Rushing out a project... in desparate need of a solution.
0
 
plusheyCommented:
Win32 is compatible with Win98. Which compiler are you using as there is probably a compile flag that can be set to generate a win32 binary, then P_NOWAIT would work.
0
 
qwertbabeAuthor Commented:
oh!... that sounds too good to be true. Oops, on checking, it's actually WINDOWS and OS/2... would that still be possible?

Hmmmm... what is OS/2 anyway??

Nevertheless I'm using Borland C++ 3.(something)

Really really appreciate your help!
0
 
qwertbabeAuthor Commented:
oh!... that sounds too good to be true. Oops, on checking, it's actually WINDOWS and OS/2... would that still be possible?

Hmmmm... what is OS/2 anyway??

Nevertheless I'm using Borland C++ 3.(something)

Really really appreciate your help!
0
 
plusheyCommented:
I think that is where your problem might be. I don't think Borland C++ 3.x ever supported the P_NOWAIT option, it was long before win32. Later versions of the C compiler do support the option, I'm sorry I don't know which.

I know it's possible to do but with a compiler that can't support the features your OS offers you are a little stuck. Sorry I can't be of further help.
0
 
qwertbabeAuthor Commented:
that's alright. but thanks very much anyways.

ok, if i were to use the create process code, what compiler do i have to use? it's still C right? and it means i would have to program in windows right?...

perhaps someone could gimme a pointer as to transferring my original c code to whatever, so I can program in windows, and so I can use the create process code?

0
 
plusheyCommented:
char *transfer_original_C_code;

Seriously, I think your original question has been answered well enough. As for the new question of what compiler you need to use, why not upgrade to the latest Borland version?
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 11
  • 7
  • 2
  • +5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now