From kde-commits Sun Oct 25 10:28:02 2009 From: Oswald Buddenhagen Date: Sun, 25 Oct 2009 10:28:02 +0000 To: kde-commits Subject: KDE/kdebase/workspace/kdm Message-Id: <1256466482.871878.8730.nullmailer () svn ! kde ! org> X-MARC-Message: https://marc.info/?l=kde-commits&m=125646649411747 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 .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; }