diff options
author | LRN <lrn1986@gmail.com> | 2013-02-14 16:15:15 +0000 |
---|---|---|
committer | LRN <lrn1986@gmail.com> | 2013-02-14 16:15:15 +0000 |
commit | fb325794836981c17396a187f97da0c542ff34d0 (patch) | |
tree | b6118f2e0cee3df9e6358398b6b6d3df870ab78e | |
parent | bb0344c616bfa067498fbfd455768847115fe96e (diff) | |
download | gnunet-fb325794836981c17396a187f97da0c542ff34d0.tar.gz gnunet-fb325794836981c17396a187f97da0c542ff34d0.zip |
More flexible native->GNUnet_handle file opening
Can now open not just FILEs, but also integer fds and
native Windows handles.
The last two will be used later by the new pipe control code.
-rw-r--r-- | src/include/gnunet_disk_lib.h | 21 | ||||
-rw-r--r-- | src/util/disk.c | 112 |
2 files changed, 101 insertions, 32 deletions
diff --git a/src/include/gnunet_disk_lib.h b/src/include/gnunet_disk_lib.h index 0f36353b0..2e1276374 100644 --- a/src/include/gnunet_disk_lib.h +++ b/src/include/gnunet_disk_lib.h | |||
@@ -504,6 +504,27 @@ GNUNET_DISK_pipe_handle (const struct GNUNET_DISK_PipeHandle *p, | |||
504 | enum GNUNET_DISK_PipeEnd n); | 504 | enum GNUNET_DISK_PipeEnd n); |
505 | 505 | ||
506 | 506 | ||
507 | #if WINDOWS | ||
508 | /** | ||
509 | * Get a GNUnet file handle from a W32 handle (W32-only). | ||
510 | * Do not call on non-W32 platforms (returns NULL). | ||
511 | * | ||
512 | * @param handle native handle | ||
513 | * @return GNUnet file handle corresponding to the W32 handle | ||
514 | */ | ||
515 | struct GNUNET_DISK_FileHandle * | ||
516 | GNUNET_DISK_get_handle_from_w32_handle (HANDLE osfh); | ||
517 | #endif | ||
518 | |||
519 | /** | ||
520 | * Get a handle from a native integer FD. | ||
521 | * | ||
522 | * @param fd native integer file descriptor | ||
523 | * @return file handle corresponding to the descriptor | ||
524 | */ | ||
525 | struct GNUNET_DISK_FileHandle * | ||
526 | GNUNET_DISK_get_handle_from_int_fd (int fno); | ||
527 | |||
507 | /** | 528 | /** |
508 | * Get a handle from a native FD. | 529 | * Get a handle from a native FD. |
509 | * | 530 | * |
diff --git a/src/util/disk.c b/src/util/disk.c index 4b9e5fd65..47325fe4e 100644 --- a/src/util/disk.c +++ b/src/util/disk.c | |||
@@ -1866,52 +1866,81 @@ GNUNET_DISK_file_close (struct GNUNET_DISK_FileHandle *h) | |||
1866 | return ret; | 1866 | return ret; |
1867 | } | 1867 | } |
1868 | 1868 | ||
1869 | 1869 | #ifndef WINDOWS | |
1870 | /** | 1870 | /** |
1871 | * Get a handle from a native FD. | 1871 | * Get a GNUnet file handle from a W32 handle. |
1872 | * | 1872 | * |
1873 | * @param fd native file descriptor | 1873 | * @param handle native handle |
1874 | * @return file handle corresponding to the descriptor | 1874 | * @return GNUnet file handle corresponding to the W32 handle |
1875 | */ | 1875 | */ |
1876 | struct GNUNET_DISK_FileHandle * | 1876 | struct GNUNET_DISK_FileHandle * |
1877 | GNUNET_DISK_get_handle_from_native (FILE *fd) | 1877 | GNUNET_DISK_get_handle_from_w32_handle (HANDLE osfh) |
1878 | { | 1878 | { |
1879 | struct GNUNET_DISK_FileHandle *fh; | 1879 | struct GNUNET_DISK_FileHandle *fh; |
1880 | int fno; | ||
1881 | #if MINGW | ||
1882 | intptr_t osfh; | ||
1883 | #endif | ||
1884 | 1880 | ||
1885 | fno = fileno (fd); | 1881 | DWORD dwret; |
1886 | if (-1 == fno) | 1882 | enum GNUNET_FILE_Type ftype; |
1887 | return NULL; | ||
1888 | 1883 | ||
1889 | #if MINGW | 1884 | dwret = GetFileType (osfh); |
1890 | osfh = _get_osfhandle (fno); | 1885 | switch (dwret) |
1891 | if (INVALID_HANDLE_VALUE == (HANDLE) osfh) | 1886 | { |
1887 | case FILE_TYPE_DISK: | ||
1888 | ftype = GNUNET_DISK_HANLDE_TYPE_FILE; | ||
1889 | break; | ||
1890 | case FILE_TYPE_PIPE: | ||
1891 | ftype = GNUNET_DISK_HANLDE_TYPE_PIPE; | ||
1892 | break; | ||
1893 | default: | ||
1892 | return NULL; | 1894 | return NULL; |
1895 | } | ||
1896 | |||
1897 | fh = GNUNET_malloc (sizeof (struct GNUNET_DISK_FileHandle)); | ||
1898 | |||
1899 | fh->h = osfh; | ||
1900 | fh->type = ftype; | ||
1901 | if (ftype == GNUNET_DISK_HANLDE_TYPE_PIPE) | ||
1902 | { | ||
1903 | /** | ||
1904 | * Note that we can't make it overlapped if it isn't already. | ||
1905 | * (ReOpenFile() is only available in 2003/Vista). | ||
1906 | * The process that opened this file in the first place (usually a parent | ||
1907 | * process, if this is stdin/stdout/stderr) must make it overlapped, | ||
1908 | * otherwise we're screwed, as selecting on non-overlapped handle | ||
1909 | * will block. | ||
1910 | */ | ||
1911 | fh->oOverlapRead = GNUNET_malloc (sizeof (OVERLAPPED)); | ||
1912 | fh->oOverlapWrite = GNUNET_malloc (sizeof (OVERLAPPED)); | ||
1913 | fh->oOverlapRead->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL); | ||
1914 | fh->oOverlapWrite->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL); | ||
1915 | } | ||
1916 | |||
1917 | return fh; | ||
1918 | } | ||
1893 | #endif | 1919 | #endif |
1894 | 1920 | ||
1921 | /** | ||
1922 | * Get a handle from a native integer FD. | ||
1923 | * | ||
1924 | * @param fd native integer file descriptor | ||
1925 | * @return file handle corresponding to the descriptor | ||
1926 | */ | ||
1927 | struct GNUNET_DISK_FileHandle * | ||
1928 | GNUNET_DISK_get_handle_from_int_fd (int fno) | ||
1929 | { | ||
1930 | struct GNUNET_DISK_FileHandle *fh; | ||
1931 | |||
1932 | #ifndef WINDOWS | ||
1895 | fh = GNUNET_malloc (sizeof (struct GNUNET_DISK_FileHandle)); | 1933 | fh = GNUNET_malloc (sizeof (struct GNUNET_DISK_FileHandle)); |
1896 | 1934 | ||
1897 | #if MINGW | ||
1898 | fh->h = (HANDLE) osfh; | ||
1899 | /* Assume it to be a pipe. TODO: use some kind of detection | ||
1900 | * function to figure out handle type. | ||
1901 | * Note that we can't make it overlapped if it isn't already. | ||
1902 | * (ReOpenFile() is only available in 2003/Vista). | ||
1903 | * The process that opened this file in the first place (usually a parent | ||
1904 | * process, if this is stdin/stdout/stderr) must make it overlapped, | ||
1905 | * otherwise we're screwed, as selecting on non-overlapped handle | ||
1906 | * will block. | ||
1907 | */ | ||
1908 | fh->type = GNUNET_DISK_HANLDE_TYPE_PIPE; | ||
1909 | fh->oOverlapRead = GNUNET_malloc (sizeof (OVERLAPPED)); | ||
1910 | fh->oOverlapWrite = GNUNET_malloc (sizeof (OVERLAPPED)); | ||
1911 | fh->oOverlapRead->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL); | ||
1912 | fh->oOverlapWrite->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL); | ||
1913 | #else | ||
1914 | fh->fd = fno; | 1935 | fh->fd = fno; |
1936 | #else | ||
1937 | intptr_t osfh; | ||
1938 | |||
1939 | osfh = _get_osfhandle (fno); | ||
1940 | if (INVALID_HANDLE_VALUE == (HANDLE) osfh) | ||
1941 | return NULL; | ||
1942 | |||
1943 | fh = GNUNET_DISK_get_handle_from_w32_handle ((HANDLE) osfh); | ||
1915 | #endif | 1944 | #endif |
1916 | 1945 | ||
1917 | return fh; | 1946 | return fh; |
@@ -1919,6 +1948,25 @@ GNUNET_DISK_get_handle_from_native (FILE *fd) | |||
1919 | 1948 | ||
1920 | 1949 | ||
1921 | /** | 1950 | /** |
1951 | * Get a handle from a native streaming FD. | ||
1952 | * | ||
1953 | * @param fd native streaming file descriptor | ||
1954 | * @return file handle corresponding to the descriptor | ||
1955 | */ | ||
1956 | struct GNUNET_DISK_FileHandle * | ||
1957 | GNUNET_DISK_get_handle_from_native (FILE *fd) | ||
1958 | { | ||
1959 | int fno; | ||
1960 | |||
1961 | fno = fileno (fd); | ||
1962 | if (-1 == fno) | ||
1963 | return NULL; | ||
1964 | |||
1965 | return GNUNET_DISK_get_handle_from_int_fd (fno); | ||
1966 | } | ||
1967 | |||
1968 | |||
1969 | /** | ||
1922 | * Construct full path to a file inside of the private | 1970 | * Construct full path to a file inside of the private |
1923 | * directory used by GNUnet. Also creates the corresponding | 1971 | * directory used by GNUnet. Also creates the corresponding |
1924 | * directory. If the resulting name is supposed to be | 1972 | * directory. If the resulting name is supposed to be |