Help regarding Programming Style

S

Sreekanth

Hi all,

I have implemented a timing out version of fgets function call. I am
pasting the entire code below. I have following doubts:

1. The code which I have written does it follow standard C programming
conventions. ( I am pretty familar with java styles but not with c :-(
).

2. In order to read character by character from stdin , I have made use
of termios.h function calls is it as standard portable way of doing it
or is there any other better way. I have tested it with freebsd 6.0 it
seems to work fine. Btw I got the code to do it from net
(http://www.macdonald.egate.net/CompSci/hkeyinp3.html)

3. Now is my code thread-safe?

Thanks for being so patient and please help me inorder to be a
efficient/better c-programmer.

----

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <setjmp.h>
#include <string.h>
#include <termios.h>


jmp_buf mybuf;


static void
sig_alrm(int signo)
{
longjmp(mybuf, 1);
return;
}

static struct termios stored_settings;

void
set_keypress(void)
{
struct termios new_settings;
tcgetattr(0, &stored_settings);
new_settings = stored_settings;
//setting buffer to 1 byte
new_settings.c_lflag &= (~ICANON);
new_settings.c_cc[VTIME] = 0;
new_settings.c_cc[VMIN] = 1;
tcsetattr(0, TCSANOW, &new_settings);
return;
}

void
reset_keypress(void)
{
tcsetattr(0, TCSANOW, &stored_settings);
return;
}



char *
tgets(char *str, int size, FILE * stream, int nsec)
{
char *mytempchar;
int i = 0;
int ch;

mytempchar = (char *)malloc(sizeof(char) * size);
if (fileno(stream) == fileno(stdin))
set_keypress();

if (setjmp(mybuf) == 1)
goto done;
signal(SIGALRM,sig_alrm);
alarm(nsec);
while (i <= size - 1) {
ch = getc(stream);
if (ch != EOF) {
if (ch != '\n') {
mytempchar = (char)ch;
i = i + 1;
} else
break;
}
}
done:
if (i == 0)
mytempchar = NULL;
else
mytempchar = 0;
//printf("The gotten string is %s\n", mytempchar);
str = mytempchar;
reset_keypress();
return mytempchar;

}

int
main(void)
{
char *mystring;
int maxlen = 256;
FILE *myfile;
myfile = fopen("gen.txt","r");
mystring = (char *)malloc(sizeof(char) * maxlen);
//printf("Enter the Input String :::: ");
//mystring = tgets(mystring,maxlen,stdin,5);
mystring = tgets(mystring, maxlen,myfile , 5);
printf("%s\n", mystring);
return 0;
}
 
J

Jack Klein

Hi all,

I have implemented a timing out version of fgets function call. I am
pasting the entire code below. I have following doubts:

1. The code which I have written does it follow standard C programming
conventions. ( I am pretty familar with java styles but not with c :-(
).

There are no "standard C programming conventions", although this group
has a convention, namely that it discusses the standard C language, as
defined by any version of the ANSI/ISO C language standard, or by the
original de facto standard, the first edition of Kernighan & Richie's
"The C programming Language".
2. In order to read character by character from stdin , I have made use
of termios.h function calls is it as standard portable way of doing it
or is there any other better way. I have tested it with freebsd 6.0 it
seems to work fine. Btw I got the code to do it from net
(http://www.macdonald.egate.net/CompSci/hkeyinp3.html)

"termios" is not part of the standard C language, instead it is a non
standard extension provided by your compiler and operating system
combination, that makes it off-topic here. It needs to be discussed
in a group that supports that combination, in your case I would
suggest
Even though it is off-topic here, you are completely wrong about
termios reading from stdin. It does no such thing. Instead it uses
platform-specific methods to read from a hardware device that need not
have any connection at all to stdin or any other C stream.
3. Now is my code thread-safe?

That's another off-topic question here, because the C language does
not define nor support multiple threads of execution. Even if your
program used absolutely nothing but completely standard C, the
language does not specify whether it is thread safe or not.

Again you need to ask about this in a group like
Thanks for being so patient and please help me inorder to be a
efficient/better c-programmer.

----

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <setjmp.h>
#include <string.h>
#include <termios.h>

The fcntrl.h and termios.h are not part of standard C.
jmp_buf mybuf;


static void
sig_alrm(int signo)
{
longjmp(mybuf, 1);
return;
}

According to the C standard, your program above has undefined
behavior. C does not define the results of calling longjmp(), or
indeed most other library functions, in a signal handler.

Also, your signal handling function is not invoked by a call to
raise() in your program. If you expect some mechanism outside your
program, such as your OS, to invoke the signal handler, that is
something else C does not define.
static struct termios stored_settings;

void
set_keypress(void)
{
struct termios new_settings;
tcgetattr(0, &stored_settings);
new_settings = stored_settings;
//setting buffer to 1 byte
new_settings.c_lflag &= (~ICANON);
new_settings.c_cc[VTIME] = 0;
new_settings.c_cc[VMIN] = 1;
tcsetattr(0, TCSANOW, &new_settings);
return;
}

Every single line of the function above is off-topic here, exec pt for
the final return statement, which is not needed.
void
reset_keypress(void)
{
tcsetattr(0, TCSANOW, &stored_settings);
return;
}



char *
tgets(char *str, int size, FILE * stream, int nsec)
{
char *mytempchar;
int i = 0;
int ch;

mytempchar = (char *)malloc(sizeof(char) * size);

Don't cast the return value of malloc() in C.
if (fileno(stream) == fileno(stdin))
set_keypress();

There is no fileno() function in the standard C library, that is
another one of your platform's non-standard extensions.
if (setjmp(mybuf) == 1)
goto done;
signal(SIGALRM,sig_alrm);
alarm(nsec);
while (i <= size - 1) {
ch = getc(stream);
if (ch != EOF) {
if (ch != '\n') {
mytempchar = (char)ch;
i = i + 1;
} else
break;
}
}
done:
if (i == 0)
mytempchar = NULL;
else
mytempchar = 0;
//printf("The gotten string is %s\n", mytempchar);
str = mytempchar;
reset_keypress();
return mytempchar;

}

int
main(void)
{
char *mystring;
int maxlen = 256;
FILE *myfile;
myfile = fopen("gen.txt","r");
mystring = (char *)malloc(sizeof(char) * maxlen);
//printf("Enter the Input String :::: ");
//mystring = tgets(mystring,maxlen,stdin,5);
mystring = tgets(mystring, maxlen,myfile , 5);
printf("%s\n", mystring);
return 0;
}


You need to take this question to there is
far too much non-standard stuff and undefined behavior for standard C>
 
P

Philip Pemberton

Sreekanth said:
1. The code which I have written does it follow standard C programming
conventions. ( I am pretty familar with java styles but not with c :-(
).

I'd suggest you read the file Documentation/CodingStyle in the Linux kernel
sources, and also take a quick look at
<http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/>.

In all fairness, there is no defined standard style. I use the Linux Kernel
style because it looks sane to me, and I find it easy to read. Everyone has
their own preference. Just be consistent in whatever style you choose to use.

If you use the Linux kernel coding style, there's a script in scripts/Lindent
that calls GNU Indent to automatically indent your source code for you (this
goes back to 'consistency'.
2. In order to read character by character from stdin , I have made use
of termios.h function calls is it as standard portable way of doing it
or is there any other better way. I have tested it with freebsd 6.0 it
seems to work fine. Btw I got the code to do it from net
(http://www.macdonald.egate.net/CompSci/hkeyinp3.html)

I'm not 100% sure about this, but I think termios is POSIX-specific. You can
use 'getc' and 'putc', which are in stdio.h and are defined by the ANSI C
standard (and have been part of C since the pre-ANSI days of K&R standard C).
3. Now is my code thread-safe?

I have absolutely no idea - I've never done multi-threaded development.
 
P

pragma

I'm not 100% sure about this, but I think termios is POSIX-specific. You can
use 'getc' and 'putc', which are in stdio.h and are defined by the ANSI C
standard (and have been part of C since the pre-ANSI days of K&R standard C).

Yes, termios.h is required by 2001 POSIX.1 version, and so it's
portable across POSIX operating systems.
3. Now is my code thread-safe?

Well, at first one should always assume that in general a source is
_not_ thread safe. Thre's a preprocessor directive, namely #define
_REENTRANT that flags the proprocessor to use reentrant versions of
the functions if they are available (a reentrant function, for
instance, may be called multiple times overlaping in time and in an
asynchrounous fashion, like threads do often). Look that this is not a
warranty of reentrance, and so a judicious check of _each_ function
call is needed to place this statement safely.
 
C

Chris Hills

Jack Klein said:
There are no "standard C programming conventions",

Yes there are...... dozens of them. Virtually every company has a C
coding standard to a style guide or a mixture of the two.

Interestingly the MISRA C++ team grabbed every C++ guide it could find
for a quick comparison and found that the virtually all of them had a
large part that was common.

I expect the same is true of C coding standards.

However as Les Hatton pointed out recently there is a lot of received
wisdom in these things with no empirical evidence to support them.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top