X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=glib%2Fgstdio.c;h=4fff212d4c6659c798ee6e70e59ef5cf7eb99277;hb=4454b815367831a71b1ae00b0182b5b389a78df2;hp=285bfe91714d964e77cc42b90113706d8aa6c128;hpb=87bc41714fe3fcb66083fe0fe40602f2bf77cb0b;p=platform%2Fupstream%2Fglib.git diff --git a/glib/gstdio.c b/glib/gstdio.c index 285bfe9..4fff212 100644 --- a/glib/gstdio.c +++ b/glib/gstdio.c @@ -14,21 +14,19 @@ * * You should have received a copy of the GNU Lesser General Public * License along with GLib; see the file COPYING.LIB. If not, - * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * see . */ #include "config.h" +#include "glibconfig.h" #define G_STDIO_NO_WRAP_ON_UNIX -#include "glib.h" - #include #include #include -#ifdef HAVE_UNISTD_H +#ifdef G_OS_UNIX #include #endif @@ -39,16 +37,22 @@ #include #include #include +#else +#include +#include #endif #include "gstdio.h" -#include "galias.h" -#if !defined (G_OS_UNIX) && !defined (G_OS_WIN32) && !defined (G_OS_BEOS) +#if !defined (G_OS_UNIX) && !defined (G_OS_WIN32) #error Please port this to your operating system #endif +#if defined (_MSC_VER) && !defined(_WIN64) +#undef _wstat +#define _wstat _wstat32 +#endif /** * g_access: @@ -57,16 +61,20 @@ * * A wrapper for the POSIX access() function. This function is used to * test a pathname for one or several of read, write or execute - * permissions, or just existence. On Windows, the underlying access() - * function in the C library only checks the READONLY attribute, and - * does not look at the ACL at all. Software that needs to handle file - * permissions on Windows more exactly should use the Win32 API. + * permissions, or just existence. + * + * On Windows, the file protection mechanism is not at all POSIX-like, + * and the underlying function in the C library only checks the + * FAT-style READONLY attribute, and does not look at the ACL of a + * file at all. This function is this in practise almost useless on + * Windows. Software that needs to handle file permissions on Windows + * more exactly should use the Win32 API. * - * See the C library manual for more details about access(). + * See your C library manual for more details about access(). * * Returns: zero if the pathname refers to an existing file system - * object that has all the tested permissions, or -1 otherwise or on - * error. + * object that has all the tested permissions, or -1 otherwise + * or on error. * * Since: 2.8 */ @@ -85,6 +93,10 @@ g_access (const gchar *filename, return -1; } +#ifndef X_OK +#define X_OK 1 +#endif + retval = _waccess (wfilename, mode & ~X_OK); save_errno = errno; @@ -103,16 +115,17 @@ g_access (const gchar *filename, * @mode: as in chmod() * * A wrapper for the POSIX chmod() function. The chmod() function is - * used to set the permissions of a file system object. Note that on - * Windows the file protection mechanism is not at all POSIX-like, and - * the underlying chmod() function in the C library just sets or - * clears the READONLY attribute. It does not touch any ACL. Software - * that needs to manage file permissions on Windows exactly should - * use the Win32 API. + * used to set the permissions of a file system object. + * + * On Windows the file protection mechanism is not at all POSIX-like, + * and the underlying chmod() function in the C library just sets or + * clears the FAT-style READONLY attribute. It does not touch any + * ACL. Software that needs to manage file permissions on Windows + * exactly should use the Win32 API. * - * See the C library manual for more details about chmod(). + * See your C library manual for more details about chmod(). * - * Returns: zero if the operation succeeded, -1 on error. + * Returns: 0 if the operation succeeded, -1 on error * * Since: 2.8 */ @@ -142,7 +155,6 @@ g_chmod (const gchar *filename, return chmod (filename, mode); #endif } - /** * g_open: * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) @@ -150,16 +162,27 @@ g_chmod (const gchar *filename, * @mode: as in open() * * A wrapper for the POSIX open() function. The open() function is - * used to convert a pathname into a file descriptor. Note that on - * POSIX systems file descriptors are implemented by the operating - * system. On Windows, it's the C library that implements open() and - * file descriptors. The actual Windows API for opening files is - * something different. - * - * See the C library manual for more details about open(). + * used to convert a pathname into a file descriptor. * - * Returns: a new file descriptor, or -1 if an error occurred. The - * return value can be used exactly like the return value from open(). + * On POSIX systems file descriptors are implemented by the operating + * system. On Windows, it's the C library that implements open() and + * file descriptors. The actual Win32 API for opening files is quite + * different, see MSDN documentation for CreateFile(). The Win32 API + * uses file handles, which are more randomish integers, not small + * integers like file descriptors. + * + * Because file descriptors are specific to the C library on Windows, + * the file descriptor returned by this function makes sense only to + * functions in the same C library. Thus if the GLib-using code uses a + * different C library than GLib does, the file descriptor returned by + * this function cannot be passed to C library functions like write() + * or read(). + * + * See your C library manual for more details about open(). + * + * Returns: a new file descriptor, or -1 if an error occurred. + * The return value can be used exactly like the return value + * from open(). * * Since: 2.6 */ @@ -187,7 +210,11 @@ g_open (const gchar *filename, errno = save_errno; return retval; #else - return open (filename, flags, mode); + int fd; + do + fd = open (filename, flags, mode); + while (G_UNLIKELY (fd == -1 && errno == EINTR)); + return fd; #endif } @@ -198,15 +225,27 @@ g_open (const gchar *filename, * * A wrapper for the POSIX creat() function. The creat() function is * used to convert a pathname into a file descriptor, creating a file - * if necessary. Note that on POSIX systems file descriptors are - * implemented by the operating system. On Windows, it's the C library - * that implements creat() and file descriptors. The actual Windows - * API for opening files is something different. - * - * See the C library manual for more details about creat(). - * - * Returns: a new file descriptor, or -1 if an error occurred. The - * return value can be used exactly like the return value from creat(). + * if necessary. + + * On POSIX systems file descriptors are implemented by the operating + * system. On Windows, it's the C library that implements creat() and + * file descriptors. The actual Windows API for opening files is + * different, see MSDN documentation for CreateFile(). The Win32 API + * uses file handles, which are more randomish integers, not small + * integers like file descriptors. + * + * Because file descriptors are specific to the C library on Windows, + * the file descriptor returned by this function makes sense only to + * functions in the same C library. Thus if the GLib-using code uses a + * different C library than GLib does, the file descriptor returned by + * this function cannot be passed to C library functions like write() + * or read(). + * + * See your C library manual for more details about creat(). + * + * Returns: a new file descriptor, or -1 if an error occurred. + * The return value can be used exactly like the return value + * from creat(). * * Since: 2.8 */ @@ -246,9 +285,8 @@ g_creat (const gchar *filename, * renames a file, moving it between directories if required. * * See your C library manual for more details about how rename() works - * on your system. Note in particular that on Win9x it is not possible - * to rename a file if a file with the new name already exists. Also - * it is not possible in general on Windows to rename an open file. + * on your system. It is not possible in general on Windows to rename + * a file that is open to some process. * * Returns: 0 if the renaming succeeded, -1 if an error occurred * @@ -319,7 +357,7 @@ g_rename (const gchar *oldfilename, * attempts to create a directory with the given name and permissions. * The mode argument is ignored on Windows. * - * See the C library manual for more details about mkdir(). + * See your C library manual for more details about mkdir(). * * Returns: 0 if the directory was successfully created, -1 if an error * occurred @@ -393,27 +431,48 @@ g_chdir (const gchar *path) } /** + * GStatBuf: + * + * A type corresponding to the appropriate struct type for the stat() + * system call, depending on the platform and/or compiler being used. + * + * See g_stat() for more information. + */ +/** * g_stat: * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) - * @buf: a pointer to a stat struct, which - * will be filled with the file information + * @buf: a pointer to a stat struct, which will be filled with the file + * information * * A wrapper for the POSIX stat() function. The stat() function * returns information about a file. On Windows the stat() function in - * the C library checks only the READONLY attribute and does not look - * at the ACL at all. Thus the protection bits in the st_mode field - * are a fabrication of little use. + * the C library checks only the FAT-style READONLY attribute and does + * not look at the ACL at all. Thus on Windows the protection bits in + * the @st_mode field are a fabrication of little use. * - * See the C library manual for more details about stat(). - * - * Returns: 0 if the information was successfully retrieved, -1 if an error - * occurred + * On Windows the Microsoft C libraries have several variants of the + * stat struct and stat() function with names like _stat(), _stat32(), + * _stat32i64() and _stat64i32(). The one used here is for 32-bit code + * the one with 32-bit size and time fields, specifically called _stat32(). + * + * In Microsoft's compiler, by default struct stat means one with + * 64-bit time fields while in MinGW struct stat is the legacy one + * with 32-bit fields. To hopefully clear up this messs, the gstdio.h + * header defines a type #GStatBuf which is the appropriate struct type + * depending on the platform and/or compiler being used. On POSIX it + * is just struct stat, but note that even on POSIX platforms, stat() + * might be a macro. + * + * See your C library manual for more details about stat(). + * + * Returns: 0 if the information was successfully retrieved, + * -1 if an error occurred * * Since: 2.6 */ int g_stat (const gchar *filename, - struct stat *buf) + GStatBuf *buf) { #ifdef G_OS_WIN32 wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); @@ -434,7 +493,7 @@ g_stat (const gchar *filename, (!g_path_is_absolute (filename) || len > g_path_skip_root (filename) - filename)) wfilename[len] = '\0'; - retval = _wstat (wfilename, (struct _stat *) buf); + retval = _wstat (wfilename, buf); save_errno = errno; g_free (wfilename); @@ -449,8 +508,8 @@ g_stat (const gchar *filename, /** * g_lstat: * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) - * @buf: a pointer to a stat struct, which - * will be filled with the file information + * @buf: a pointer to a stat struct, which will be filled with the file + * information * * A wrapper for the POSIX lstat() function. The lstat() function is * like stat() except that in the case of symbolic links, it returns @@ -458,16 +517,16 @@ g_stat (const gchar *filename, * refers to. If the system does not support symbolic links g_lstat() * is identical to g_stat(). * - * See the C library manual for more details about lstat(). + * See your C library manual for more details about lstat(). * - * Returns: 0 if the information was successfully retrieved, -1 if an error - * occurred + * Returns: 0 if the information was successfully retrieved, + * -1 if an error occurred * * Since: 2.6 */ int g_lstat (const gchar *filename, - struct stat *buf) + GStatBuf *buf) { #ifdef HAVE_LSTAT /* This can't be Win32, so don't do the widechar dance. */ @@ -619,16 +678,22 @@ g_rmdir (const gchar *filename) /** * g_fopen: * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) - * @mode: a string describing the mode in which the file should be - * opened + * @mode: a string describing the mode in which the file should be opened * - * A wrapper for the POSIX fopen() function. The fopen() function opens - * a file and associates a new stream with it. + * A wrapper for the stdio fopen() function. The fopen() function + * opens a file and associates a new stream with it. * - * See the C library manual for more details about fopen(). + * Because file descriptors are specific to the C library on Windows, + * and a file descriptor is part of the FILE struct, the FILE* returned + * by this function makes sense only to functions in the same C library. + * Thus if the GLib-using code uses a different C library than GLib does, + * the FILE* returned by this function cannot be passed to C library + * functions like fprintf() or fread(). + * + * See your C library manual for more details about fopen(). * - * Returns: A FILE pointer if the file was successfully - * opened, or %NULL if an error occurred + * Returns: A FILE* if the file was successfully opened, or %NULL if + * an error occurred * * Since: 2.6 */ @@ -673,17 +738,16 @@ g_fopen (const gchar *filename, /** * g_freopen: * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) - * @mode: a string describing the mode in which the file should be - * opened - * @stream: an existing stream which will be reused, or %NULL + * @mode: a string describing the mode in which the file should be opened + * @stream: (allow-none): an existing stream which will be reused, or %NULL * * A wrapper for the POSIX freopen() function. The freopen() function * opens a file and associates it with an existing stream. * - * See the C library manual for more details about freopen(). + * See your C library manual for more details about freopen(). * - * Returns: A FILE pointer if the file was successfully - * opened, or %NULL if an error occurred. + * Returns: A FILE* if the file was successfully opened, or %NULL if + * an error occurred. * * Since: 2.6 */ @@ -737,8 +801,7 @@ g_freopen (const gchar *filename, * See your C library manual for more details about how utime() works * on your system. * - * Returns: 0 if the operation was successful, -1 if an error - * occurred + * Returns: 0 if the operation was successful, -1 if an error occurred * * Since: 2.18 */ @@ -769,5 +832,47 @@ g_utime (const gchar *filename, #endif } -#define __G_STDIO_C__ -#include "galiasdef.c" +/** + * g_close: + * @fd: A file descriptor + * @error: a #GError + * + * This wraps the close() call; in case of error, %errno will be + * preserved, but the error will also be stored as a #GError in @error. + * + * Besides using #GError, there is another major reason to prefer this + * function over the call provided by the system; on Unix, it will + * attempt to correctly handle %EINTR, which has platform-specific + * semantics. + * + * Since: 2.36 + */ +gboolean +g_close (gint fd, + GError **error) +{ + int res; + res = close (fd); + /* Just ignore EINTR for now; a retry loop is the wrong thing to do + * on Linux at least. Anyone who wants to add a conditional check + * for e.g. HP-UX is welcome to do so later... + * + * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html + * https://bugzilla.gnome.org/show_bug.cgi?id=682819 + * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR + * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain + */ + if (G_UNLIKELY (res == -1 && errno == EINTR)) + return TRUE; + else if (res == -1) + { + int errsv = errno; + g_set_error_literal (error, G_FILE_ERROR, + g_file_error_from_errno (errsv), + g_strerror (errsv)); + errno = errsv; + return FALSE; + } + return TRUE; +} +