2014-11-05 12:41:07 +01:00

185 lines
4.7 KiB
Plaintext

$NetBSD: patch-ab,v 1.3 2014/03/06 15:44:21 joerg Exp $
--- tty.c.orig 1995-06-30 23:41:05.000000000 +0000
+++ tty.c
@@ -140,9 +140,10 @@ int tty_nomesg ( void )
int tty_lock ( char *path, int mode )
{
+#define MAX_LOCK_ATTEMPTS 3
struct passwd *pw;
-
- int fd;
+ char number[12], *temp_path;
+ int fd, i, saved_errno;
if ( mode ) /* locking on ? */
@@ -152,32 +153,71 @@ int tty_lock ( char *path, int mode )
return 0; /* standard input */
}
- if ( saved_path != NULL )
+ temp_path = (char*) malloc ( sizeof ( PATH_LOCKD ) +
+ strlen("TMP..") + 10); /* max PID */
+
+ (void) sprintf ( number, "%u", (unsigned)getpid() );
+ (void) strcpy ( temp_path, PATH_LOCKD );
+ (void) strcat ( temp_path, "TMP.." );
+ (void) strcat ( temp_path, number );
+
+ if ( opt_debg )
+ printf ( "DIP: tty: trying to create lock temp file %s\n", temp_path );
+ if ( ( fd = open ( temp_path, O_CREAT|O_TRUNC|O_WRONLY, 0644 ) ) < 0)
{
- free ( saved_path );
- saved_path = NULL;
+ (void) fprintf ( stderr, "DIP: tty: lock: (%s): %s\n",
+ temp_path, strerror ( errno ) );
+ free(temp_path);
+ return -1;
}
+ /*
+ * now enter our PID;
+ * Note: the 10 digits + newline are convention and cannot be changed
+ */
+ (void) sprintf ( number, "%10u\n", getpid() );
+ if ( opt_debg )
+ printf ( "DIP: tty: writing \"%10u\" into lock temp file\n", getpid() );
+ if ( write (fd, number, 11) != 11 )
+ {
+ (void) fprintf ( stderr, "DIP: tty: lock write error: %s\n",
+ strerror ( errno ) );
+ free(temp_path);
+ return -1;
+ }
+ (void) close ( fd );
+
+ free ( saved_path ); /* just in case [NB: free(NULL) is legal] */
saved_path = (char*) malloc ( sizeof ( PATH_LOCKD ) +
- strlen ( path ) + 1 );
+ strlen ( path ) + 3 );
(void) strcpy ( saved_path, PATH_LOCKD );
+ (void) strcat ( saved_path, ".." );
(void) strcat ( saved_path, path );
-
- if ( ( fd = creat ( saved_path, 0644 ) ) < 0)
- {
- if ( errno != EEXIST )
+ if ( opt_debg )
+ printf ( "DIP: tty: linking %s to %s\n", temp_path, saved_path );
+ for ( i = 0; i < MAX_LOCK_ATTEMPTS; i++ )
{
- (void) fprintf ( stderr, "DIP: tty: lock: (%s): %s\n",
- saved_path, strerror ( errno ) );
+ /* now attempt to actually get the lock */
+ if ( link ( temp_path, saved_path ) == 0 )
+ break;
+ sleep(2 * (i + 1));
+ }
+ saved_errno = errno;
+ (void) unlink ( temp_path );
+ free(temp_path);
+
+ if ( i >= MAX_LOCK_ATTEMPTS )
+ {
+ /* did not get it */
+ if ( saved_errno != EEXIST )
+ (void) fprintf ( stderr, "DIP: tty: lock: (%s): %s\n",
+ saved_path, strerror ( saved_errno ) );
+ else if ( opt_debg )
+ printf ( "DIP: tty: lock attempt failed, EEXIST\n" );
+ return -1;
}
-
- return -1;
- }
-
- (void) close ( fd );
-
/*
* Make sure UUCP owns the lockfile. Required by some packages.
@@ -215,7 +255,26 @@ int tty_lock ( char *path, int mode )
return 0;
}
+/*
+ * Enter daemon's PID into the lock file;
+ * This is icky.
+ */
+void tty_relock ( void )
+{
+ int fd;
+ char number[12];
+ if ( saved_path == NULL )
+ return;
+
+ (void) sprintf ( number, "%10u\n", (unsigned)getpid() );
+ if ( opt_debg )
+ printf ( "DIP: tty: rewriting lock file (PID = %u)\n", getpid() );
+ if ( (fd = open ( saved_path, O_WRONLY, 0 )) == -1 )
+ return;
+ (void) write ( fd, number, 11);
+ (void) close ( fd );
+}
/*
* Find a serial speed code in the table.
@@ -482,7 +541,7 @@ int tty_set_disc ( int disc )
}
- if ( ( disc == SLIPDISC ) )
+ if ( disc == SLIPDISC )
{
int tmp_unit = -1;
@@ -965,7 +1024,6 @@ int tty_open ( char *name )
char *sp;
char path [ MAXPATHLEN ];
-
/*
* Try opening the TTY device.
*/
@@ -985,8 +1043,10 @@ int tty_open ( char *name )
else
sp = name;
-
- if ( ( fd = open ( path, O_RDWR | O_NONBLOCK ) ) < 0 )
+ if ( tty_lock ( sp, 1 ) == -1 )
+ return -1;
+
+ if ( ( fd = open ( path, O_RDWR | O_NONBLOCK | O_EXCL ) ) < 0 )
{
(void) fprintf ( stderr, "DIP: tty: open(%s, RW): %s\n",
path, strerror ( errno ) );
@@ -1080,8 +1140,7 @@ int tty_open ( char *name )
/*
* If we are running in MASTER mode, set the default speed.
*/
- if ( ( path != NULL )
- && ( tty_set_speed ( &tty_current, "9600" ) != 0 ) )
+ if ( ( tty_set_speed ( &tty_current, "9600" ) != 0 ) )
{
(void) fprintf ( stderr, "DIP: tty: open: cannot set 9600 bps!\n" );
@@ -1118,10 +1177,5 @@ int tty_open ( char *name )
{
return 0 ;
}
-
-
- /*
- * OK, all done. Lock this terminal line.
- */
- return tty_lock ( sp, 1 );
+ return 0;
}