run a program with tcsetattr raw mode in background - termios

I need to run a program as is in the background. The catch is that the program does a tcsetattr() call and sets the raw mode as following :
struct termios tio;
if (tcgetattr(fileno(stdin), &tio) == -1) {
perror("tcgetattr");
return;
}
_saved_tio = tio;
tio.c_iflag |= IGNPAR;
tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF);
tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL);
// #ifdef IEXTEN
tio.c_lflag &= ~IEXTEN;
// #endif
tio.c_oflag &= ~OPOST;
tio.c_cc[VMIN] = 1;
tio.c_cc[VTIME] = 0;
if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) == -1)
perror("tcsetattr");
else
_in_raw_mode = 1;
The implication is that as soon as I run my program with '&' and press enter, the process shows 'stopped'. Even the ps aux output shows 'T' as the process state which means it is not running.
How can I make this program running in background.Issue is I cant modify this program.
For complete details, actually I need to use ipmitool with 'sol' as a background process.
Any help is appreciated !
Thanks

It is hard to give a complete answer on what is going wrong without knowledge of how ipmitool is actually used/started but I'll try to add some details.
So all the options in the question are needed to adjust i/o for the program (see comments):
// ignorance of errors of parity bit
tio.c_iflag |= IGNPAR;
// removed any interpretation of symbols (CR, NL) for input and control signals
tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF);
// switch off generation of signals for special characters, non-canonical mode is on,
// no echo, no reaction to kill character etc
tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL);
// removed recognition of some spec characters
// #ifdef IEXTEN
tio.c_lflag &= ~IEXTEN;
// #endif
// disable special impl-based output processing
tio.c_oflag &= ~OPOST;
// minimum number of characters to read in non-canonical mode
tio.c_cc[VMIN] = 1;
// timeout -> 0
tio.c_cc[VTIME] = 0;
// accurately make all the adjustments then it will be possible
if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) == -1)
perror("tcsetattr");
else
_in_raw_mode = 1;
More details on terminal configuring are here and here.
In other words this part of code configures the standard input of the process to a "complete silent" or "raw" mode.
In spite of the lack of the information you may also try "kill -cont %PID%" to the process or try to provide some file as standard input for it.

Related

How to check if process is already running by name in JXA

Using /usr/bin/osascript JS to automate my task, struggling with a check if process is already running or not:
const app = Application.currentApplication()
app.includeStandardAdditions = true
function run(args) {
const query = args[0]
let response = 'Wrong command passed'
if (query === 'on') { // need to check if process named "asdf" is already running
response = 'Process turned ON'
} else if (query === 'off') { // need to check if process named "asdf" is already running
response = 'Process turned OFF'
}
return response
}
JXA documentation could be better, i want to implement a check in an if construction. I've tried to make it using:
const se = Application('System Events')
const process = se.processes.byName('processname')
But it has no effect.
Solved myself:
const PNAME = `ps aux | grep processname | grep -v grep | wc -l | xargs echo`
Getting "processname", if it's running, it returns 1, otherwise 0.
Were I to call out to a shell to do this, I would aim to make it as an efficient combination of commands as possible. xargs, wc, and the second pipe into grep are all unnecessary: if grep processname matches, the exit status of the command will be 0, and in all other cases, non-zero. It looks like the only reason you pipe through to those other programs is because you didn't utilise the most effective set of program options when calling ps:
const PNAME = 'ps -Acxo comm | grep processname > /dev/null; echo $(( 1 - $? ))'
Even this use of grep is unnecessary, as bash can pattern match for you:
const PNAME = '[[ "$( ps -Acxo comm )" =~ processname ]]; echo $(( 1 - $? ))'
But, putting that to one side, I wouldn't get a shell script to do this unless I were writing a shell script. JXA is very capable of enumerating processes:
sys = Application('com.apple.SystemEvents');
sys.processes.name();
Then, to determine whether a specific named process, e.g. TextEdit, is running:
sys.processes['TextEdit'].exists();
which will return true or false accordingly.
Solved myself:
const PNAME = `ps aux | grep processname | grep -v grep | wc -l | xargs echo`
Getting processname, if it's running, it returns 1, otherwise 0. All what's left to do is:
if (app.doShellScript(PNAME) < 1) {
// do something
} else {
// do something else
}

How to get Monitor Handle from Index or Name?

A C++ version (How can I get an HMONITOR handle from a display device name?) has no solution provided (at least in my circumstances that require non-OOP code such as in AutoIt).
I'm adapting an AutoIt script that uses WinAPI functions to support multi-monitor Windows 7+ systems. I can provide either monitor/device Name or it's Index, but some functions require an HMONITOR handle instead.
I cannot get the HMONITOR by Window or by pixel or point, which would be quite easy. No, I need to get the handle from name or index only, and I need a non-OOP solution (ideally AutoIt & WinAPI calls but non-OOP pseudo-code would be fine).
The function below returns an array of the following structure:
| hMonitor | xPosMonitor | yPosMonitor | widthMonitor | heightMonitor |
| 0x00010001 | 0 | 0 | 1366 | 768 |
| 0x0001024 | 1366 | -236 | 1920 | 1080 |
Code:
#include-once
#include <Array.au3>
#include <WinAPIGdi.au3>
Func _getMonitorInfos()
Local $aPosition, $aMonitorData = _WinAPI_EnumDisplayMonitors()
If IsArray($aMonitorData) Then
ReDim $aMonitorData[$aMonitorData[0][0] + 1][5]
For $i = 1 To $aMonitorData[0][0] Step 1
$aPosition = _WinAPI_GetPosFromRect($aMonitorData[$i][1])
For $j = 0 To 3 Step 1
$aMonitorData[$i][$j + 1] = $aPosition[$j]
Next
Next
Return $aMonitorData
EndIf
EndFunc
Global $aMonitorData = _getMonitorInfos()
_ArrayDisplay($aMonitorData)
hMonitor value is contained by the array $aMonitorData[1][1].

How to detect if video is running on Mac?

I want to know the idle time of Mac. Currently I use this code
CFMutableDictionaryRef properties = 0;
CFTypeRef obj;
mach_port_t masterPort;
io_iterator_t iter;
io_registry_entry_t curObj;
IOMasterPort(MACH_PORT_NULL, &masterPort);
/* Get IOHIDSystem */
IOServiceGetMatchingServices(masterPort, IOServiceMatching("IOHIDSystem"), &iter);
if (iter == 0)
{
return -1;
}
else
{
curObj = IOIteratorNext(iter);
}
if (IORegistryEntryCreateCFProperties(curObj, &properties, kCFAllocatorDefault, 0) == KERN_SUCCESS && properties != NULL)
{
obj = CFDictionaryGetValue(properties, CFSTR("HIDIdleTime"));
CFRetain(obj);
}
else
{
return -1;
}
uint64_t tHandle = 0;
if (obj)
{
CFTypeID type = CFGetTypeID(obj);
if (type == CFDataGetTypeID())
{
CFDataGetBytes((CFDataRef) obj, CFRangeMake(0, sizeof(tHandle)), (UInt8*) &tHandle);
}
else if (type == CFNumberGetTypeID())
{
CFNumberGetValue((CFNumberRef)obj, kCFNumberSInt64Type, &tHandle);
}
else
{
// error
tHandle = 0;
}
CFRelease(obj);
tHandle /= 1000000; // return as milliseconds
}
else
{
tHandle = -1;
}
CFRelease((CFTypeRef)properties);
IOObjectRelease(curObj);
IOObjectRelease(iter);
return (double)tHandle;
However, I want the idle time to keep 0 if any video is running.
Is there any code sample or library to check? (include video running on iTunes, VLC, youtube on browser or any other video applications)
I can interpret your question several ways:
How to determine when the screensaver kicks in?
Check the following script (original answer):
#!/bin/bash
systemSleepTimeMinutes=`pmset -g | grep "^[ ]*sleep" | awk '{ print $2 }'`
if [ $systemSleepTimeMinutes -gt "0" ]; then
systemSleepTime=`echo "$systemSleepTimeMinutes * 60" | bc`
devicesIdleTime=`ioreg -c IOHIDSystem | awk '/HIDIdleTime/ {print $NF/1000000000; exit}'`
secondsBeforeSleep=`echo "$systemSleepTime - $devicesIdleTime" | bc`
echo "Time before sleep (sec): $secondsBeforeSleep"
exit 0
else
echo "The system is set to not sleep."
exit 0
fi
In case the screensaver is suppressed, for example by VLC, the result is:
The system is set to not sleep.
Otherwise it returns the time until the screensaver kicks in, for example:
Time before sleep (sec): 899.88056
Run the script above through NSTask or NSAppleScript and parse the result.
Please note "sleep" may also rever to the screensaver, depending on which one kicks in first.
How to determine wether the screensaver is suppressed?
The following line does the trick:
pmset -g | grep "^[ ]*sleep" | awk '{ print $2 }'
In case the screensaver is suppressed it returns 0.
Run the line above through NSTask or NSAppleScript and parse the result.
How to suppress the screensaver?
The official Apple documentation (including code snippet):
How can I prevent system sleep while my application is running?
EDIT (Response to comment)
However, is there a built-in method that works the same as this script?
I'm not familiar with such a method. I actually doubt it exists.
Quick NSAppleScript example:
NSString *source = #"do shell script \"pmset -g | grep \\\"^[ ]*sleep\\\" | awk '{ print $2 }'\"";
NSAppleScript *script= [[NSAppleScript alloc] initWithSource:source];
NSDictionary *scriptError = nil;
NSAppleEventDescriptor *descriptor=[script executeAndReturnError:&scriptError];
if(scriptError) {
NSLog(#"Error: %#",scriptError);
} else {
if ([[descriptor stringValue] intValue] == 0) {
NSLog(#"Screensaver suppressed.");
} else {
NSLog(#"Screensaver not suppressed.");
}
}
Just don't be reticent about using NSTask or NSAppleScript :)
Better yet, watch for com.apple.screensaver.didstart and com.apple.screensaver.didstop

fopen and open produce files with different file permissions

These two code snippets produce files with different file-permissions. Example 1 creates the expected default file-permissions but Example 2 does not. What's the explanation for this?
OS: Mac OS X version: 10.6.4
Xcode version: 3.2.2, 64 bit
// Example 1
FILE *fh1 = fopen("Test1.txt", "w+x");
if (fh1) {
fwrite("TEST1", 1, 5, fh1);
fclose(fh1);
}
Creates:
-rw-r--r-- 1 me staff 5 29 Jul 00:41 Test1.txt
// Example 2
int fh2 = open("Test2.txt", O_EXCL | O_CREAT | O_WRONLY);
if (fh2 >= 0) {
write(fh2, "TEST2", 5);
close(fh2);
}
Creates:
---------- 1 me staff 5 29 Jul 00:41 Test2.txt
When you use O_CREAT you need to add a third argument to open, the mode. For instance:
int fh2 = open("Test2.txt",
O_EXCL | O_CREAT | O_WRONLY,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
This would be equivalent to 0666. Be aware that this mode is then masked by the process's umask, meaning the permissions you specify will usually be reduced a bit. A typical umask is 0022, which would result in a mode of 0666 & ~0222 = 0644, i.e. -rw-r--r--.
From man open:
The oflag argument may indicate that the file is to be created if it does not exist (by specifying the O_CREAT flag). In this case, open requires a third argument mode_t mode; the file is created with mode mode as described in chmod(2) and modified by the process' umask value (see umask(2)).
int open(const char *pathname, int flags, mode_t mode);
The argument mode specifies the permissions to use in case a new file is created. See http://linux.about.com/od/commands/l/blcmdl2_open.htm
In your case, you'll want to set mode with value 0644

Windows Equivalent of 'nice'

Is there a Windows equivalent of the Unix command, nice?
I'm specifically looking for something I can use at the command line, and not the "Set Priority" menu from the task manager.
My attempts at finding this on Google have been thwarted by those who can't come up with better adjectives.
If you want to set priority when launching a process you could use the built-in START command:
START ["title"] [/Dpath] [/I] [/MIN] [/MAX] [/SEPARATE | /SHARED]
[/LOW | /NORMAL | /HIGH | /REALTIME | /ABOVENORMAL | /BELOWNORMAL]
[/WAIT] [/B] [command/program] [parameters]
Use the low through belownormal options to set priority of the launched command/program. Seems like the most straightforward solution. No downloads or script writing. The other solutions probably work on already running procs though.
If you use PowerShell, you could write a script that let you change the priority of a process. I found the following PowerShell function on the Monad blog:
function set-ProcessPriority {
param($processName = $(throw "Enter process name"), $priority = "Normal")
get-process -processname $processname | foreach { $_.PriorityClass = $priority }
write-host "`"$($processName)`"'s priority is set to `"$($priority)`""
}
From the PowerShell prompt, you would do something line:
set-ProcessPriority SomeProcessName "High"
Maybe you want to consider using ProcessTamer that "automatize" the process of downgrading or upgrading process priority based in your settings.
I've been using it for two years. It's very simple but really effective!
from http://techtasks.com/code/viewbookcode/567
# This code sets the priority of a process
# ---------------------------------------------------------------
# Adapted from VBScript code contained in the book:
# "Windows Server Cookbook" by Robbie Allen
# ISBN: 0-596-00633-0
# ---------------------------------------------------------------
use Win32::OLE;
$Win32::OLE::Warn = 3;
use constant NORMAL => 32;
use constant IDLE => 64;
use constant HIGH_PRIORITY => 128;
use constant REALTIME => 256;
use constant BELOW_NORMAL => 16384;
use constant ABOVE_NORMAL => 32768;
# ------ SCRIPT CONFIGURATION ------
$strComputer = '.';
$intPID = 2880; # set this to the PID of the target process
$intPriority = ABOVE_NORMAL; # Set this to one of the constants above
# ------ END CONFIGURATION ---------
print "Process PID: $intPID\n";
$objWMIProcess = Win32::OLE->GetObject('winmgmts:\\\\' . $strComputer . '\\root\\cimv2:Win32_Process.Handle=\'' . $intPID . '\'');
print 'Process name: ' . $objWMIProcess->Name, "\n";
$intRC = $objWMIProcess->SetPriority($intPriority);
if ($intRC == 0) {
print "Successfully set priority.\n";
}
else {
print 'Could not set priority. Error code: ' . $intRC, "\n";
}

Resources