[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdebase/workspace/kdm
From:       Oswald Buddenhagen <ossi () kde ! org>
Date:       2009-10-25 10:28:02
Message-ID: 1256466482.871878.8730.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 1040005 by ossi:

add some more file write error checking

 M  +14 -11    backend/auth.c  
 M  +2 -1      backend/dm.c  
 M  +9 -7      backend/inifile.c  
 M  +3 -1      backend/printf.c  
 M  +27 -13    backend/sessreg.c  
 M  +92 -46    kfrontend/genkdmconf.c  


--- trunk/KDE/kdebase/workspace/kdm/backend/auth.c #1040004:1040005
@@ -316,18 +316,20 @@
 		 * to the auth file so xrdb and setup programs don't fail.
 		 */
 		if (auths[i]->data_length > 0)
-			if (!XauWriteAuth( auth_file, auths[i] ) ||
-			    fflush( auth_file ) == EOF)
-			{
+			if (!XauWriteAuth( auth_file, auths[i] )) {
 				fclose( auth_file );
-				logError( "Cannot write X server authorization file %s\n",
-				          d->authFile );
-				free( d->authFile );
-				d->authFile = NULL;
-				return False;
+				goto whoops;
 			}
 	}
-	fclose( auth_file );
+	if (fclose( auth_file ) == EOF) {
+	  whoops:
+		logError( "Cannot write X server authorization file %s: %m\n",
+		          d->authFile );
+		unlink( d->authFile );
+		free( d->authFile );
+		d->authFile = NULL;
+		return False;
+	}
 	return True;
 }
 
@@ -1128,7 +1130,7 @@
 				return;
 			/*
 			 * Note, that we don't lock the auth file here, as it's
-			 * temporary - we can assume, that we are the only ones
+			 * temporary - we can assume that we are the only ones
 			 * knowing about this file anyway.
 			 */
 #ifdef HAVE_MKSTEMP
@@ -1198,7 +1200,8 @@
 		}
 		if (!endUserAuth( old, new, new_name, ok )) {
 			if (!name) {
-				logError( "Cannot save user authorization\n" );
+				/* XXX this should be user-visible */
+				logError( "Cannot save user authorization: %m\n" );
 				return;
 			}
 			undoUserAuth( name, new_name );
--- trunk/KDE/kdebase/workspace/kdm/backend/dm.c #1040004:1040005
@@ -1641,7 +1641,8 @@
 #endif
 		}
 		fprintf( pidFilePtr, "%ld\n", (long)getpid() );
-		(void)fflush( pidFilePtr );
+		if (fflush( pidFilePtr ) == EOF)
+			logError( "Cannot write PID file %s: %m", pidFile );
 		registerCloseOnFork( pidFd );
 	}
 	return 0;
--- trunk/KDE/kdebase/workspace/kdm/backend/inifile.c #1040004:1040005
@@ -92,16 +92,18 @@
 		return False;
 	}
 	len = strlen( data );
-	if ((cnt = write( fd, data, len )) == len) {
+	if ((cnt = write( fd, data, len )) != len) {
+		if (cnt != -1)
+			errno = -ENOSPC;
+		debug( "cannot write ini-file %\"s: %m", fname );
 		close( fd );
-		return True;
+		return False;
 	}
-	if (cnt == -1)
+	if (close( fd ) < 0) {
 		debug( "cannot write ini-file %\"s: %m", fname );
-	else
-		debug( "cannot write ini-file %\"s: partial write", fname );
-	close( fd );
-	return False;
+		return False;
+	}
+	return True;
 }
 
 #define apparr(d,s,n) do { memcpy (d, s, n); d += n; } while(0)
--- trunk/KDE/kdebase/workspace/kdm/backend/printf.c #1040004:1040005
@@ -61,6 +61,7 @@
  *     - { -> short for ('{')' }'<' '|''
  *   - the pointer to the array is the last argument to the format
  * - the %m conversion from syslog() is supported
+ *   (extended by -ENOSPC meaning "partial write")
  */
 
 /**************************************************************
@@ -426,7 +427,8 @@
 			dopr_outch( bp, ch );
 			break;
 		case 'm':
-			fmtstr( dopr_outch, bp, strerror( errn ), flags, min, max );
+			strvalue = (errn == -ENOSPC) ? "partial write" : strerror( errn );
+			fmtstr( dopr_outch, bp, strvalue, flags, min, max );
 			break;
 		case 'c':
 			dopr_outch( bp, va_arg( args, int ) );
--- trunk/KDE/kdebase/workspace/kdm/backend/sessreg.c #1040004:1040005
@@ -95,6 +95,23 @@
 }
 #endif
 
+#if (!defined(NO_UTMP) && defined(BSD_UTMP)) || \
+    !defined(HAVE_UPDWTMP) || \
+    (!defined(NO_LASTLOG) && !defined(HAVE_LASTLOGX))
+static void
+writeOut( int fd, const void *buf, size_t len, const char *msg )
+{
+	ssize_t ret;
+	if ((ret = write( fd, buf, len )) != (ssize_t)len) {
+		if (ret >= 0)
+			errno = -ENOSPC;
+		logError( msg );
+	}
+	if (close( fd ) < 0)
+		logError( msg );
+}
+#endif
+
 void
 sessreg( struct display *d, int pid, const char *user, int uid )
 {
@@ -240,6 +257,7 @@
 		}
 		if (!pid) {
 			debug( "utmp entry for display %s vanished\n", d->name );
+			close( utmp );
 			goto skip;
 		}
 		if (freeslot >= 0)
@@ -251,15 +269,14 @@
 			bzero( ut_ent.ut_host, sizeof(ut_ent.ut_host) );
 #  endif
 		lseek( utmp, slot * sizeof(ut_ent), SEEK_SET );
-		if (write( utmp, (char *)&ut_ent, sizeof(ut_ent) ) != sizeof(ut_ent))
-			logError( "Cannot write utmp file " UTMP_FILE ": %m\n" );
-	  skip:
-		close( utmp );
+		writeOut( utmp, &ut_ent, sizeof(ut_ent),
+		          "Cannot write utmp file " UTMP_FILE ": %m\n" );
 	}
+  skip:
 # else
 	UTMPNAME( UTMP_FILE );
 	SETUTENT();
-	PUTUTLINE( &ut_ent );
+	PUTUTLINE( &ut_ent ); /* Returns void on some systems => no error check. */
 	ENDUTENT();
 # endif
 #endif
@@ -273,11 +290,9 @@
 #else
 	if ((wtmp = open( WTMP_FILE, O_WRONLY|O_APPEND )) < 0)
 		debug( "cannot open wtmp file " WTMP_FILE ": %m\n" );
-	else {
-		if (write( wtmp, (char *)&ut_ent, sizeof(ut_ent) ) != sizeof(ut_ent))
-			logError( "Cannot write wtmp file " WTMP_FILE ": %m\n" );
-		close( wtmp );
-	}
+	else
+		writeOut( wtmp, &ut_ent, sizeof(ut_ent),
+		          "Cannot write wtmp file " WTMP_FILE ": %m\n" );
 #endif
 
 #ifndef NO_LASTLOG
@@ -293,9 +308,8 @@
 			debug( "cannot open lastlog file " LLOG_FILE ": %m\n" );
 		else {
 			lseek( llog, (off_t)uid * sizeof(ll), SEEK_SET );
-			if (write( llog, (char *)&ll, sizeof(ll) ) != sizeof(ll))
-				logError( "Cannot write llog file " WTMP_FILE ": %m\n" );
-			close( llog );
+			writeOut( llog, &ll, sizeof(ll),
+			          "Cannot write lastlog file " LLOG_FILE ": %m\n" );
 		}
 # endif
 	}
--- trunk/KDE/kdebase/workspace/kdm/kfrontend/genkdmconf.c #1040004:1040005
@@ -319,6 +319,60 @@
 }
 
 
+static char *curName;
+
+/* Create a new file in KDMCONF */
+static FILE *
+createFile( const char *fn, int mode )
+{
+	FILE *f;
+
+	free( curName );
+	ASPrintf( &curName, "%s/%s", newdir, fn );
+	displace( curName );
+	if (!(f = fopen( curName, "w" ))) {
+		fprintf( stderr, "Cannot create %s\n", curName );
+		exit( 1 );
+	}
+	chmod( curName, mode );
+	return f;
+}
+
+static void
+writeError()
+{
+	fprintf( stderr, "Warning: cannot write %s (disk full?)\n", curName );
+	unlink( curName );
+	exit( 1 );
+}
+
+static void
+fputs_( const char *str, FILE *f )
+{
+	if (fputs( str, f ) == EOF)
+		writeError();
+}
+
+static void
+ATTR_PRINTFLIKE(2, 3)
+fprintf_( FILE *f, const char *fmt, ... )
+{
+	va_list args;
+
+	va_start( args, fmt );
+	if (vfprintf( f, fmt, args ) < 0)
+		writeError();
+	va_end( args );
+}
+
+static void
+fclose_( FILE *f )
+{
+	if (fclose( f ) == EOF)
+		writeError();
+}
+
+
 static char *
 locate( const char *exe )
 {
@@ -464,8 +518,8 @@
 
 	putFqVal( "General", "ConfigVersion", RCVERSTR );
 	for (cs = config; cs; cs = cs->next) {
-		fprintf( f, "%s[%s]\n",
-		         cs->comment ? cs->comment : "\n", cs->name );
+		fprintf_( f, "%s[%s]\n",
+		          cs->comment ? cs->comment : "\n", cs->name );
 		for (ce = cs->ents; ce; ce = ce->next) {
 			if (ce->spec->comment) {
 				cmt = ce->spec->comment;
@@ -475,7 +529,7 @@
 						goto havit;
 					}
 				if (!(sp = malloc( sizeof(*sp) )))
-					fprintf( stderr, "Warning: Out of memory\n" );
+					fprintf_( stderr, "Warning: Out of memory\n" );
 				else {
 					sp->str = cmt;
 					sp->next = sl; sl = sp;
@@ -483,8 +537,8 @@
 			} else
 				cmt = "";
 		  havit:
-			fprintf( f, "%s%s%s=%s\n",
-			         cmt, ce->active ? "" : "#", ce->spec->key, ce->value );
+			fprintf_( f, "%s%s%s=%s\n",
+			          cmt, ce->active ? "" : "#", ce->spec->key, ce->value );
 		}
 	}
 }
@@ -726,24 +780,6 @@
 "WallpaperList=\n"
 "WallpaperMode=Scaled\n";
 
-/* Create a new file in KDMCONF */
-static FILE *
-createFile( const char *fn, int mode )
-{
-	char *nname;
-	FILE *f;
-
-	ASPrintf( &nname, "%s/%s", newdir, fn );
-	displace( nname );
-	if (!(f = fopen( nname, "w" ))) {
-		fprintf( stderr, "Cannot create %s\n", nname );
-		exit( 1 );
-	}
-	chmod( nname, mode );
-	free( nname );
-	return f;
-}
-
 /* Create a copy of a file under KDMCONF and fill it */
 static void
 writeCopy( const char *fn, int mode, time_t stamp, const char *buf, size_t len )
@@ -759,8 +795,11 @@
 		fprintf( stderr, "Cannot create %s\n", nname );
 		exit( 1 );
 	}
-	write( fd, buf, len );
-	close( fd );
+	if (write( fd, buf, len ) != (ssize_t)len || close( fd ) < 0) {
+		fprintf( stderr, "Cannot write %s (disk full?)\n", nname );
+		unlink( nname );
+		exit( 1 );
+	}
 	if (stamp) {
 		utim.actime = utim.modtime = stamp;
 		utime( nname, &utim );
@@ -1022,8 +1061,8 @@
 writeFile( const char *tname, int mode, const char *cont )
 {
 	FILE *f = createFile( tname + sizeof(KDMCONF), mode );
-	fputs( cont, f );
-	fclose( f );
+	fputs_( cont, f );
+	fclose_( f );
 	addedFile( tname );
 }
 
@@ -2046,8 +2085,15 @@
 
 	if (readFile( &file, from )) {
 		if ((fd = open( to, O_WRONLY | O_CREAT | O_EXCL, 0644 )) >= 0) {
-			write( fd, file.buf, file.eof - file.buf );
-			close( fd );
+			size_t len = file.eof - file.buf;
+			if (write( fd, file.buf, len ) != (ssize_t)len) {
+				fprintf( stderr, "Warning: cannot write %s (disk full?)\n", to );
+				unlink( to );
+			}
+			if (close( fd ) < 0) {
+				fprintf( stderr, "Warning: cannot write %s (disk full?)\n", to );
+				unlink( to );
+			}
 		} else if (errno != EEXIST)
 			fprintf( stderr, "Warning: cannot create %s\n", to );
 		freeBuf( &file );
@@ -2812,7 +2858,7 @@
 	}
 	free( txt );
 	if (ftxt) {
-		fputs( ftxt, f );
+		fputs_( ftxt, f );
 		free( ftxt );
 	}
 }
@@ -3111,55 +3157,55 @@
 					ce->spec->func( ce, cs );
 	f = createFile( "kdmrc", kdmrcmode );
 	writeKdmrc( f );
-	fclose( f );
+	fclose_( f );
 
 	f = createFile( "README", 0644 );
-	fprintf( f,
+	fprintf_( f,
 "This automatically generated configuration consists of the following files:\n" );
-	fprintf( f, "- " KDMCONF "/kdmrc\n" );
+	fprintf_( f, "- " KDMCONF "/kdmrc\n" );
 	for (fp = aflist; fp; fp = fp->next)
-		fprintf( f, "- %s\n", fp->str );
+		fprintf_( f, "- %s\n", fp->str );
 	if (use_destdir && !no_in_notice)
 		fprintfLineWrap( f,
 "All files destined for " KDMCONF " were actually saved in %s; "
 "this config will not be workable until moved in place.\n", newdir );
 	if (uflist || eflist || cflist || lflist) {
-		fprintf( f,
+		fprintf_( f,
 "\n"
 "This config was derived from existing files. As the used algorithms are\n"
 "pretty dumb, it may be broken.\n" );
 		if (uflist) {
-			fprintf( f,
+			fprintf_( f,
 "Information from these files was extracted:\n" );
 			for (fp = uflist; fp; fp = fp->next)
-				fprintf( f, "- %s\n", fp->str );
+				fprintf_( f, "- %s\n", fp->str );
 		}
 		if (lflist) {
-			fprintf( f,
+			fprintf_( f,
 "These files were directly incorporated:\n" );
 			for (fp = lflist; fp; fp = fp->next)
-				fprintf( f, "- %s\n", fp->str );
+				fprintf_( f, "- %s\n", fp->str );
 		}
 		if (cflist) {
-			fprintf( f,
+			fprintf_( f,
 "These files were copied verbatim:\n" );
 			for (fp = cflist; fp; fp = fp->next)
-				fprintf( f, "- %s\n", fp->str );
+				fprintf_( f, "- %s\n", fp->str );
 		}
 		if (eflist) {
-			fprintf( f,
+			fprintf_( f,
 "These files were copied with modifications:\n" );
 			for (fp = eflist; fp; fp = fp->next)
-				fprintf( f, "- %s\n", fp->str );
+				fprintf_( f, "- %s\n", fp->str );
 		}
 		if (!no_backup && !use_destdir)
-			fprintf( f,
+			fprintf_( f,
 "Old files that would have been overwritten were renamed to <oldname>.bak.\n" );
 	}
-	fprintf( f,
+	fprintf_( f,
 "\nTry 'genkdmconf --help' if you want to generate another configuration.\n"
 "\nYou may delete this README.\n" );
-	fclose( f );
+	fclose_( f );
 
 	return 0;
 }
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic