system() does not work - c

My program reads and stores standard input into a char array cmd and then call system(cmd). I printed out cmd and its content is what I expected. But system(cmd) does not save the content in report.log. I tried with a literal string stored in cmd2, and this time it worked. So what is wrong with system(cmd)?
And I am using Windows 8.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <time.h>
#define MAXLEN 100
char *now(){
time_t t;
time(&t);
return asctime(localtime(&t));
}
int main(int argc, char *argv[])
{
char comment[80];
char cmd[120];
fgets(comment, 80, stdin);
sprintf(cmd, "echo '%s %s' >> report.log", comment, now());
printf("%s", cmd); // content of cmd is what I expect
system(cmd); // does not work, why?
char cmd2 = "echo 'Hello world' >> report.log";
system(cmd2); // work
return 0;
}

Your problem maybe with the excess \ns present in your inputs to sprintf().
fgets() scans and stores the \n from the stdin. You need to get rid of that \n and replace that with a null.
asctime() returns a ctime() return style string, again ended with a newline \n. You need to remove (replace) that too.
You can check the following code for your reference.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
#define MAXLEN 100
char *now(){
time_t t;
time(&t);
return asctime(localtime(&t));
}
int main(int argc, char *argv[])
{
char comment[80] = {0};
char cmd[120] = {0};
char * timestring = NULL; //initialize local variables, good practice
fgets(comment, 80, stdin);
comment[ strlen(comment) -1] = 0; //reomve the trailing \n taken by fgtes(), replace by null
timestring = now();
timestring[strlen(timestring)-1] = 0; //remove the \n from ctime() return style string, replace b null
sprintf(cmd, "echo '%s %s' >> report.log", comment, timestring);
printf(">> The string is : %s\n", cmd);
system(cmd); // should work now.. :-)
return 0;
}

Related

If statement is not printing out on my system call

I input age as 30 but its not printing my if statement. Can i know why ? Thanks
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#define BUFFSIZE 512
int main()
{
int a;
char *buffer[BUFFSIZE];
write(1,"Please Enter your age: ",23);
a=read(0,*buffer,100);
if(a>21)
write(1,"You are an adult",16);
return 0;
}
This
char *buffer[BUFFSIZE];
declares an array of uninitialized pointers.
This
a=read(0,*buffer,100);
passes the first uninitialized pointer to read, so almost certain returns an error (probably EFAULT).
If you were to fix that (remove the * from both lines), it would still return 3 if you enter 30Enter on the keyboard (3 characters entered)
Fixing all that, you end up with something like:
int main() {
int len;
char buffer[BUFSIZE];
write(1,"Please Enter your age: ",23);
len=read(0,buffer,BUFSIZE-1);
if (len <= 0) {
write(1, "invalid input", 13);
} else {
buffer[len] = '\0';
char *end;
int age = strtol(buffer, &end, 0);
if (*end != '\n')
write(1, "input not a (just) a number", 27);
if(age > 21)
write(1,"You are an adult",16);
}
return 0;
}
There's more stuff you can do with error checking (for example, you might want to ignore spaces on the end of the line, or other questionable input), but this shows where to start.
If you consult the documentation for read you will see that the return value is the number of bytes read. You will need to read the characters in buffer and convert them from a string to an int instead of doing what you are doing.
The C standard library provides functions like atoi and scanf that you can use to convert the string into a number, but it's pretty easy to do it yourself and it's a good exercise for a new C programmer.
Try this out, which changes read for more commonly used fscanf:
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a;
write(1,"Please Enter your age: ",23);
fscanf(stdin, "%d",&a);
if(a>21)
write(1,"You are an adult",16);
return 0;
}

Issues with execvp() and incomplete multi-argument commands

I'm using execvp() to run some system calls. Program works great for valid commands, and fails for any command that doesn't exist, which is perfect.
The program is, when I use execvp() on a command that needs extra arguments(like cat) and I don't provide arguments, the program just infinitely reads from input.
I'm not sure how to get around this issue, as I don't know how to 'tell' if a command is incomplete. Any ideas?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char* argv[]) {
char command[1000];
printf("Enter command: ");
scanf("%[^\n]s", command);
char *temp = strtok(command, " ");
char *commandList[100];
int index = 0;
while (temp != NULL) {
commandList[index] = temp;
index++;
temp = strtok(NULL, " ");
}
commandList[index] = NULL;
execvp(commandList[0], commandList);
printf("Failed");
}
The ideal result would be a print of "Command incomplete" and the process ending.
One of the ideas from the comment completely answered my question (To the exact needs I had). Not sure how to give him credit on here, though.
The solution is to simply close stdin right before I use execvp(). If the command is not completed on the first scanf, the program throws an error, which is perfect.
Since I'm running the main program I'm using this on in a loop, I can use dup and dup2 to save and reload stdin later.
The code I used to test if it'll work:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char* argv[]) {
char command[1000];
int stdinput = dup(STDIN_FILENO);
close(STDIN_FILENO);
dup2(stdinput, STDIN_FILENO);
printf("Enter command: ");
scanf("%[^\n]s", command);
printf("%s\n", command);
}

`read` in C hangs the program when string of length more than 16 entered

I made following program that uses read (system call in C) to get a string from user (of length lesser than 100).
#include<stdio.h>
#include <unistd.h>
#include <string.h>
int main() {
char *s;
int a = read(0, s, 100);
s[a-1] = '\0';
printf("\"%s\" \n read returned: %i; NUL at: %u", s, a, strlen(s));
return 0;
}
What I expected here is, it will get characters until user enters a new-line character. It will then replace that '\n' character by '\0', and print it.
The program works well until I enter 15 or less characters in stdin, but stops working when there are more than 16 characters.
My inputs are as follows:
E:\My Files\Codes>a.exe
1234567890123456
"1234567890123456"
returned = 17; length = 16
E:\My Files\Codes>a.exe
12345678901234567
[My program hanged on this input.]
Why does it only hangs on 16? What is special in this 2^2?
Post script: I used the string.h just to get the length of the string. Once my program starts working good, I will remove it.
I have been testing your code. The faults is: You have a pointer which points nowhere. I solve it reserving and allocating memory for your string (char array). I will post the working code:
#include <stdlib.h> // It is needed for malloc, free, etc...
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main() {
char *s = malloc(100*sizeof(char)); // Allocate memory with malloc
int a = read(0, s, 100);
s[a-1] = '\0';
printf("\"%s\" \n read returned: %i; NUL at: %u", s, a, strlen(s));
free(s); // You need liberate memory before exit
return 0;
}
Also, other way to solve this, without dynamic memory is:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main() {
char s[100]; // s is a char array of 100 elements
int a = read(0, s, 100);
s[a-1] = '\0';
printf("\"%s\" \n read returned: %i; NUL at: %u", s, a, strlen(s));
return 0;
}

Setting GNU readline prompt to NULL causes custom prompt to be overwritten

I am writing a custom shell in c, and have encountered a strange little bug, which can be seen in the following testcase:
#include <stdio.h>
#include <stdbool.h>
#include <readline/readline.h>
#include <readline/history.h>
int main(int argc, char **argv, char **env) {
while(true) {
fprintf(stdout, "input: ");
char *line = readline(NULL);
if(line) {
add_history(line);
}
}
return 0;
}
The program spits out the prompt, and if I type something like this:
input: foo bar baz
And then go to erase the line, input: gets erased as well (once I hit the first character I inputted). Is there anyway to fix this? The only thing I could think to do was fflush(stdout) but that didn't work.
Tell readline() about the prompt:
#include <readline/readline.h>
#include <readline/history.h>
int main(void)
{
char *line;
while ((line = readline("input: ")) != 0)
add_history(line);
return 0;
}
When you do the prompting yourself, readline() doesn't know about the presence of the prompt, and therefore mishandles redrawing the line when you erase the last character you entered (moving the cursor back to the beginning of the line). When it knows about the prompt, it doesn't erase it.

C help in using system function with batch

Hello I have a small problem with my C program.
#include<stdio.h>
int main ( int argc, char **argv )
{
char buff[120];
char text;
printf("Enter your name: ");
gets(buff);
text = sprintf(buff, "echo StrText=\"%s\" > spk.vbs");
system(text);
system("echo set ObjVoice=CreateObject(\"SAPI.SpVoice\") >> spk.vbs");
system("echo ObjVoice.Speak StrText >> spk.vbs");
system("start spk.vbs");
return 0;
}
How can I get input from a user and apply it in the system() function?. I am new to C and I am mostly a batch coder, I am trying to port some applications to C so Can anyone tell me to write this application without using the system function?
Thanks in Advance.
Add this to your includes:
#include <string.h>
Change your char text; to char text[120]; - has to be an array, not a single char
Then replace gets with fgets:
fgets(buff, sizeof(buff), stdin); /* for sizeof(buff) to work buff and fgets must be in the same scope */
buff[strlen(buff) - 1] = '\0'; /* this will trim the newline character for you */
Finally you pass text to system after you've formatted it to your purposes (perhaps something like):
sprintf(text, "echo StrText=\"%s\" > spk.vbs", buff);
Is this what you're looking for?
Note: You should also include #include <stdlib.h> for your system call. Always compile with warnings (gcc -Wall -Wextra if you are on Linux), it will be pointed out for you.
Is this what you need?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main ( int argc, char **argv )
{
char buff[120];
char text[120];
printf("Enter your command: ");
fgets(buff, sizeof(buff), stdin);
buff[strlen(buff) - 1] = '\0'; /* get rid of the newline characters */
sprintf(text, "echo StrText=\"%s\" > spk.vbs", buff);
system(text);
return 0;
}
gets is deprecated. Use fgets instead.
#include<stdio.h>
int main ( int argc, char **argv )
{
char inputBuf[120];
char cmdBuf[200];
printf("Enter your name: ");
fgets(inputBuf , sizeof( inputBuf) - 1 , stdin );
sprintf(cmdBuf, "echo StrText=\"%s\" > spk.vbs" , inputBuf );
system(cmdBuf);
return 0;
}

Resources