?
Solved

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

Posted on 2003-03-12
27
Medium Priority
?
264 Views
Last Modified: 2010-04-15
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
Comment
Question by:qwertbabe
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 11
  • 7
  • 2
  • +5
27 Comments
 
LVL 8

Expert Comment

by:akshayxx
ID: 8125697
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
 
LVL 8

Expert Comment

by:akshayxx
ID: 8125700
and windows doesnt have fork .. so if u r on linux or any oother unix .. then i can help
0
 
LVL 24

Expert Comment

by:fridom
ID: 8125781
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:qwertbabe
ID: 8126754
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
 
LVL 12

Expert Comment

by:rajeev_devin
ID: 8127039
Use the system() command. Hope this amy help...
0
 
LVL 1

Expert Comment

by:jcaldwel
ID: 8128661
The system command blocks... I think that is probably undesirable.
0
 

Expert Comment

by:plushey
ID: 8130316
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
 
LVL 1

Expert Comment

by:jcaldwel
ID: 8130362
<snip>
Is it possible to call another exe file
</snip>

Sounds like DOS... Fork would be nice if I were writing in DOS.
0
 

Expert Comment

by:plushey
ID: 8132804
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
 
LVL 5

Expert Comment

by:Kocil
ID: 8133619
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
 
LVL 8

Expert Comment

by:ssnkumar
ID: 8133900
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
 

Author Comment

by:qwertbabe
ID: 8134064
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
 

Author Comment

by:qwertbabe
ID: 8134096
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
 
LVL 5

Expert Comment

by:Kocil
ID: 8134111
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
 

Author Comment

by:qwertbabe
ID: 8134135
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
 

Author Comment

by:qwertbabe
ID: 8134187
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
 

Author Comment

by:qwertbabe
ID: 8134386
and the mode P_NOWAIT doesn't work as well...
0
 

Expert Comment

by:plushey
ID: 8135032
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
 

Author Comment

by:qwertbabe
ID: 8135104
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
 

Accepted Solution

by:
plushey earned 60 total points
ID: 8135710
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
 

Author Comment

by:qwertbabe
ID: 8136215
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
 

Expert Comment

by:plushey
ID: 8136307
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
 

Author Comment

by:qwertbabe
ID: 8136387
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
 

Author Comment

by:qwertbabe
ID: 8136444
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
 

Expert Comment

by:plushey
ID: 8138682
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
 

Author Comment

by:qwertbabe
ID: 8145974
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
 

Expert Comment

by:plushey
ID: 8150837
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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and inf…
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.
Suggested Courses
Course of the Month9 days, 19 hours left to enroll

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question