Four Writings for getModuleFileName under Linux

xiaoxiao2021-03-06  41

Four Writings for getModuleFileName under Linux

The cause of the problem is to put a stuff to port from Windows to Linux-based embedded systems. During the transplantation process, GetModuleFileName was encountered. In order to solve this problem, it took a lot of time and walked a lot of detours. The following is the result of organizing.

First excerproval a paragraph, source "Unix Programming FAQ Chinese version" 1.14. How do I find the corresponding executable of the process? This problem can be used as a good candidate for 'Frequently Unanswered Questions', because in fact, this problem often means that the program is designed to be defective. :) You can get the 'Best Guess' ('Best Guess') is obtained by examining the value of 'Argv [0]'. If it consists of one '/', it may be absolute or relative (for the current directory at the beginning of the program). If you don't include, you can imitate the shell to find this program for the 'Path' variable query. However, it cannot be guaranteed, because 'argv [0]' is some of the arbitrary values ​​when it is possible to execute the program, nor does this executable may have been renamed or deleted after execution. If all you want to do, you can print a suitable name that appears together with the error message, then the best way to save the value of 'Argv [0]' in the 'main ()' function in the global variable for the whole The program is used. Although it is not guaranteed that 'Argv [0]''s value is always meaningful, but in most cases it is the best choice. The most common cause of this question is to intend to locate the profile of their programs. This is considered a bad form; the directory containing executable should * only * contains executable files, and management-based requirements are often attempted to place the configuration files and different file systems with executable files. Trying to do this is more uncommon but more formal reason to allow program call 'exec ()' to perform itself; this is a way to completely reinitialize the process (such as the version used for some 'Sendmail' versions) (For example, when a daemon captures a 'SIGHUP' signal).

I fully agree with the above view! Therefore, it is not recommended to implement getModuleFileName in Linux, but it is also possible to discuss this problem for the perspective of technology. Ok, let's talk about four ways of writing in anise. Oh, no, it is a four ways to getModuleFileName.

GetModuleFileName's four ways method 1: From PATH: Int getModuleFileName1 (CHAR * SMODULENAME, CHAR * SFILENAME, INT NSI (SMODULENAME, '/')! = NULL) STRCPY (SFileName, Smodulen); Else {char * spath = GetENV ("path"); char * phead = spath; char * ptail = null; while (PHEAD! = Null&& * phead! = '/ X0' ) {PTAIL = STRCHR (PHEAD, ':'); if (ptail! = Null) {strncpy (sfilename); sfilename [ptail-pead] = '/ x0'; PHEAD = PTAIL 1; } Else {structure (sfilename, pHead); PHEAD = null;} int Nlen = Strlen (sfilename); if (sfilename [Nlen]! = '/') Sfilename [Nlen] = '/'; strcpy (SFileName Nlen 1, smodulename); if (0 == Access (sfilename, f_ok)) {RET = 0; Break;}}}} Return Ret;

Method 2: Use the Which command description: Compared with the method, it is completely changed to the soup without changing the medicine. And get the result of its execution. int GetModuleFileName2 (char * sModuleName, char * sFileName, int nSize) {int ret = 0; (! strchr (sModuleName, '/') = NULL) if strcpy (sFileName, sModuleName); else {char sBuffer [256] = { 0,}; char scommand [256] = {0,}; file * fp = null; sprintf (scommand, "which% s", smodulename); if ((fp = POMMAND, "R")) == NULL) {RET = -1;} else {sfilename [0] = '/ x0'; while (! Feof (fp)) {IF (FGETS (SBuffer, nsize-1, fp) == null) {Continue;} Strcat (sfilename, sbuffer);}} int Nlen = Strlen (sfilename); if (0 == NLEN) RET = -1; Else IF (SFileName [Nlen-1] = '/ n') sfilename [NLEN-1] = '/ x0';} Return Ret;} Method 2: Get environmental variable "_"

INT getModuleFileName3 (Char * sfilename, int nsize) {int RET = -1; char * p = getenv ("_"); if (p! = null && strstr (p, smodulename)! = null) { RET = 0; STRCPY (SFileName, P);} return ret;}

Method 4: Access the Proc File System, Read / Proc / Self / Maps Description: Please refer to http://autopackage.org/docs/binreloc/int getModuleFileName4 (Char * sfilename, int nsize) {int RET = -1; Char sline [1024] = {0}; void * psymbol = (void *) ""; file * fp; char * ppath;

FP = fopen ("/ proc / self / maps", "r"); if (fp! = null) {while (! feof (fp)) {unsigned long start, end;

IF (! fgets (sline, sizeof (sline), fp) Continue; if (! strs, "r-xp") ||! strchr (sline, '/')) Continue;

SSCANF (Sline, "% lx-% lx", & start, & end); if (psymbol> = (void *) start && psymbol <(void *) end) {char * tmp; size_t len;

/ * Extract the filename; it is always an absolute path * / ppath = strchr (sline, '/');

/ * GET RID of the newline * / tmp = strrchr (ppath, '/ n'); if (tmp) * TMP = 0;

/ * GET RID OF "* / // LEN = Strlen (PPATH); // IF (Len> 10 && Strcmp (PPath LEN - 10,") == 0) // { // TMP = PPATH LEN - 10; // * TMP = 0; //} RET = 0; STRCPY (SFileName, PPath);}} fclose (fp);} Return Ret;}

Test code: int main (int Argc, char ** argv) {charffer [256] = {0}; getchar (); Printf ("ModuleFileName1 IS:% S / N", getModuleFileName1 (Argv [0], Buffer, 256) == - 1? "NOT FOUND!": Buffer; Printf ("ModuleFileName2 IS:% S / N", getModuleFileName2 (Argv [0], Buffer, 256) == - 1? "NOT FOUND!": Buffer; Printf ("ModuleFileName3 IS:% S / N", GetModuleFileName3 (Argv [0], Buffer, 256) == - 1? "NOT FOUND!": buffer; printf ("ModuleFileName4 IS:% S / N ", GetModuleFileName4 (Buffer, 256) == - 1?" NOT FOUND! ": Buffer; return 0;}

Test Results:

Normal output: ModuleFileName1 is: / home / coldcrane / bin / helloModuleFileName2 is: / home / coldcrane / bin / helloModuleFileName3 is: / home / coldcrane / bin / helloModuleFileName4 is: / home / coldcrane / bin / hello

The program execution time the directory is moved to $ mv ~ / bin ~ / NIB output: modulefilename1 is: not found! ModuleFileName2 is: Not Found! ModuleFileName3 is: / home / foldcrane / bin / hellomodulefilename4 is: / home / coldcrane / nib / Hello

The program is executed when the file is changed to $ mv ~ / bin / hello ~ / bin / hh output results: modulefilename1 is: NOT Found! ModuleFileName2 is: Not Found! ModuleFileName3 IS: / Home / Coldcrane / bin / HellomoduleFileName4 is: / home / coldcrane / bin / hh program execution time file is deleted $ RM ~ / bin / hello output: ModuleFileName1 IS: NOT Found! ModuleFileName2 is: Not Found! ModuleFileName3 IS: / Home / Coldcrane / Bin / HellomoduleFileName4 IS: / Home / Coldcrane / BIN / HELLO (Deleded)

Relatively speaking, the method is the strongest, and some information is available, but still can't solve all the problems. Of course, for different environments, the above code has a certain reference value.

转载请注明原文地址:https://www.9cbs.com/read-72720.html

New Post(0)