• C

C Programming: Terminate execution when user input is ^d

The boolean check "!feof(stdin)" inside the while loop on line 28 was working fine when I was using buffered IO. But when I switched to using raw IO it stopped working. The project requires the use of read(2), write(2), open(2), etc.

This started happening when I switched from fgets() to read() on line 73.

My goal is to end the program when the user input is ^d (ctrl + d).

#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <pwd.h>

static int writeLine(const char *b, const char *u, int filedes);
static char* readInput(const char *u, char buffer[]);
static char* getUser();

int main( int argc, char *argv[] ) {

   int fd;
   int max_input = 200;
   char buffer[max_input];
   //char *buf = malloc(sizeof(char) * 1024);

   // get username
   char *myUser = getUser();

   //open file
   fd = open(argv[1], O_RDWR);

   while(!feof(stdin)) {
     char *buf = readInput(myUser, buffer);
     if(writeLine(buf, myUser, fd) < 0)

static char* getUser() {
   struct passwd *mypasswd;
   char *mytty;

   if( (mypasswd = getpwuid(geteuid())) != NULL ) {
      char *user = mypasswd->pw_name;

      if(( mytty = ttyname(STDIN_FILENO)) == NULL)
         perror("ttyname() error");

      int userLen = strlen(user);
      int ttyLen = strlen(mytty);
      char *usr = malloc(sizeof(char) * (userLen + ttyLen + 5));

      strcpy(usr, user);
      strcat(usr, "@");
      strcat(usr, mytty);
      strcat(usr, ": ");

      return usr;

static char* readInput(const char *u, char buffer[]) {

   ssize_t bytes_read;
   size_t count = 200;

   //buffer[0] = '\0';
   //strcpy(b, "");
   //printf("%s", u);

   // display UserName
   if(write(STDOUT_FILENO, u, strlen(u)) < 0)
      perror("write() error");

   // read
   if(( bytes_read = read(STDIN_FILENO, buffer, count)) == -1) {
        perror("read() error");
   else {

   //fgets(buffer, count, stdin);
   // append user input to *b string
   //strcat(b, u);
   //strcat(b, buffer);

   return buffer;

static int writeLine(const char *b, const char *u, int filedes) {
   size_t ulen, blen;

   blen = strlen(b);
   ulen = strlen(u);

   if(write(filedes, u, ulen) < 0 || write(filedes, b, blen) < 0 ) {
        perror("write() error");
        return -1;
   return 0;

Open in new window

Who is Participating?
ozoConnect With a Mentor Commented:
if( (bytes_read = read(STDIN_FILENO, buffer, count)) == -1 ){
        perror("read() error");
   }else if(  bytes_read == 0 ){
Murugesan NagarajanSubject-matter expert at C++ C delivery, implementation, and automation at UNIX oriented operating systems (Windows: CYGWIN_NT MINGW32_NT MINGW64_NT)Commented:
The following change is required for maintaining the source code.
As per the work I used to do in C/C++, I (and all programmers) used to prefer
(  0 == bytes_read )

Open in new window

instead of
(  bytes_read == 0 )

Open in new window

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.