int main(void) {
int status = EXIT_SUCCESS;
FILE *in;
struct sigrecord {
int signum;
char signame[10];
char sigdesc[100];
} sigrec;
if ((in = fopen("signals.txt", "r")) == NULL) {
fputs("Cannot open signals.txt file\n", stderr);
return EXIT_FAILURE;
}
do {
int n = fscanf(in, "%d%9s%*[ \t]%99[^\n]", &sigrec.signum,
sigrec.signame, sigrec.sigdesc);
if (n == 3) {
printf("Signal\n number = %d\n name = %s\n description = %s\n\n",
sigrec.signum, sigrec.signame, sigrec.sigdesc);
} else if (n != EOF) {
fputs("Failed to match signum, signame or sigdesc\n", stderr);
status = EXIT_FAILURE;
break;
}
} while (1);
if (fclose(in) == EOF) {
fputs("Failed to close file\n", stderr);
status = EXIT_FAILURE;
}
return status;
}
Output is fine, but while(1) loop does not end do{} loop and my program gets stuck after doing its purpose, printing output perfectly. Thanks for any help.
You need to break if scanf was not successful despite the reason.
}
else {
if (n != EOF) {
fputs("Failed to match signum, signame or sigdesc\n", stderr);
status = EXIT_FAILURE;
}
break;
}
Related
This certain getopt case is supposed to be used as an ls (the unix/linux command) alternative that returns the active files but once compiled and ran nothing is returned in the terminal.
Here is the full code:
#include <errno.h>
#include <getopt.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#define DATA_SIZE 1000
void print_help(void)
{
printf("Help\n");
printf("> cast -d (deletes file)\n");
printf("> cast -r (renames file)\n");
printf("> cast -c (create new file)\n");
printf("> cast -s (searches contents of file)\n");
printf("________________________________________\n");
printf("Find an error or a bug? please submit it in the issues section on github\n");
}
case 's': {
int main(void)
{
DIR *directory;
struct dirent *entry;
directory = opendir(".");
if (directory == NULL)
{
printf("Error reading directory\n");
return 1;
}
while ((entry = readdir(directory)) != NULL)
if (entry->d_type == DT_REG)
{
printf("file: %s\n", entry->d_name);
}
}
if (closedir(directory) == -1)
{
printf("Error closing directory\n");
return 1;
}
return 0;
}
}
int main(int argc, char **argv)
{
int option_val = 0;
int opt_delete = 0;
int opt_help = 0;
int opt_rename = 0;
int opt_create = 0;
int opt_search = 0;
while ((option_val = getopt(argc, argv, "dhrcs")) != -1) {
switch (option_val) {
case 'd': {
char filename[65]; //Hope your filename isnt bigger than this
printf("Filename or path to file: ");
scanf("%s", filename); // checks to see if your filename isnt bigger than specified
if (remove(filename) != 0)
{
fprintf(stderr, "Errno: %d\n", errno);
perror("Error msg");
} else printf("%s, deleted.\n", filename);
opt_delete = 1;
break;
case 'r': {
char file[65], new[65];
printf("File: ");
scanf("%s", file);
printf("New name: ");
scanf("%s", new);
if (rename(file, new) != 0)
{
fprintf(stderr, "Errno: %d\n", errno);
perror("Error msg");
} else printf("%s --> %s", file, new);
opt_rename = 1;
break;
case 'c': {
FILE *f = fopen("Castdocument.txt", "w+");
fprintf(f, "Finished with maybe no errors? Rename this file to whatever you would like and change the filename extension with ""cast -r""");
printf("File created! (Check your home directory for ""Castdocument.txt"" file and modify that to fit your needs)");
fclose(f);
opt_create = 1;
case 'h': {
print_help();
opt_help = 1;
break;
default:; /* '?' */
//print_help();
}
if (opt_delete) {
printf("\n");
} if (opt_rename) {
printf("\n");
} if (opt_help) {
print_help();
} if (opt_search) {
printf("\n");
} if (opt_create) {
printf("\n");
}
}
}
}
}
}
}
and here is the 's' case:
case 's': {
int main(void)
{
DIR *directory;
struct dirent *entry;
directory = opendir(".");
if (directory == NULL)
{
printf("Error reading directory\n");
return 1;
}
while ((entry = readdir(directory)) != NULL)
if (entry->d_type == DT_REG)
{
printf("file: %s\n", entry->d_name);
}
}
if (closedir(directory) == -1)
{
printf("Error closing directory\n");
return 1;
}
return 0;
}
}
I attempted to move the case out of the switch statement but to no avail.
I have command tee in C, and I should add option -a which :supports the -a option file, which results in adding the data being read to the end of the file, if available. Anyone could help?
I try put inside :
if ( (option = getopt(argc,argv,"a")) != -1 ){
switch (option){
case 'a':
But I don't know what next.
main(int argc, char *argv[]){
FILE *fp, *fp1;
char buffer;
if(argc != 4){
printf("\nError");
printf("\nSintaxis: tee [archivo1] [archivo2]\n");
exit(0);
}
if(strcmp(argv[1], "tee") == 0){
fp = fopen(argv[2], "r");
fp1 = fopen(argv[3], "w");
printf("\Content in %s:\n", argv[2]);
while(!feof(fp)){
buffer = fgetc(fp);
fputc(buffer, fp1);
printf("%c", buffer);
}
printf("\n\n%s received %s\n", argv[3], argv[2]);
fclose(fp);
fclose(fp1);
}
else
printf("\nThe first argument have to be tee\n");
}
Second version , I think better.
But if I run program without option -a else if (argc == 2) {
printf("Write to file: %s\n", argv[1]);
process_save_reading(argv[1],"w+") write some text in file argv[1] -file is empty
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void usage() {
fprintf(stderr, "Usage: [-a program]");
exit(1);
}
void err(char * s1, char * s2) {
fprintf(stderr, "Error: %s ", s1);
perror(s2);
exit(1);
}
void process_reading() {
int c = fgetc(stdin);
while (c != EOF) {
putchar(c);
c = getchar();
}
}
void write_file_content(char * filename, int cnt, const char* mode) {
FILE *fp;
if ((fp = fopen(filename, mode)) == NULL) {
fprintf(stderr, "Can not open file: %s\n", filename);
exit(1);
}
fputc(cnt, fp);
fclose (fp);
}
void process_save_reading(char * filename, const char* mode) {
int c = fgetc(stdin);
while (c != EOF) {
putchar(c);
write_file_content(filename, c, mode);
c = getchar();
}
}
int file_exists(char * filename) {
return access(filename, F_OK) != -1;
}
int main(int argc, char * argv[]) {
char * opts = "a:";
int c;
if (argc == 1) {
process_reading();
}
else if (argc == 2) {
printf("Write to file: %s\n", argv[1]);
process_save_reading(argv[1],"w+");
}
else {
while ((c = getopt(argc, argv, opts)) != -1) {
switch (c) {
case 'a':
if (!file_exists(optarg)) {
fprintf(stderr, "File: '%s' doesn't exists\n", optarg);
exit(1);
}
printf("Save to file: %s\n", optarg);
process_save_reading(optarg,"a+");
I have a problem with my program to get it run correctly.
here is the code:
#include <stdio.h>
#include <stdlib.h> // for EXIT_SUCCESS and EXIT_FAILURE
#include <ctype.h>
#include <string.h>
void ReadFile(FILE* file) {
unsigned lines = 0;
int braces = 0;
int curlyBraces = 0;
int comments = 0;
int c;
char* line = 0;
unsigned col = 0;
while ((c = fgetc(file)) != EOF) {
if(c == '\n') { // new line
lines++;
printf("%4d: {%d} (%d) /*%d*/ |%s\n", lines, curlyBraces, braces, comments, line);
free(line); line = 0;
col = 0;
} else {
// add character to line
line = (char*)realloc(line, (col+1)*sizeof(char));
if (line == 0) {
fprintf(stderr, "error reallocating memory");
return;
}
line[col] = c;
col++;
if (c == '(') {
braces++;
} else if (c == ')') {
braces--;
} else if (c == '{') {
curlyBraces++;
} else if (c == '}') {
curlyBraces--;
} else if (c == '/') {
if (fgetc(file) == '*') {
comments++;
} else {
fseek(file, -1, SEEK_CUR);
}
} else if (c == '*') {
if (fgetc(file) == '/') {
comments--;
} else {
fseek(file, -1, SEEK_CUR);
}
}
}
}
}
int main(int argc, char** argv) {
short lines = 0, words = 0, chars = 0;
/* check for arguments */
if (argc == 1) {
fprintf(stderr, "usage: %s filename\n", argv[0]);
return EXIT_FAILURE;
}
/* open file */
FILE* file = fopen(argv[1], "r");
if(file == 0) {
fprintf(stderr, "error open file '%s'\n", argv[1]);
return EXIT_FAILURE;
}
ReadFile(file);
if (fclose(file) == EOF) {
fprintf(stderr, "error in fclose()\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
on the output i get some weird output, like realloc overwrites some data...
i already tried strcat, but i can't use constant chars. so i have to use realloc.
here is a short excerpt of the output
P 68: {1} (0) /*0*/ | / open file *
69: {1} (0) /*0*/ | FILE* file = fopen(argv[1], "r");
70: {2} (0) /*0*/ | if(file == 0) {
rn EXIT_FA(0) /*0*/ | fprintf(stderr, "error open file '%s'\n", argv[1]);
r open fi (0) /*0*/ | return EXIT_FAILURE;
73: {1} (0) /*0*/ | }
} 74: {1} (0) /*0*/ |
maybe there is another way to reaize this? with fgets() i could get the whole line, but increments the pointer in the file and i have to give fgets() a count of chars. so that wouldn't be the perfect solution.
You need to terminate your string before you print it out:
lines++;
line[col] = 0; // new
printf("%4d: {%d} (%d) /*%d*/ |%s\n", lines, curlyBraces, braces, comments, line);
Unfortunately line[col] is out of bounds here. So you need realloc line before adding the terminator like this:
lines++;
line = (char*)realloc(line, (col+1)*sizeof(char));
if (line == 0) {
fprintf(stderr, "error reallocating memory");
return;
}
line[col] = 0; // new
printf("%4d: {%d} (%d) /*%d*/ |%s\n", lines, curlyBraces, braces, comments, line);
Also, do you know about ungetc? You can replace those fseek(-1) with ungetc.
I'm trying to get 2 way communication between a main file and a helper file.
The main file forks, and the child does some pipe work and then runs an exec.
My problem is that I can send information from the child exec to the parent exec, but not the other way around.
Below Is my entire code from the two files, so you should be able to run it.
Any help in getting the 2 way communication working will be extremely helpful. i'm been at this for almost 8 hours straight now.
When you run it, you'll see it print out "yo 0". This was me testing that it takes an integer from the main file, sends it to the helper, adds yo in front of it and sends it back. The first slab of code is the main file, second is the helper, third is the map file needed to run it. make sure there isn't a blank line underneath the last line, and the fourth is the agent file needed to run it.
the running is [./handler mapfile 20 agentfile.]
the int 20 doesn't do anything yet, but you need it in there to run the file.
If anyone actually goes to the effort to do all this and help me, i am eternally grateful
main file (handler.c)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/wait.h>
enum ErrorCode {
SHOW_USAGE = 1, BAD_STEPS, OPEN_MAP_ERROR, CORRUPT_MAP,
OPEN_AGENT_ERROR, CORRUPT_AGENTS, AGENT_ERROR,
AGENT_WALLED, AGENT_COLLIDED, TOO_MANY_STEPS, INVALID_AGENT_RESPONSE,
AGENT_CLOSED, AGENT_DIED, SIGINT_REC
};
typedef struct {
int valid;
int row, col;
} Point;
typedef struct {
Point point;
int number;
char name;
char param[20];
char type[20];
} Agent;
typedef struct {
int rows, cols;
char **grid;
} Map;
Map map;
Map agentMap;
int listSize = 0;
void error(enum ErrorCode e) {
switch(e) {
case SHOW_USAGE:
fprintf(stderr, "Usage: handler mapfile maxsteps agentfile\n");
break;
case BAD_STEPS:
fprintf(stderr, "Invalid maxsteps.\n");
break;
case OPEN_MAP_ERROR:
fprintf(stderr, "Unable to open map file.\n");
break;
case CORRUPT_MAP:
fprintf(stderr, "Corrupt map.\n");
break;
case OPEN_AGENT_ERROR:
fprintf(stderr, "Unable to open agent file.\n");
break;
case CORRUPT_AGENTS:
fprintf(stderr, "Corrupt agents.\n");
break;
case AGENT_ERROR:
fprintf(stderr, "Error running agent.\n");
break;
case AGENT_WALLED:
fprintf(stderr, "Agent walled.\n"); // needs fixing, check spec sheet
break;
case AGENT_COLLIDED:
fprintf(stderr, "Agent collided.\n"); // same as AGENT_WALLED
break;
case TOO_MANY_STEPS:
fprintf(stderr, "Too many steps.\n");
break;
case INVALID_AGENT_RESPONSE:
fprintf(stderr, "Agent sent invalid response.\n"); // fixiing
break;
case AGENT_CLOSED:
fprintf(stderr, "Agent exited with status.\n"); // fixiing
break;
case AGENT_DIED:
fprintf(stderr, "Agent exited due to signal.\n"); // fixing
break;
case SIGINT_REC:
fprintf(stderr, "Exiting due to INT signal.\n");
break;
}
exit(e);
}
void print_map(Map map)
{
int r;
for (r = 0; r < map.rows; ++r) {
printf("%s", map.grid[r]);
}
puts("");
}
void print_agents(Agent *agents, int size)
{
int i;
for (i = 0; i < size; i++) {
Agent temp = agents[i];
printf("%d %d %c %d %s %s %i\n", temp.point.row, temp.point.col, temp.name, temp.number, temp.type, temp.param, i);
}
puts("");
}
void readMap(char *file)
{
int r;
FILE *fd = fopen(file, "r");
char buffer[20];
char d;
if (!fd) {
error(OPEN_MAP_ERROR);
}
if (fgets(buffer, 20, fd) == NULL) {
error(CORRUPT_MAP);
}
if (sscanf(buffer, "%d %d%1[^\n]\n", &map.rows, &map.cols, &d) != 2 ||
map.rows < 1 || map.rows > 999 || map.cols < 1 || map.cols > 999) {
error(CORRUPT_MAP);
}
map.grid = malloc(map.rows * sizeof(char *));
for (r = 0; r < map.rows; ++r) {
map.grid[r] = calloc(map.cols + 2, sizeof(char));
if (fgets(map.grid[r], map.cols + 2, fd) == NULL ||
map.grid[r][map.cols] != '\n') {
error(CORRUPT_MAP);
}
}
fclose(fd);
}
void checkAgent(char *file)
{
FILE *fd = fopen(file, "r");
if (!fd) {
error(AGENT_ERROR);
}
fclose(fd);
}
int growList (Agent **agentList, int curSize, int increaseNum)
{
const int newSize = curSize + increaseNum;
Agent *temp = (Agent*) realloc(*agentList, (newSize * sizeof(Agent)));
if (temp == NULL) {
exit(20);
}
else {
*agentList = temp;
return newSize;
}
}
Agent* readAgentFile(char *file, Agent *agentList)
{
int readCount = 0;
FILE *fp = fopen(file, "r");
char buffer[80];
listSize = 0;
if (!fp) {
error(OPEN_AGENT_ERROR);
}
if (fgets(buffer, 80, fp) == NULL) {
error(CORRUPT_AGENTS);
}
rewind(fp);
while (fgets(buffer, 80, fp) != NULL) {
if (buffer[0] != '#') {
Agent agent;
sscanf( buffer, "%d %d %c %s %s" ,&agent.point.row, &agent.point.col, &agent.name, agent.type, agent.param);
checkAgent(agent.type);
agent.number = readCount+1;
listSize = growList(&agentList, listSize, 1);
agentList[readCount] = agent;
readCount++;
}
}
if (readCount == 0) {
error(CORRUPT_AGENTS);
}
fclose(fp);
return agentList;
}
void createAgentMap()
{
int i,j;
agentMap = map;
for (i=0; i < map.rows; i++) {
for (j=0; j < map.cols; j++) {
char c = map.grid[i][j];
if (c == '.') {
agentMap.grid[i][j] = ' ';
}
}
}
}
int main(int argc, char **argv)
{
int steps;
int pid;
int returnStatus;
int i;
int out_pipe[2];
int in_pipe[2];
char ch[20];
Agent firstAgent;
Agent *agentList =(Agent *) calloc(1, sizeof(Agent));
if (argc != 4) {
error(SHOW_USAGE);
}
sscanf(argv[2], "%d", &steps);
if ((steps < 1)) {
error(BAD_STEPS);
}
readMap(argv[1]);
agentList = readAgentFile(argv[3], agentList);
firstAgent = agentList[0];
createAgentMap();
for (i=0; i < listSize; i++) {
if (pipe(out_pipe) < 0) {
perror("Pipe Error");
}
if (pipe(in_pipe) < 0) {
perror("Child pipe error");
}
Agent temp;
temp = agentList[i];
switch ( pid = fork() )
{
case -1:
perror("Can't fork.\n");
exit(20);
case 0:
/* Child */
/*close(1);
dup(in_pipe[1]);
close(0);
dup(out_pipe[0]);
close(in_pipe[0]);
close(out_pipe[1]);*/
dup2(out_pipe[0], 0);
dup2(in_pipe[1], 1);
execlp(temp.type, temp.type, temp.param, (char *)0);
perror("No exec");
default:
//close(1);
//dup(handlerChild[1]);
//fprintf(stdout, "%d", listSize);
write(out_pipe[1], "%d", listSize);
close(in_pipe[1]);
close(0);
dup(in_pipe[0]);
if (fgets(ch, 20, stdin) == NULL) {
break;
}
printf("%s\n", ch);
}
}
while (steps > 0) {
steps -= 1;
}
return 0;
}
helper file (simple.c)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
typedef struct {
int valid;
int row, col;
} Point;
typedef struct {
int numAgents;
char agentNames[80];
int agentNumber;
} Info;
typedef struct {
int rows, cols;
char **grid;
} Map;
Map agent_map;
int main(int argc, char **argv)
{
int steps = 10;
int simple_pipe[2];
int dir;
char inputDir;
char input_stream[20];
int in = dup(0);
Info info;
if (argc == 2) {
sscanf(argv[1], "%c1", &inputDir);
switch (inputDir) {
case 'N': dir = 0; break;
case 'E': dir = 1; break;
case 'S': dir = 2; break;
case 'W': dir = 3; break;
default : fprintf(stdout, "Invalid params.\n"); exit(2);
}
}
else {
fprintf(stdout, "Incorrect number of params.\n");
exit(1);
}
close(0);
dup(simple_pipe[0]);
fgets(input_stream, 20, stdin);
sscanf(input_stream, "%d", &info.numAgents);
//printf("%d", info.numAgents);
//printf("this is the input: %s\n", input_stream); // This is successfully printing to stdout in the pipe
fprintf(stderr, "yo %d \n", info.numAgents);
while (steps > 0) {
steps -= 1;
}
exit(0);
}
map file
6 6
##..##
#....#
#.##.#
#....#
##....
######
agent file
1 1 A ./simple E
2 2 B ./simple N
5 2 C ./simple S
A pipe is a unidrectional connection across processes. Before you fork, you open the pipe and it will reserve two file descriptors, where fd[0] can be read from and fd[1] can be written to.
So when you want to have a two way commumincation you need to create two pipes, and then use one for reading in the parent writing in the child and the second pipe the other way around.
A more detailed explanation along with some sample code can be foun dhere: http://linux.die.net/man/2/pipe
I want to run shell command in C program and get stdout output.
I did it in this function:
int run_shell_cmd_nout(const char* cmd)
{
FILE *fp;
char out[4096] = {0};
char str[256] = {0};
char full_cmd[1024] = {0};
int result = 0;
// Compose full shell command
if (!sprintf(full_cmd, "/system/bin/%s", cmd))
{
printf("Failed to compose full shell command\n");
return -1;
}
// Open the command for reading.
fp = popen(full_cmd, "r");
if (fp == NULL)
{
printf("Failed to run command\n");
return -1;
}
// Read the output a line at a time - output it.
while(!feof(fp))
{
if(fgets(str, 256, fp) != NULL)
{
result = -1;
strcat(out, str);
}
}
pclose(fp);
if (result != 0)
{
printf("%s\n", out);
return -1;
}
return 0;
}
But it doesn't work with insmod.
Is there any way to intercept all outputs when invoke insmod?