xcode multiple main methods - c

I am using Xcode for c programming. I have a project called system_commands. Inside this project I have a file A, and a file B.
This is file A:
int main(int argc, char *argvector[])
{
char *arguments[] = {"./runProcesses","Hello","World",NULL};
execvp("./runProcesses", arguments);
return 0;
}
File A simply "executes" File B, and file B is here:
int main(int argc, char *argvector[])
{
for(int i = 0; i < argc; i++)
{
printf("%s", argvector[i]);
}
//some forks etc
}
Obviously, Xcode will not allow this, since there are two main methods inside the project. But is there a workaround somehow? Do I really have to create another project, so that the files reside in different projects?
Or is there a way I can execvp() a file without main method?

If you don't want two projects, you can create a second target ("File" - "New" - "Target..." and choose another "Console app") for your second program. Put your other main.c there:
You can also go to the Target settings for the first console app and add a dependency for the second console app, that way, it will build the second, if needed, whenever you run the first one.
Frankly, this multiple target approach is designed when you have an app with some shared code base, but it can be used in this scenario, too.
The other approach is to go ahead and have multiple projects, but work with them under a single "workspace". So, create a folder, create your two projects in that folder, and then create a "Workspace" (which I called "MyProject", in my example below) and add the two xcodeproj files for the two separate projects ("FirstApp" and "SecondApp" in my example below).
So, in Xcode it looks like:
And in the file system, it looks like:
So, in this case, you have two projects, but you can work with them together under a single workspace, making it really easy to work with both projects at the same time. Just open that xcworkspace workspace rather than the individual xcodeproj files.

Related

What is the entry point for git?

I was browsing through the git source code, and I was wondering where the entry point file is? I have gone through a couple files, that I thought would be it but could not find a main function.
I could be wrong, but I believe the entrypoint is main() in common-main.c.
int main(int argc, const char **argv)
{
/*
* Always open file descriptors 0/1/2 to avoid clobbering files
* in die(). It also avoids messing up when the pipes are dup'ed
* onto stdin/stdout/stderr in the child processes we spawn.
*/
sanitize_stdfds();
git_setup_gettext();
git_extract_argv0_path(argv[0]);
restore_sigpipe_to_default();
return cmd_main(argc, argv);
}
At the end you can see it returns cmd_main(argc, argv). There are a number of definitions of cmd_main(), but I believe the one returned here is the one defined in git.c, which is a bit long to post here in its entirety, but is excerpted below:
int cmd_main(int argc, const char **argv)
{
const char *cmd;
cmd = argv[0];
if (!cmd)
cmd = "git-help";
else {
const char *slash = find_last_dir_sep(cmd);
if (slash)
cmd = slash + 1;
}
/*
* "git-xxxx" is the same as "git xxxx", but we obviously:
*
* - cannot take flags in between the "git" and the "xxxx".
* - cannot execute it externally (since it would just do
* the same thing over again)
*
* So we just directly call the builtin handler, and die if
* that one cannot handle it.
*/
if (skip_prefix(cmd, "git-", &cmd)) {
argv[0] = cmd;
handle_builtin(argc, argv);
die("cannot handle %s as a builtin", cmd);
}
handle_builtin() is also defined in git.c.
Perhaps it's best to address the misunderstanding. Git is a way of collecting, recording, and archiving changes to a project directory. This is the purpose of a Version Control System, and git is perhaps one of the more recognizable ones.
Sometimes they also provide build automation, but often the best tools focus on the fewest responsibilities. In the case of git, it mostly focuses on commits to a repository in order to preserve different states of the directory it is initialized to. It doesn't build the program, so the entry points are unaffected.
For C projects, the entry point will always be the same one defined by the compiler. Generally this is a function called main, but there are ways to redefine or hide this entry point. Arduino, for example, uses setup as the entry point and then calls loop.
The comment left by #larks is an easy way to find the entry point when you're not sure. Using a simple recursive search from a git repo's root directory can hunt for the word main in any included file:
grep main *.c
The Windows equivalent is FINDSTR, but recent updates to Windows 10 have greatly improved compatibility with Bash commands. grep is usable in the version I'm running. So is ls, though I'm not sure whether it has been there all along.
Some git projects include multiple languages, and many languages related to C (and predecessors) use the same entry point name. Looking only in file extensions of .c is a good way to find the entry point of the C components, assuming the code is of high enough quality that you'd want to run it in the first place.
There are definitely ways to interfere with how well the extension filters out other languages, but their use implies very haphazard coding practice.

Creating directories based off variable names

I have been creating a C program that is going to pull a range of data from excel and store it in variables. My question, how do i create a directory in C that uses variables. I have tried several ways yesterday while at work.
#include <stdio.h>
int main(void)
{
//creating directory (works)
system("md E:\sub_directory");
system("mkdir E:\\sub_dir2");
//trying to create directory based off variables (not working yet)
char CustName[50] = "Mars";
char Product[50] = "Chocolate Drops";
int JobNumber = 100;
system("md E:\\",JobNumber,CustName,Product"",JobNumber,CustName,Product);
system("md E:\\%04i %s %s",JobNumber,CustName,Product);
return 0;
}
As you can see above, this is the code that i finished up with. The first section was just a reference point so i know base command structure. I then proceeded to fiddle with formatting that i currently know which didnt work.
Would anyone be able to shed some light on how i would use variables name to create the directories? (im currently working on a windows 10 machine but the program is going to be run on a windows 7 machine. I dont know if this changes anything.
You should use sprintf to create one string with the complete pathname you want to create. Then you should use the mkdir function of the standard library to create the directory.
Note that to create a directory, all component paths must exist, so to create E:\my\path you may first need to create E:\my and then E:\my\path.
I have had a look at sprintf and i think i understand it. i have the following code:
char CustName[50] = "Mars";
char Product[50] = "Chocolate Drops";
int JobNumber = 100;
char *filepath[100];
sprintf(*filepath, "mkdir D:\\%04i %s %s", JobNumber, CustName, Product);
puts(*filepath);
sorry if this isnt the correct use, i am still pritty new to programming

How to open files from a NaCl Dev Environment application?

I'm trying to get a simple command line application to run in the NaCl Development Environment. But I don't understand why it doesn't want to open files:
#include <stdio.h>
#include <ppapi_simple/ps_main.h>
int my_main (int argc, char ** argv) {
FILE * f = fopen ("out.txt","w");
if (f) {
fputs ("output to the file", f);
fclose(f);
} else {
puts("could not open file");
}
}
PPAPI_SIMPLE_REGISTER_MAIN(my_main)
Running:
bash.nmf-4.3$ gcc -I"$NACL_SDK_ROOT/include" test.c -lppapi_simple -lnacl_io -lppapi
bash.nmf-4.3$ ./a.out
could not open file
bash.nmf-4.3$
It's clearly possible for an application to open files in arbitrary locations within the dev environment - I'm using nano to edit the test code! But the naclports version of nano doesn't look like it's been changed in ways that are immediately connected to file manipulation..?
Lua is another app that appears to have only been modified very slightly. It falls somewhere in between, in that it can run test files but only if they're placed in /mnt/html5, and won't load them from the home folder. My test program shows no difference in behaviour if I change it to look in /mnt/html5 though.
NB. my goal here is to build a terminal application I can use within the dev environment alongside Lua and nano and so on, not a browser-based app - I assume that makes some difference to the file handling rules.
Programs run in the NaCl Dev Environment currently need to linked with -lcli_main (which in turn depends on -lnacl_spawn) for an entry point which understands how to communicate with the javascript "kernel" in naclprocess.js. They need this to know what current working directory they were run from, as well as to heard about mounted file systems.
Programs linked against just ppapi_simple can be run, but will not setup all the mount points the dev environment may expect.
There is a linker script in the dev env that simplifies linking a command line program -lmingn. For example the test program from the question can be compiled with:
gcc test.c -o test -lmingn
NOTE: This linker script had a recently resolved issue, a new version with the fix was published to the store on 5/5/2015.
In the near future, we have plans to simplify things further, by allowing main to be the entry point.
Thanks for pointing out the lua port lacks the new entry point!
I've filed an issue and will look into fixing it soon:
https://code.google.com/p/naclports/issues/detail?id=215
I found a solution to this, although I don't fully understand what it's doing. It turns out that the small changes made to nano are important, because they cause some other functions elsewhere in the NaCl libraries to get pulled in that correctly set up the environment for file handling.
If the above file is changed to:
#include <stdio.h>
int nacl_main (int argc, char ** argv) {
FILE * f = fopen ("out.txt","w");
if (f) {
fputs ("output to the file", f);
fclose(f);
} else {
puts("could not open file");
}
}
...and compiled with two more libraries:
gcc -I"$NACL_SDK_ROOT/include" test.c -lppapi_simple -lnacl_io -lppapi -lcli_main -lnacl_spawn
...then it will work as expected and write the file.
Instead of registering our own not-main function with PPAPI_SIMPLE_REGISTER_MAIN, pulling in cli_main causes it to do so with an internal function that sets some things up, presumably including what is needed for file writing to work, and expects to then be able to call nacl_main, which is left to the program to define with external visibility (several layers of fake-main stacking going on). This is why the changes to nano look so minimal.
nacl_spawn needs to be linked because cli_main uses it for ...something.

How to call same file as different name for different method?

I was recently at a presentation where one of the speakers stated that he'd used a single CGI file, written in C, that is called by the webserver, but the webserver calls the file by using different names, the CGI file would run a different method.
How can I have a single C file execute different functions within when it is called by different names? Also how do I re-direct the calls for differently named files back to this single file?
Is this possible or was he just full of himself?
If you create the executable with different names but with the same code base, you can take a different branch of the code based the name of the executable used to invoke the program.
Simple example file:
#include <stdio.h>
#include <string.h>
int main1(int argc, char** argv)
{
printf("Came to main1.\n");
return 0;
}
int main2(int argc, char** argv)
{
printf("Came to main2.\n");
return 0;
}
int main(int argc, char** argv)
{
// If the program was invoked using main1, go to main1
if (strstr(argv[0], "main1") != NULL )
{
return main1(argc-1, argv+1);
}
// If the program was invoked using main2, go to main2
if (strstr(argv[0], "main2") != NULL )
{
return main2(argc-1, argv+1);
}
// Don't know what to do.
return -1;
}
Create two different executables from the file.
cc test-262.c -o main1
cc test-262.c -o main2
Then, invoke the program by using the two different executables:
./main1
Output:
Came to main1.
and...
./main2
Output:
Came to main2.
Unix filesystems support the concept of hard and soft links. To create them just type:
ln origfile newfile
to create a hard link, or:
ln -s origfile newfile
to create a soft link.
Soft links are just a special kind of file that contains the path of another file. Most operations in the link transparently result in operating on the target file.
Hard links are lower level. In effect, all files are a link from the pathname to the content. In Unix you can link more than one pathname to the same content. In effect, there's no "original" and "links", all are links. When you delete a file, you're just removing a link, and when the link count goes to zero, the content is removed.
Many unix utilities do this trick. Since the running shell includes the name used to invoque the executable, it's handled just like the 0'th argument of the command line.
When a CGI script is being called by a web server, it receives a considerable amount of information in its environment to let it know how it was called, including:
SCRIPT_NAME, the path to the script from the document root
SCRIPT_FILENAME, the filesystem path to the script (usually the same as argv[0])
REQUEST_URI, the path that was requested by the browser (usually similar to SCRIPT_NAME in the absence of URL rewriting)
QUERY_STRING and PATH_INFO, which contain URL parameters following the script's name
HTTP_*, which contain most of the HTTP headers that were passed in the request
Point is, the script gets a lot of information about how it was called. It could be using any of those to make its decision.
It's possible and actually pretty common.
The first element in the argv array passed to the main function is the "name" of the executable. This can be the full path, or it can be just the last component of the path, or -- if the executable is started with an exec* function call, it can be an arbitrary string. (And Posix allows it to be a null string, as well, but in practice that's pretty rare.)
So there is nothing stopping the executable from looking at argv[0] (having first checked to make sure that argc > 0) and parsing it.
The most typical way to introduce a different name for the executable is to insert a filesystem link with the alternate name (which could be either a hard or a soft-link, but for maintainability soft links are more useful.)
For CGIs, it is not even necessary to examine argv[0], since there are various useful environment variables, including (at least): SCRIPT_NAME.

Store binary file as a string inside my code

I'm creating a library to provide access to another library.
The library in question is a vendor, so not everyone should access this library.
One solution to do so is to put the library on a specific group (AIX) and then put everyone that can compile using it in the same group.
This solution don't works here because there are a lot of new people coming in and out, and the user that compiles (Its a process that do this operation) is not the same as the user that can access the code.
The solution i'm trying to archive is.
Every application have an pattern on their directory.
/Aplications/Group/...
So i can get the Group using the folder when the program runs.
What i am trying to do is.
Create a library that checks the directory and then loads the library using (loadAndInit) the dlopen function on AIX that already loads all the symbols, so i don't need the dlsym.
The problem is, i want to put the binary code of the library i want to load inside my source code.
WHY: Because if App -> Lib (Loads) -> Vendor, nothing can limit the developer from doing an link by hand or compiling by hand the App -> Vendor.
And the structure that call the compilation process cannot limit that.
What i have tried.
Convertlib
FILE* file=fopen("vendor.so", "rb");
int c;
do{
c=getc(file);
if(c > 0)
printf("\\x%02x", c);
}while(c!=EOF);
Then i have a little script that puts the output of this file as a
char *lib=(char* (malloc(sizeof(char) * /* lib size */));
lib="/*output of the Convertlib*/
Then i try to load it using fmemopen, so i dont create a temporary file just a file descriptor inside my process area.
To load it i do
FILE* vendorLib=fmemopen(lib, /*libSize*/, "r");
char path[50];
sprintf("/proc/%d/fd/%d", getpid(), fileno(vendorLib));
loadAndInit(path, 0, "");
If i call directly a lib (i have it to test) and dont load using the hex formated library it works.
But as i converted my binary code to hex and i'm trying to load it, it dont work.
Should i convert back to load it on the memory and use it as an library again?
This seems the only solution to work with, as the library is a vendor i cannot change it and it is the only way i see to limit the access because we have here more than 1000 programmers
I solved it using
printf("\x%02x", thechar);
Inside the getc loop
So i wrote it inside a memcpy then i copy to the memory so the binary file is stored as HEX data.
Works perfectly

Resources