Why doesn't the system() function work? - c

As I Know , in cmd , when we want to switch drives we write "[drive]:" exemple :
when we want to switch to D:\ we type
D:
and i try this and it work .
But now , I want to apply this process in my C program , so I used the famous "system " command and i type :
system("D:");
and i have some code after that , when i try to execute it , it write
the specified path was not found.
so i tried to see if the system comand really work and i add another system comand like this :
system("chdir");
to verify the working directory and when I execute it , it show me the path of the executable that's mean that the system("D:"); dont work.
any solution please

Probably because system() starts a new instance of cmd.exe, which runs your command and then exits. Thus, it doesn't hold state between invocations, unlike when you run a single instance and give it multiple commands interactively.
One way of working around this is hinted at by cmd.exe's help text:
Note that multiple commands separated by the command separator '&&'
are accepted for string if surrounded by quotes.
So, you should be able to run a command like "d: && chdir" to do both operations in a single invocation of cmd.exe.

Related

Obtain all filenames in a directory using vim

This is the algorithm of the code:
for every *file* in a directory
nnoremap ,*file* <C-o>:read $HOME/*file*
end
So the problem is, I don't know how to code the "for every file in a directory".
PS: I am new to vim and I don't know if it's possible
You're looking for glob() function. -> glob($HOME.'/*')
I'm not sure this is a good idea, but hey, who am I to judge? :)
Apart from glob() (see answer from #LucHermitte), you also need :execute:
execute 'nnoremap ,' . file . ' <C-o>:read $HOME/' . file
(or more elegantly with printf():)
execute printf('nnoremap ,%s <C-o>:read $HOME/%s', file, file)
Description
Vimscript is evaluated exactly like the Ex commands typed in the : command-line. There were no variables in ex, so there's no way to specify them. When typing a command interactively, you'd probably use <C-R>= to insert variable contents:
:sleep <C-R>=timetowait<CR>m<CR>
... but in a script, :execute must be used. All the literal parts of the Ex command must be quoted (single or double quotes), and then concatenated with the variables:
execute 'sleep' timetowait . 'm'

Cygwin bash.exe cannot run make, works in cmd.exe

I am having issues running any make command in a Cygwin bash terminal. The following is the error that is returned.
"'ygdrive' is not reconized as an internal or external command, operable program or batch file"
However I am able to properly run the make file using cmd.exe, any help would be appreciated.
Thanks Eric E
Looks like you are referencing a path in some recipe with \cygdrive\<letter>\.... bash interprets a single backslash as an escape character and therefore ignores the c directly following it.
Solutions:
If you want the Makefile to be portable to Unix systems, just write forward slashes in paths like this /cygdrive/<letter>/....
If you instead want the Makefile to be compatible with cmd, too, use double backslashes like \\cygdrive\\<letter\\... -- both bash and cmd will understand this.
In any case, such a path should be in a make variable because it is probably completely different on another machine.
The above solution by Felix might be the answer for others, however the solution for my problem was removing "SHELL=C:/Windows/System32/cmd.exe" from the top of my Makefile..

Run Unix Commands to DOS equivalent in C Language

In Operating System concept i want to write a C program to make Unix command works as DOS commands.
It Means when ever i press Unix Command like ls -which is used for Display list of Files- it works like Dir command in DOS.Could you please help me out with this?
Starting with the ls command as example, take input from user for the command. If the command is ls call a windows function that will display the content of the current working directory(). For ls,
you need to get first the current working directory. GetCurrentDir() for windows will be your first step. This will help How do I get the directory that a program is running from?
Then you can list the files in directory like this https://msdn.microsoft.com/en-us/library/windows/desktop/aa365200(v=vs.85).aspx. But you do need the output of first step.
Other commands can also be implemented like this

Spawning multiple copies of a program from C code and redirecting the output to a file

I am working on modifying a command-line program that is written in MSDN C and Pro*C (Oracle pre-compiler to write in-line SQL and PL/SQL statements) so that multiple copies can be spawned and process concurrently. It is a database-heavy program and concurrency issues are mostly taken care of on the database side, so we thought it would be easier to just run multiple copies than to alter the program to run truly multi-threaded.
Anyway, we rely on printf() and output piping to write the program's output to log files for debugging purposes. I am having trouble launching separate copies of the exe that appropriately write to their own log files. I have played a lot the exec() and system() functions to get different copies of the EXE to launch and write to logs. The closest I have gotten to work is using a C line such as:
system("start cmd /k call [program commmand and args] > log_file.txt");
This works great - spawns separate command windows and spawns separate copies of the program for the appropriate data-sets. The only problem is that the command windows stay open after the program has finished executing. Some of our clients run this program frequently on a scheduler, and having to manually close all of the command windows would not be acceptable for them.
Other similar commands that I have tried to get to what I am looking for are like:
system("[program command and args] > log_file.txt");
or
exec("[program command and args] > log_file.txt");
Both of these will execute a new copy of the program, write to the log files just fine, and close the command window when the process is finished, but the commands wait for the newly spawned EXE to finish running to return control to the launching executable. This obviously prevents multiple copies from running at the same time, which was the whole goal to begin with, so this is not a good solution either.
I also played with trying to add an "exit" command to the end of the command line windows by appending to the exiting command line, hoping that I could get the command window to close, like this:
system("start cmd /k call \"[program commmand and args] > log_file.txt; exit\"");
to no avail. I tried some similar variations, but could never the correct behavior.
I would greatly appreciate any advice that could get the correct behavior. I am basically looking to launch multiple copies of an executable that run concurrently and write to separate log files, using the " > log_file.txt" output-piping feature of the windows command prompt. I would like to avoid having to use threading libraries (It's been awhile and I'm under time constraints) or using something other than printf() and output piping, since these print statements are used throughout the application and it would be a large effort to effectively replace all of the function calls at this point in time.
Anyone know a way to get the command windows to close using system() calls, or have some other easy method of solving the problem? Keep in mind that there are some time constraints involved, so I'm not necessarily looking for the best way to do this, but the quickest and easiest. I will have the opportunity to implement proper logging functionality soon, but I need to get past this problem first.
You said your first solution works great except it doesn't close the command window after the program is done executing.
system("start cmd /k call [program commmand and args] > log_file.txt");
The /K option states Carries out the command specified by string but remains
The /C option states Carries out the command specified by string and then terminates
You should be able to change your original solution to use the /C option as so
system("start cmd /C call [program commmand and args] > log_file.txt");

.bat to .sh converting for SQL*Loader Start on UNIX PC

I have a simple .bat file
#echo; set nls_lang=russian_cis.ru8pc866
#echo off
SET NLS_NUMERIC_CHARACTERS=. '
sqlldr.exe userid=PRB/0611#TSESTDB control=control_file.ctl LOG=fdb_log.log errors=100
cmd
and i need to convert to .sh file for running on the UNIX based pc.
I began to read "BASH Programming - Introduction HOW-TO" (is it suitable for beginners?), but it is a episodical task and dead line comes.
Could anybody help me to convert file? Thanks a lot!!!
rewriting your script.
#!/bin/bash
# #echo;
# set nls_lang=russian_cis.ru8pc866
export NLS_LANG=russian_cis.ru8pc866
# not needed #echo off
# SET NLS_NUMERIC_CHARACTERS=. '
export NLS_NUMERIC_CHARACTERS='.'
PATH="/path/to/sqlDir/install:${PATH}"
# sqlldr.exe userid=PRB/0611#TSESTDB control=control_file.ctl LOG=fdb_log.log errors=100
sqlldr userid=PRB/0611#TSESTDB control=control_file.ctl LOG=fdb_log.log errors=100
# ? cmd
I've left your code in, but commented out (using the shell comment char '#'). The uncommented lines are the 'translation' of .bat syntax into Linux/Unix bash/shell syntax.
There some things above that you may need to fix:
You'll have to include the correct value in the resetting of PATH,
note that the value there is strictly to illustrate the issue.
export is used so that variables set in the current shell (the
shell script) are visible to child processes that run from the shell
script, in this case the important one being sqlldr
I'm not sure what values you really need assigned to
NLS_NUMERIC_CHARACTERS. Note that by quoting with the single-quote
char ' available to the shell, you should get exactly the value
used that you intended. If '*' or other reg-exp chars are used, this
may cause problems.
You may find that sqlldr.exe has a different name altogether. The
linux/unix convention for executable commands does not require the
.exe extension, so I have used sqlldr. Just use the full name of
the program you find in the installed directory.
The line with #!/bin/bash needs to be the first line in the file, with no leading spaces.
You'll also need to inform your OS that the script is intended to be executable. From a bash cmd line, IN the directory that contains this script, do
chmod 755 mySQLLDR_runningScript
Finally, not sure why you have cmd at the end of your .bat file, to open a new window? You'll need to experiment on your system to find the correct cmd to do that. Maybe xterm.
I hope this helps.

Resources