I have a program that works like this
program1.exe program2.exe
I need to make it run like this
%USERPROFILE%\program1.exe program2.exe
How can that be done on C?
From what I could see, you're using Microsoft Windows.
There are (at least) two answers to your question, a simple one, and one tied to the Windows operating system interface, usually called Win32 API.
Let's use the simple one. If your prefer to have more control about the execution of the 2nd program, please comment.
#include <stdio.h> /* printf() */
#include <stdlib.h> /* system() */
int main(int argc, char* const* argv)
{
int rv;
if (argc < 2) {
printf("Please inform the name of the program to execute.\n");
return 1;
}
rv = system(argv[1]);
printf("Program execution returned %d\n", rv);
return 0;
}
Related
Here is my code for user/sleep.c:
#include "kernel/types.h"
#include "user/user.h"
int
main(int argc, char *argv[])
{
if (argc < 2)
{
printf("You have forgotten to pass an argument.");
exit(1);
}
int arg = atoi(argv[1]);
sleep(arg);
exit(0);
// return 0;
}
All is fine but with the return 0 instead of exit(0), I get the following error:
usertrap(): unexpected scause 0x000000000000000d pid=4
sepc=0x00000000000000f6 stval=0x0000000000003008
Why is that?
It's because xv6 is not standard on this point:
see https://tnallen.people.clemson.edu/2019/03/04/intro-to-xv6.html
Returning after main is a special case that is not supported in XV6, so just remember to always exit() at the end of main instead of return. Otherwise, you will get a “trap 14,” which in this case is XV6-speak for “Segmentation Fault.” Finally, notice that our headers are different. There is no #include <stdio.h> as you might be used to. Again, this is because the standard library is different. Check out these headers to see what kind of user utilities you have available.
So why did we need exit() in xv6?
Because, when building a program with gcc for linux for instance, the tool chain add the required exit call: see https://en.wikipedia.org/wiki/Crt0
In short, on linux, your program don't start at main but at start:
void start(void) {
/* get argc, argv, env) */
int r = main(argc, argv, envp); /* << start calls the actual main */
exit(r);
}
On xv6, on contrary, the real starting point is main when OS try to return from main, it has no address to pop what cause a segfault
the program is still very empty and "naked" because im just trying to get the logic out of the way before I actually start making functions. For some reason, whatever my argv[1] is, it always prints "The help message". What am I missing? I have a bad feeling about that for statement, but I dont know whats wrong with it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void help()
{
printf("The help message\n");
exit(1);
}
void a()
{
printf("The a screen\n");
exit(1);
}
int main(int argc, char *argv[])
{
char recognised_commands[3] = {help(), a()};
int i;
if (argc != 2)
{
fprintf(stderr, "usage of sake: \"sake [option(s)]\"\nFor a full listing of all available commands type \"-help\" or \"--help\"\n\n");
exit(1);
}
for (i = recognised_commands[0]; i != recognised_commands; i++)
{
printf(argv[1]);
}
}
Edit 1: djikay: Fixed the -1 to 0,
Ricky: How do I correct the help() and the a() to only call the one the user inputs after the program name (EX: sake -a)? I also fixed the exit(0). Thanks
The line:
char recognised_commands[3] = {help(), a()};
causes both help and a to be called. help is called first, and it prints out the help message & exits the program.
char recognised_commands[3] = {help(), a()};
This line is definitely your issue. help() and a() are both being called, thus exiting your program.
Why are you trying to assign those function return values there? Both of the functions are void in return type, meaning they won't return anything anyways.
On a side note, calling exit() with 0 as the argument means your program exited without errors. I'd exit with 1 if it's because of an error (or even better, EXIT_SUCCESS and EXIT_FAILURE, respectively).
How do I programmatically open a file in its default program in Linux (im using Ubuntu 10.10).
For example, opening *.mp3 will open the file in Movie Player (or something else).
You need to run gnome-open, kde-open, or exo-open, depending on which desktop you are using.
I believe there is a project called xdg-utils that attempts to provide a unified interface to the local desktop.
So, something like:
snprintf(s, sizeof s, "%s %s", "xdg-open", the_file);
system(s);
Beware of code injection. It's safer to bypass scripting layers with user input, so consider something like:
pid = fork();
if (pid == 0) {
execl("/usr/bin/xdg-open", "xdg-open", the_file, (char *)0);
exit(1);
}
// parent will usually wait for child here
Ubuntu 10.10 is based on GNOME. So, it would be good idea to use
g_app_info_launch_default_for_uri().
Something like this should work.
#include <stdio.h>
#include <gio/gio.h>
int main(int argc, char *argv[])
{
gboolean ret;
GError *error = NULL;
g_type_init();
ret = g_app_info_launch_default_for_uri("file:///etc/passwd",
NULL,
&error);
if (ret)
g_message("worked");
else
g_message("nop: %s", error->message);
return 0;
}
BTW, xdg-open, a shell script, tries to determin your desktop environment and call a known helper like gvfs-open for GNOME, kde-open for KDE, or something else. gvfs-open ends up calling g_app_info_launch_default_for_uri().
A simple solution with less coding:
I've tested this program on my Ubuntu and it is working fine, and if I am not wrong you are looking for something like this
#include <stdio.h>
#include <stdlib.h>
int main()
{
system("firefox file:///dox/song.mp3");
return 0;
}
On Wi32
I am trying to start a executable who redirects to a filename (current date) e.g. the same as:
Someexecutable.exe > 20101220000000.txt
When I do this from windows cmd.exe everything works fine. However when doing this from my program as shown below the system seems ot either drop the redirect even if it creates the file and/or it seems to buffer a large amount of data before flushing to disk.
I can't change the executable that is being run.
The program beeing executed now only writes to stdout, but remember I can't change this at all. (the simplest way woud be to just do stdout = filehandle; but I that is sadly impossible for me right now!)
(Not required: Also the program waits as system() this is not required but what is the simplest way of detaching the program being run via system() )
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char *argv[])
{
char execstr[512];
char s[30];
size_t i;
struct tm tim;
time_t now;
now = time(NULL);
tim = *(localtime(&now));
i = strftime(s,30,"%Y%m%d%H%M",&tim);
sprintf(execstr,"someexecutable.exe > %s.txt",s);
printf("Executing: \"%s\"\n",execstr);
system(execstr);
exit(0);
return 0;
}
I don't see any reason for this to not work, but if this is the case with you, one of the alternative solution could be to use popen and then read from the pipe for writing in the desired file. Here is some sample code which is printing on the screen. You can write that to file instead of screen/console as per your requirement.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char *argv[])
{
char execstr[512];
char s[30];
size_t i;
struct tm tim;
time_t now;
char buf[128];
FILE *pipe;
now = time(NULL);
tim = *(localtime(&now));
i = strftime(s,30,"%Y%m%d%H%M",&tim);
#if 0
sprintf(execstr,"a.exe > %s.txt",s);
printf("Executing: \"%s\"\n",execstr);
#endif /* #if 0 */
if( (pipe = _popen("a.exe", "rt")) == NULL )
exit( 1 );
while(!feof(pipe))
{
if (fgets(buf, 128, pipe) != NULL )
printf(buf); /* write to the required file here */
}
_pclose(pipe);
return 0;
}
Your program works fine for me (testing in VS 2010). Some problems you might run into if you're running your tests in the IDE are:
the current directory for the program might not be what you expect it to be (so you might be looking for the output file in the wrong place). By default, the current directory for the program when run in the IDE will be the directory that has the project file (whatever.vcproj or whatever,.vcxproj) - not the directory that has the executable. This can be changed in the project settings.
the IDE's path might not be the same as what you get at a standard command line, so you program might not be finding someexecutable.exe
If you change you program so that the line with the sprintf() call looks like:
sprintf(execstr,"someexecutable.exe",s);
Do you see the output of someexecutable.exe in the console window?
I am writting an application that has multiple threads in Linux environment using C or python. I am using pthread for that. But How number of threads should be accepted via command line.
In C you handle command line arguments by having main take two arguments,
int main(int argc, char** argv)
in which argc is the number of command line arguments (including the program itself) and argv is a pointer to a memory location where argc-1 pointers to strings with the actual arguments are located. Example:
int main(int argc, char** argv)
{
printf("The program was executed as %s.\n", argv[0]);
printf("The arguments were:\n");
for (int i = 1; i < argc; i++)
printf("%s\n", argv[i]);
return 0;
}
Let's now assume that your program takes a single command line argument, an integer telling you how many threads to spawn. The integer is given as a string, so we have to convert it using atoi:
if (argc != 2)
{
printf("Need exactly one argument!\n");
return 1;
}
int num_threads = atoi(argv[1]); // Convert first argument to integer.
if (num_threads < 1)
{
printf("I'll spawn no less than 1 thread!\n");
return 2;
}
Now what you do is simply create an array of thread handles,
pthread_t* threads = malloc(num_threads*sizeof(pthread_t));
and use it to store the thread handles as you start num_threads number of threads using pthread_create.
If you are not familiar with pthreads at all, I recommend this short tutorial.
If you were using a threading framework like OpenMP, then this is all handled automatically simply by setting the environment variable OMP_NUM_THREADS.
But if you're implementing threads "manually", you'll need to do it the way most runtime configuration is done: either by parsing argv[], or by setting an environment variable and using getenv().
Usually, you would just pass it like any other argument. I've used code similar to the following in projects before to specify fixed thread counts. This is fairly simple but suitable for situations where you don't need the full power of thread pooling (though you could just as easily set a minimum and maximum thread count the same way).
#include <stdio.h>
#define THRD_DFLT 5
#define THRD_MIN 2
#define THRD_MAX 20
static int numThreads = 0;
int main (int argCount, char *argVal[]) {
if (argCount > 1)
numThreads = atoi (argVal[1]);
if ((numThreads < 5) || (numThreads > THRD_MAX)) {
printf ("Number of threads outside range %d-%d, using %d\n",
THRD_MIN, THRD_MAX, THRD_DFLT);
numThreads = THRD_DFLT;
}
:
: