What is the Windows equivalent of "pidof" from Linux? - c

In a batchscript, I need to get a list of process IDs with given binary path C:\path\to\binary.exe.
In Linux, I can just do pidof /path/to/binary.
Is there a Win32 executable which does the same, supported from WinXP Home to Win7 (tasklist won't work)?
The package which includes this has to be portable, so a 10MB download is not what I'm looking for.
Is there a C function available which does this and is supported from WinXP to Win7? Note: I want to match a process path, not a filename which could be used by other applications too.

wmic.exe is available on XP, Vista and 7 and can do this. However, it does not come with Windows XP Home edition.
wmic process where ExecutablePath='C:\\windows\\system32\\notepad.exe' get ProcessId
If you want support for Windows XP Home too, you can use EnumProcess and GetModuleFileNameEx. The downside here is that you won't be able to query names of processes running by another user if you're not running as administrator. QueryFullProcessImageName will probably do the trick here, but it's Vista+.
If that's not enough, you'll need Process32First (swatkat's code). For each process you need to call Module32First and then get MODULEENTRY32->szExePath. Note that even this is not completely portable and will not work well on x64 where you'll need QueryFullProcessImageName.

You can use Toolhelp APIs to enumerate processes, get their full path and compare it with the required process name. You need to walk the modules list for each process. The first module in the list is the process executable itself. Here's a sample code:
int main( int argc, char* argv[] )
{
if( argc > 1 )
{
printf( "\nGetting PID of: %s\n", argv[1] );
HANDLE hProcSnapshot = ::CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( INVALID_HANDLE_VALUE != hProcSnapshot )
{
PROCESSENTRY32 procEntry = {0};
procEntry.dwSize = sizeof(PROCESSENTRY32);
if( ::Process32First( hProcSnapshot, &procEntry ) )
{
do
{
HANDLE hModSnapshot = ::CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, procEntry.th32ProcessID );
if( INVALID_HANDLE_VALUE != hModSnapshot )
{
MODULEENTRY32 modEntry = {0};
modEntry.dwSize = sizeof( MODULEENTRY32 );
if( Module32First( hModSnapshot, &modEntry ) )
{
if( 0 == stricmp( argv[1], modEntry.szExePath ) )
{
printf( "\nPID: %ld\n", procEntry.th32ProcessID );
::CloseHandle( hModSnapshot );
break;
}
}
::CloseHandle( hModSnapshot );
}
}
while( ::Process32Next( hProcSnapshot, &procEntry ) );
}
::CloseHandle( hProcSnapshot );
}
}
return 0;
}

You can write a small C# application which first calls Process.GetProcessesByName(String) , then go over the results and print the Id property of each one when the MainModule.FileName is equal to the path you are looking for.

PowerShell can solve your problems, if is buit in in Win 7, and downloadable on the other OSs.
param($fileName)
Get-Process | where -FilterScript {$_.MainModule.FileName -eq $fileName}
This script will receive one parameter, the filename you are looking for, and it will output the filename of its executable.
You can call this from a bat file by doing:
powershell -Command "& {Get-Process | where -FilterScript {$_.MainModule.FileName -eq %FILENAME%}"

Related

generate temporary filename with .ico extension on windows

I wish to generate a temporary filename that ends with the extension .ico using the windows C API.
I have tried using GetTempFileName but then I cannot control the extension.
The only reasons why you'd want to use GetTempFileName is, because it guarantees to produce a unique file name. Appending an arbitrary extension breaks that invariant, so that is not a solution.
So you need a solution that produces a unique file name. Using the string representation of a GUID is a common way to get that:
std::wstring GetUniqueFileName( const std::wstring& extension = std::wstring() ) {
GUID guid{ 0 };
_com_util::CheckError( ::CoCreateGuid( &guid ) );
wchar_t buffer[39];
if ( !::StringFromGUID2( guid, buffer, sizeof( buffer ) / sizeof( *buffer ) ) ) {
throw std::runtime_error( "StringFromGUID2() failed." );
}
std::wstring retVal{ buffer };
retVal += extension;
return retVal;
}

Nagios plugin (written in C) unable to open file

I have a plugin written in c that will parse a .log file and determine the page hit count:
_xLogFileName = "./loging.log";
/* File operation starts here */
_xFile = fopen ( _xLogFileName, "r" );
if ( _xFile != NULL )
{
//read a line upto the end of the file
while ( fgets ( _xFileLine , sizeof _xFileLine, _xFile ) != NULL )
{
// #_xTiemInStr --> cur date in YYYY-MM-DD format to identify todays log
if(strstr(_xFileLine, _xTiemInStr) != NULL) {
if(strstr(_xFileLine, _xLoginHitString) != NULL) {
_xLoginPageCounter = _xLoginPageCounter + 1;
}
}
}
printf("Usage:Total Login Page Hit :%d\n",_xLoginPageCounter );
fclose ( _xFile );
return 0;
}
else
{
printf("error\n");
perror ( _xLogFileName );
return 3;
}
return 0;
Now I placed the a.out file in /usr/lib/nagios/plugin folder and placed the "loging.log" file in the same folder- for both chmod 777 done. I can run the plugin from command line but when I integrate the same with nagios then it is giving unknown status and printing the "error" from else part-- can anyone please help
2nd part
In addition I added the following code to determine from where the nagios is running?
char cwd[1024];
_xLogFileName1 = "loging.log";
if (getcwd(cwd, sizeof(cwd)) != NULL)
_xLogFileName = strcat( cwd,_xLogFileName1);
printf("FileName : %s\n", _xLogFileName);
and it is printing /loging.log in status information?
So where I have to actually place the file, my nagios is running from /etc/nagios3 and I placed the loging.log file there also but still it is not working.
UPDATE: Now it is working, as I print the pwd by the c program and find that it is running from my root (/) dir , so I placed the loging.log file there and now it is working fine.
You should be passing the full path to the file and storing that in '_xLogFileName1', and not just the file name alone. Strongly recommend that you do not copy files into the root directory.
Knowing web logs, it is very likely that the date string you're looking for is at the front of the line. So I'd recommend using 'strnstr' instead of 'strstr'. It would greatly improve your search speed.

Input bar at console bottom in C

Window bottom
Some applications like vim, mutt, aptitude contain
a top window section for output and
a bottom section for the user to type in or for status display.
(Suppose there is one child process to output and another one to take user input. The purpose is to allow for updated output at the same time as you are typing the input or viewing the status.)
Actions Undo Package Resolver Search Options Views Help
C-T: Menu ?: Help q: Quit u: Update g: Download/Install/Remove Pkgs
|
|
|
|
|
┌─────────────┐ |
│Loading cache│ |
└─────────────┘ |
|
|
|
|
|
|
|
--------------------------------------------------------------------------- |
Initialising package states 100% |
+-------------------------------------------------------+
| some output here |
| |
| |
| |
| |
| |
|-------------------------------------------------------+
|:input here |
+-------------------------------------------------------+
Ncurses tutorial does not mention this to be obviously possible.
A query on "c print to {window,screen,terminal,console} bottom" at StackOverflow or at a web search engine isn't helpful.
Can this be done in C programmatically?
Discarding input
While some of the solutions below can move character to a given position, there is the problem that it may be needed to discard user input rather than leaving it on screen. Like in vim's case, typing ":w" and pressing Enter does not leave a ":w" on the screen.
Update. This is found here: How to delete text after getstr() c++ ncurses
Window focus - the UNSOLVED PART OF THE PROBLEM
While you are typing the input at window bottom and the text at the top changes, we see the problem of moving the focus back to the bottom. This is absent in the solutions as of December 29.
Update 1. Just attempting to
remember the previous cursor position, then
display the output, and then
restore the position
is not an easy solution: as these are different processes, attempts to retrieve cursor position don't affect the changes that happened during the other process execution.
Eg if parent takes input then the child doesn't know how the cursor position changed and can't restore the cursor position after performing a line of output at another part of the console.
Implementing this would involve some inter process communication and if there are other solutions they could be preferable.
Related
Get Input from keyboard without waiting for input Related, but not specific enough.
How to make a chat like UI using Python Urwid? Urwid for Python which does the job (per J.F. Sebastian in the comment below). Unfortunately not in C.
Using the standard libraries, there's no way to do that; using ncurses, as you already suggest, it is easily possible; I think this tutorial explains it quite nicely.
Using ANSI escape sequence it's possible to control the position of the cursor:
void gotoxy(int x, int y) {
printf("\033[%d;%dH",x,y);
}
So once you figure out the terminal height and width then you can use that function to position the cursor wherever you like and print stuff.
This answer suggests a slightly different approach, but it avoids a lot of complication you'd introduce by using the current method. I hope it is possible to implement these simplifications.
Use termio to turn off canonical mode.
Sample code (here) will show you exactly how to set up such an input loop. This sample 'polls-and-sleeps' which could mean a delay unless you reduce the sleep. Also I think you can use termio to set a timeout (wait a second and return 'no input' or give me the input NOW if it comes earlier). But if you are really going to monitor another process, polling might be the more flexible option.. You can really poll 30x a second and live with the .00001% processor hit it is going to cause, but you will love the simplicity and bug prevention it gives.
Avoid multiple threads and processes like the plague
You don't need to use 2 processes/threads if the only problem you are trying to solve is the fact that getch() blocks. That would be required if it were impossible to prevent the input functions from blocking. 'Canonical' (rules based) means all sorts of handy 'rules' are in effect, like, 'don't give the input to the program until ENTER is hit'. For a full screen console app you want to turn off all the rules and do everything yourself.
Put the main thread in charge of the window...
... Then you can just use the ansi escape csi codes to position the cursor back to where you want it. Caveat: you can't write to the lower-right box in the screen. Everything will scroll.
There is an annoying thing in MS windows programming where only the thread that creates a window can safely update it. There is actually a reason for this. Whether you're talking console, or windowing system. sooner or later, if you have multiple threads/processing hitting one output device, you'll interrupt an escape sequence (or have to make extra code to manage this which is a bad thing), be fighting for the output 'port', etc. you need one thread to manage the output.
if you really care about what some other thread or process is doing, just check it in your main console management loop. For example of you have another process that you just want to report its progress, start it from your program and capture its stdouput and look at that; another thread, just lock something shared you can check in your polling routine. Heck if it's just a byte and it's only used for statuses, don't even lock the damn thing. You can throw in a couple of GOTO's too, just to show your individuality :-)
caveat I don't know that ncurses would play well with you if you are manually messing with termio? I would guess it wants to do that itself. Never tried mixing. If your app is simple you could go it alone without the help, especially if you can wrestle ncurses into doing what you want. I'm no expert on those apps you mention but I'd bet they are micromanaging everything.
I had a similar issue a few weeks ago while writing an IRC client that runs in the terminal. I wrote it using the Windows conio library, but I'm fairly sure this should be applicable to curses. The idea is that console output is handled by a single thread, and console input is handled in a separate thread. Basically, all you need is a loop that pushes the return of getch() onto a mutexed FIFO that runs for the duration of the program. In the display thread, you can pop the keypresses off the FIFO and handle them however you like. You can't use a standard function like fgets(), but it's a very solid solution to your problem. I can provide the full (messy) source on request.
Edit: alright, well here's the relevant code from the FIFO pushing:
bool keyqueuewriting = false;
std::deque<int> keyqueue;
void grabkey( void* in )
{
int t;
while( true ){
t = getch();
#ifdef _WIN32
if( t == 224 || t == 0 )
{
t += getch() << 8;
}
#else
int off = 8;
if( t == 27 ){
int e = getch();
t += e << off;
off += 8;
while( e ==91 || (e >= '0' && e <= '9') || e == ';' )
{
e = getch();
t += e << off;
off += 8;
}
}
#endif
while( keyqueuewriting ){}
keyqueuewriting = true;
keyqueue.push_back( t );
keyqueuewriting = false;
}
}
And Handling:
while( keyqueuewriting ){}
keyqueuewriting = true;
while( keyqueue.size() > 0 )
{
shouldsleep = false;
int t = keyqueue.front();
keyqueue.pop_front();
switch( t )
{
case K_BACKSPACE:
if( pos > 0 ){
for( int i = pos-1; input[i] != 0; i++ ){input[i] = input[i+1];}
movecursorback( 1 );
pos -= 1;
} break;
case K_LEFT: if( pos > 0 ){ movecursorback( 1 ); pos -= 1; } break;
case K_RIGHT: if( input[pos] != 0 ) {movecursorforward( 1 ); pos += 1;} break;
case K_HOME: { gotoxy(0,SCREENHIG-1); pos = 0; } break;
case K_END: { int a = strlen( input ); /*gotoxy( 79,39 );*/ pos = a;} break;
case 3: exit(3); break;
default: if( t >= 0x20 && t < 0x80 ){
int a = strlen( input );
if( a > 998 )
a = 998;
int deadcode = 1;
input[999] = 0;
for( int i = a+1; i > pos; i-- ){input[i] = input[i-1];}
input[ pos ] = t;
movecursorforward( 1 );
pos++;
} break;
}
change = bufpos[curroom] - bufprev;
if( pos > 998 ) pos = 998;
if( pos - mescroll < 1 ) {mescroll += (pos-mescroll-1); gotoxy( pos-mescroll, SCREENHIG-1 );}
if( pos - mescroll > 78 ) {mescroll += (pos-mescroll-78); gotoxy( pos-mescroll, SCREENHIG-1 );}
if( mescroll < 0 ) {mescroll = 0; gotoxy( 0, SCREENHIG-1 ); }
savexy();
gotoxy( 0, SCREENHIG-1 );
char y = (input+mescroll)[79];
(input+mescroll)[79] = 0;
printf( "%s ", input+mescroll );
(input+mescroll)[79] = y;
returntosaved();
change2 = change;
bufprev = bufpos[curroom];
}
keyqueuewriting = false;
Yes, it uses std::deque. That should be the only C++ specific thing though. Just replace it with a C compatible FIFO.
The entire client can be found here.
Yes, it DOES compile in Linux, but it doesn't work. I never bothered to figure out how ncurses should be used before I started work on it.

How to get Module HANDLE from func ptr in Win32?

I'm working on native call bindings for a virtual machine, and one of the features is to be able to look up standard libc functions by name at runtime. On windows this becomes a bit of a hassle because I need to get a handle to the msvcrt module that's currently loaded in the process. Normally this is msvcrt.dll, but it could be other variants as well (msvcr100.dll, etc) and a call to GetModuleHandle("msvcrt") could fail if a variant with a different name is used.
What I would like to be able to do is a reverse lookup, take a function pointer from libc (which I have in abundance) and get a handle to the module that provides it. Basically, something like this:
HANDLE hlibc = ReverseGetModuleHandle(fprintf); // Any func from libc should do the trick
void *vfunc = GetProcAddress(hlibc);
Is there such a thing in the win32 API, without descending into a manual walk of process handles and symbol tables? Conversely, if I am over-thinking the problem, is there an easier way to look up a libc function by name on win32?
The documented way of obtaining the module handle is by using GetModuleHandleEx.
HMODULE hModule = NULL;
if(GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, // behave like GetModuleHandle
(LPCTSTR)address, &hModule))
{
// hModule should now refer to the module containing the target address.
}
MEMORY_BASIC_INFORMATION mbi;
HMODULE mod;
if (VirtualQuery( vfunc, &mbi, sizeof(mbi) ))
{
mod = (HMODULE)mbi.AllocationBase;
}
Unfortunately you will have to walk through modules as you feared. It's not too bad though. Here is the idea, some code written in notepad:
MODULEENTRY32 me = {0};
HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, 0 );
me.dwSize = sizeof me;
Module32First( hSnapshot, &me );
if( me.modBaseAddr <= funcPtr &&
( me.modBaseAddr + me.modBaseSize ) > funcPtr ) {
...
break;
}
do {
} while( Module32Next( hSnapshot, &me ) );
CloseHandle( hSnapshot );

Monitor directory for new files only

I'd like to monitor a directory for new files from a C app. However, I'm not interested in modified files, only in new files. Currently I'm using readdir/stat for that purpose:
while ( (ent = readdir(dir)) != NULL ) {
strcpy(path, mon_dir);
strcat(path, "/");
strcat(path, ent->d_name);
if ( stat(path, &statbuf) == -1 ) {
printf( "Can't stat %s\n", ent->d_name );
continue;
}
if ( S_ISREG(statbuf.st_mode) ) {
if ( statbuf.st_mtime > *timestamp ) {
tcomp = localtime( &statbuf.st_mtime );
strftime( s_date, sizeof(s_date), "%Y%m%d %H:%M:%S", tcomp );
printf( "%s %s was added\n", s_date, ent->d_name );
*timestamp = statbuf.st_mtime;
}
}
}
Any idea how I can detect newly created files on Linux AND Solaris 10 without keeping a list of files?
Cheers,
Martin.
gamin provides an abstraction around system dependant file notification apis for many *nixes , and it's included in many linux distros by default.
For linux, you could use the linux specific inotify api.
Win32 has a similar API via FindFirstChangeNotification
The solution is to store the last access time in a global variable and pick the latest files with a filter to scandir():
int cmp_mtime( const struct dirent** lentry, const struct dirent** rentry ):
Stat (*lentry)->d_name (extended by path, but that's a detail only)
ltime = statbuf.st_mtime;
Stat (*rentry)->d_name (extended by path, but that's a detail only)
rtime = statbuf.st_mtime;
if ( ltime < rtime ) return -1;
else if ( ltime > rtime ) return 1;
return 0;
int selector( const struct dirent* entry ):
Stat entry->d_name (extended by path, but that's a detail only)
If not normal file then return 0
If stat.st_mtime > lastseen then return 1 else return 0
Main:
Init global time variable lastseen
scandir( directory, &entries, selector, cmp_mtime );
Process list of entries
lastseen := mtime of last entry in list
There is probably no better way with Solaris 10 outside interfacing with either the dtrace command or libdtrace (not recommended). On SunOS 5.11 based OSes (eg: OpenSolaris, Solaris 11 Express, ...), you can just use the File Event Notification framework.
On MacOS X there is a file monitoring API and the provided sample code shows how to find which files have changed.
You could use FAM - File Alteration Monitor for this.
one trick may be to set the archive bit for handled files.
Edith says:
if nothing else from the other answeres helpes, you may play with chmod() instead.
Was researching the same topic on Solaris and found the example of the watchdir app, to be used from within scripts, as in
watchdir /foo/bar
which will perform a blocking wait until something happens on the watched directory.
Link: https://solarisrants.wordpress.com/2013/07/24/solaris-file-event-notification/
I know you were asking for a solution from C but in fact Java (now) has a cross-platform class for this. You can read more about it here. Also see documentation for the WatchService class which is the central class of Java's file change notification ability.
Perhaps there's some documentation somewhere as to how Java accomplishes this on the various platforms ?
From the little I understand Java uses the OS's native file change notification API on Linux, Solaris and Windows and then in addition also implements a fallback method which is based on polling and which will work on any platform.

Resources