This is the answer - it can use a timeout on hard mounted nfs mounted directories.
It uses fork(2), pipe(2), child(2) and kill(2) to create a child that attempts to use the mount.
The parent uses select to set a timeout and listen to a pipe for a successful child response.
Remember to use the intr flag when mounting nfs shares!
Code:
#include <sys/stat.h>
#include <signal.h>
#include <stdio.h>
#include <time.h>
void timed_out(){}
int main()
{
int timeout = 5,check_in = 0;
int ch_res;
struct sigaction action;
FILE *temp_file = NULL;
int fd,rc,error;
int fds[2];
fd_set fdset;
struct timeval t;
pid_t child;
char *h = "/var/tmp/nfs/mount/somewhere/";
if(pipe(fds) != 0)
{
return NULL;
}
child = fork();
if(child == -1)
{
printf("Error forking child\n");
exit(1);
}
if( child == 0 )
{
char *buf = "ok";
printf("Child attempting to chdir\n");
chdir(h);
printf("Child writing to pipe\n");
write(fds[1],buf,3);
close(fds[0]);
close(fds[1]);
printf("Child exiting normally\n");
exit(0);
}
else
{
t.tv_sec = timeout;
t.tv_usec = 0;
FD_ZERO(&fdset);
FD_SET(fds[0], &fdset);
rc = select(fds[0] + 1,&fdset,NULL,NULL,&t);
if(rc == -1)
{
printf("Error in select\n");
close(fds[0]);
close(fds[1]);
exit(1);
}
else if(rc == 0)
{
printf("Timeout - possible nfs error\n");
kill(child,SIGINT);
close(fds[0]);
close(fds[1]);
exit(1);
}
else if(FD_ISSET(fds[0],&fdset))
{
printf("Got a response, nfs ok\n");
//close all stuff
close(fds[0]);
close(fds[1]);
}
}
ch_res = chdir(h);
if (ch_res < 0)
{
printf("Creating directory %s\n",h);
if(mkdir(h, 0755))
{
printf("Error making directory %s\n",h);
exit(1);
}
else
{
printf("Made directory %s\n",h);
}
if (chdir(h) < 0)
{
printf("Error changing to directory %s\n",h);
exit(1);
}
}
else
{
printf("Changed directory successfully %d\n",ch_res);
}
exit(0);
}