@@ -68,10 +68,7 @@ int git_blob_create_frombuffer(git_oid *oid, git_repository *repo, const void *b
6868int git_blob_create_fromfile (git_oid * oid , git_repository * repo , const char * path )
6969{
7070 int error = GIT_SUCCESS ;
71- int islnk = 0 ;
72- int fd = 0 ;
7371 git_buf full_path = GIT_BUF_INIT ;
74- char buffer [2048 ];
7572 git_off_t size ;
7673 git_odb_stream * stream = NULL ;
7774 struct stat st ;
@@ -92,51 +89,69 @@ int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *pat
9289 goto cleanup ;
9390 }
9491
95- islnk = S_ISLNK (st .st_mode );
9692 size = st .st_size ;
9793
9894 error = git_repository_odb__weakptr (& odb , repo );
9995 if (error < GIT_SUCCESS )
10096 goto cleanup ;
10197
102- if (!islnk ) {
103- if ((fd = p_open (full_path .ptr , O_RDONLY )) < 0 ) {
104- error = git__throw (GIT_ENOTFOUND , "Failed to create blob. Could not open '%s'" , full_path .ptr
105- );
106- goto cleanup ;
107- }
108- }
109-
11098 if ((error = git_odb_open_wstream (& stream , odb , (size_t )size , GIT_OBJ_BLOB )) < GIT_SUCCESS )
11199 goto cleanup ;
112100
113- while (size > 0 ) {
101+ if (S_ISLNK (st .st_mode )) {
102+ char * link_data ;
114103 ssize_t read_len ;
115104
116- if (!islnk )
117- read_len = p_read (fd , buffer , sizeof (buffer ));
118- else
119- read_len = p_readlink (full_path .ptr , buffer , sizeof (buffer ));
105+ link_data = git__malloc (size );
106+ if (!link_data ) {
107+ error = GIT_ENOMEM ;
108+ goto cleanup ;
109+ }
110+
111+ read_len = p_readlink (full_path .ptr , link_data , size );
120112
121- if (read_len < 0 ) {
122- error = git__throw (GIT_EOSERR , "Failed to create blob. Can't read full file" );
113+ if (read_len != (ssize_t )size ) {
114+ error = git__throw (GIT_EOSERR , "Failed to create blob. Can't read symlink" );
115+ free (link_data );
123116 goto cleanup ;
124117 }
125118
126- stream -> write (stream , buffer , read_len );
127- size -= read_len ;
119+ stream -> write (stream , link_data , size );
120+ free (link_data );
121+
122+ } else {
123+ int fd ;
124+ char buffer [2048 ];
125+
126+ if ((fd = p_open (full_path .ptr , O_RDONLY )) < 0 ) {
127+ error = git__throw (GIT_ENOTFOUND , "Failed to create blob. Could not open '%s'" , full_path .ptr );
128+ goto cleanup ;
129+ }
130+
131+ while (size > 0 ) {
132+ ssize_t read_len = p_read (fd , buffer , sizeof (buffer ));
133+
134+ if (read_len < 0 ) {
135+ error = git__throw (GIT_EOSERR , "Failed to create blob. Can't read full file" );
136+ p_close (fd );
137+ goto cleanup ;
138+ }
139+
140+ stream -> write (stream , buffer , read_len );
141+ size -= read_len ;
142+ }
143+
144+ p_close (fd );
128145 }
129146
130147 error = stream -> finalize_write (oid , stream );
131148
132149cleanup :
133150 if (stream )
134151 stream -> free (stream );
135- if (!islnk && fd )
136- p_close (fd );
152+
137153 git_buf_free (& full_path );
138154
139- return error == GIT_SUCCESS ? GIT_SUCCESS :
140- git__rethrow (error , "Failed to create blob" );
155+ return error ;
141156}
142157
0 commit comments